diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge index 9d9ca32183944..e547afaeb722f 100755 --- a/.ci/generate-buildkite-pipeline-premerge +++ b/.ci/generate-buildkite-pipeline-premerge @@ -128,9 +128,8 @@ if [[ "${windows_projects}" != "" ]]; then limit: 2 timeout_in_minutes: 150 env: - CC: 'cl' - CXX: 'cl' - LD: 'link' + MAX_PARALLEL_COMPILE_JOBS: '16' + MAX_PARALLEL_LINK_JOBS: '4' commands: - 'C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat -arch=amd64 -host_arch=amd64' - 'bash .ci/monolithic-windows.sh "$(echo ${windows_projects} | tr ' ' ';')" "$(echo ${windows_check_targets})"' diff --git a/.ci/metrics/metrics.py b/.ci/metrics/metrics.py index 48d2aa2f330ec..70b787665a8b9 100644 --- a/.ci/metrics/metrics.py +++ b/.ci/metrics/metrics.py @@ -130,34 +130,6 @@ def get_per_workflow_metrics( workflow_jobs = workflow_run.jobs() if workflow_jobs.totalCount == 0: continue - if workflow_jobs.totalCount > 1: - raise ValueError( - f"Encountered an unexpected number of jobs: {workflow_jobs.totalCount}" - ) - - created_at = workflow_jobs[0].created_at - started_at = workflow_jobs[0].started_at - completed_at = workflow_jobs[0].completed_at - - job_result = int(workflow_jobs[0].conclusion == "success") - if job_result: - # We still might want to mark the job as a failure if one of the steps - # failed. This is required due to use setting continue-on-error in - # the premerge pipeline to prevent sending emails while we are - # testing the infrastructure. - # TODO(boomanaiden154): Remove this once the premerge pipeline is no - # longer in a testing state and we can directly assert the workflow - # result. - for step in workflow_jobs[0].steps: - if step.conclusion != "success": - job_result = 0 - break - - queue_time = started_at - created_at - run_time = completed_at - started_at - - if run_time.seconds == 0: - continue if ( workflows_to_track[workflow_run.name] is None @@ -170,20 +142,45 @@ def get_per_workflow_metrics( ): break - # The timestamp associated with the event is expected by Grafana to be - # in nanoseconds. - created_at_ns = int(created_at.timestamp()) * 10**9 - - workflow_metrics.append( - JobMetrics( - workflow_run.name, - queue_time.seconds, - run_time.seconds, - job_result, - created_at_ns, - workflow_run.id, + for workflow_job in workflow_jobs: + created_at = workflow_job.created_at + started_at = workflow_job.started_at + completed_at = workflow_job.completed_at + + job_result = int(workflow_job.conclusion == "success") + if job_result: + # We still might want to mark the job as a failure if one of the steps + # failed. This is required due to use setting continue-on-error in + # the premerge pipeline to prevent sending emails while we are + # testing the infrastructure. + # TODO(boomanaiden154): Remove this once the premerge pipeline is no + # longer in a testing state and we can directly assert the workflow + # result. + for step in workflow_job.steps: + if step.conclusion != "success": + job_result = 0 + break + + queue_time = started_at - created_at + run_time = completed_at - started_at + + if run_time.seconds == 0: + continue + + # The timestamp associated with the event is expected by Grafana to be + # in nanoseconds. + created_at_ns = int(created_at.timestamp()) * 10**9 + + workflow_metrics.append( + JobMetrics( + workflow_run.name + "-" + workflow_job.name, + queue_time.seconds, + run_time.seconds, + job_result, + created_at_ns, + workflow_run.id, + ) ) - ) return workflow_metrics diff --git a/.ci/monolithic-windows.sh b/.ci/monolithic-windows.sh index 68303a3ea153a..57b276f3e1df0 100755 --- a/.ci/monolithic-windows.sh +++ b/.ci/monolithic-windows.sh @@ -50,6 +50,10 @@ echo "--- cmake" pip install -q -r "${MONOREPO_ROOT}"/mlir/python/requirements.txt pip install -q -r "${MONOREPO_ROOT}"/.ci/requirements.txt +export CC=cl +export CXX=cl +export LD=link + # The CMAKE_*_LINKER_FLAGS to disable the manifest come from research # on fixing a build reliability issue on the build server, please # see https://github.com/llvm/llvm-project/pull/82393 and @@ -72,8 +76,8 @@ cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \ -D CMAKE_EXE_LINKER_FLAGS="/MANIFEST:NO" \ -D CMAKE_MODULE_LINKER_FLAGS="/MANIFEST:NO" \ -D CMAKE_SHARED_LINKER_FLAGS="/MANIFEST:NO" \ - -D LLVM_PARALLEL_COMPILE_JOBS=16 \ - -D LLVM_PARALLEL_LINK_JOBS=4 + -D LLVM_PARALLEL_COMPILE_JOBS=${MAX_PARALLEL_COMPILE_JOBS} \ + -D LLVM_PARALLEL_LINK_JOBS=${MAX_PARALLEL_LINK_JOBS} echo "--- ninja" # Targets are not escaped as they are passed as separate arguments. diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 484b947bda402..dd4116fa16bc5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -131,7 +131,7 @@ /bolt/ @aaupov @maksfb @rafaelauler @ayermolo @dcci @yota9 # Bazel build system. -/utils/bazel/ @rupprecht @keith +/utils/bazel/ @rupprecht @keith @aaronmondal # InstallAPI and TextAPI /llvm/**/TextAPI/ @cyndyishida diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml index 566308bb3df8d..9863ff087ca86 100644 --- a/.github/new-prs-labeler.yml +++ b/.github/new-prs-labeler.yml @@ -730,6 +730,9 @@ llvm:regalloc: lldb: - lldb/** +lldb-dap: + - lldb/tools/lldb-dap/** + backend:AMDGPU: - '**/*amdgpu*' - '**/*AMDGPU*' diff --git a/.github/workflows/build-ci-container.yml b/.github/workflows/build-ci-container.yml index 8a81d47186469..8272c8f6e266f 100644 --- a/.github/workflows/build-ci-container.yml +++ b/.github/workflows/build-ci-container.yml @@ -20,24 +20,31 @@ on: jobs: build-ci-container: if: github.repository_owner == 'llvm' - runs-on: depot-ubuntu-22.04-16 - outputs: - container-name: ${{ steps.vars.outputs.container-name }} - container-name-agent: ${{ steps.vars.outputs.container-name-agent }} - container-name-tag: ${{ steps.vars.outputs.container-name-tag }} - container-name-agent-tag: ${{ steps.vars.outputs.container-name-agent-tag }} - container-filename: ${{ steps.vars.outputs.container-filename }} - container-agent-filename: ${{ steps.vars.outputs.container-agent-filename }} + runs-on: ${{ matrix.runs-on }} + strategy: + matrix: + include: + # The arch names should match the names used on dockerhub. + # See https://github.com/docker-library/official-images#architectures-other-than-amd64 + - arch: amd64 + runs-on: depot-ubuntu-22.04-16 + - arch: arm64v8 + runs-on: depot-ubuntu-22.04-arm-16 steps: - name: Checkout LLVM uses: actions/checkout@v4 with: sparse-checkout: .github/workflows/containers/github-action-ci/ + # podman is not installed by default on the ARM64 images. + - name: Install Podman + if: runner.arch == 'ARM64' + run: | + sudo apt-get install podman - name: Write Variables id: vars run: | - tag=`date +%s` - container_name="ghcr.io/$GITHUB_REPOSITORY_OWNER/ci-ubuntu-22.04" + tag=$(git rev-parse --short=12 HEAD) + container_name="ghcr.io/$GITHUB_REPOSITORY_OWNER/${{ matrix.arch }}/ci-ubuntu-22.04" echo "container-name=$container_name" >> $GITHUB_OUTPUT echo "container-name-agent=$container_name-agent" >> $GITHUB_OUTPUT echo "container-name-tag=$container_name:$tag" >> $GITHUB_OUTPUT @@ -61,7 +68,7 @@ jobs: - name: Upload container image uses: actions/upload-artifact@v4 with: - name: container + name: container-${{ matrix.arch }} path: "*.tar" retention-days: 14 @@ -84,18 +91,29 @@ jobs: steps: - name: Download container uses: actions/download-artifact@v4 - with: - name: container - name: Push Container run: | - podman load -i ${{ needs.build-ci-container.outputs.container-filename }} - podman tag ${{ needs.build-ci-container.outputs.container-name-tag }} ${{ needs.build-ci-container.outputs.container-name }}:latest + function push_container { + image_name=$1 + latest_name=$(echo $image_name | sed 's/:[a-f0-9]\+$/:latest/g') + podman tag $image_name $latest_name + echo "Pushing $image_name ..." + podman push $image_name + echo "Pushing $latest_name ..." + podman push $latest_name + } + podman login -u ${{ github.actor }} -p $GITHUB_TOKEN ghcr.io - podman push ${{ needs.build-ci-container.outputs.container-name-tag }} - podman push ${{ needs.build-ci-container.outputs.container-name }}:latest + for f in $(find . -iname *.tar); do + image_name=$(podman load -q -i $f | sed 's/Loaded image: //g') + push_container $image_name - podman load -i ${{ needs.build-ci-container.outputs.container-agent-filename }} - podman tag ${{ needs.build-ci-container.outputs.container-name-agent-tag }} ${{ needs.build-ci-container.outputs.container-name-agent }}:latest - podman push ${{ needs.build-ci-container.outputs.container-name-agent-tag }} - podman push ${{ needs.build-ci-container.outputs.container-name-agent }}:latest + if echo $image_name | grep '/amd64/'; then + # For amd64, create an alias with the arch component removed. + # This matches the convention used on dockerhub. + default_image_name=$(echo $(dirname $(dirname $image_name))/$(basename $image_name)) + podman tag $image_name $default_image_name + push_container $default_image_name + fi + done diff --git a/.github/workflows/clang-tests.yml b/.github/workflows/clang-tests.yml deleted file mode 100644 index 2569ce19518e3..0000000000000 --- a/.github/workflows/clang-tests.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Clang Tests - -permissions: - contents: read - -on: - workflow_dispatch: - push: - branches: - - 'release/**' - paths: - - 'clang/**' - - '.github/workflows/clang-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - pull_request: - branches: - - 'release/**' - paths: - - 'clang/**' - - '.github/workflows/clang-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - check_clang: - if: github.repository_owner == 'llvm' - name: Test clang,lldb,libclc - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-clang - projects: clang;lldb;libclc diff --git a/.github/workflows/commit-access-greeter.yml b/.github/workflows/commit-access-greeter.yml new file mode 100644 index 0000000000000..29a1b578f8af8 --- /dev/null +++ b/.github/workflows/commit-access-greeter.yml @@ -0,0 +1,39 @@ +name: Commit Access Greeter + +on: + issues: + types: + - labeled + +permissions: + contents: read + +jobs: + commit-access-greeter: + permissions: + issues: write + if: >- + github.repository_owner == 'llvm' && + github.event.label.name == 'infra:commit-access-request' + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + sparse-checkout: llvm/utils/git/ + + - name: Setup Automation Script + working-directory: ./llvm/utils/git/ + run: | + pip install --require-hashes -r requirements.txt + + - name: Add comments to issue + working-directory: ./llvm/utils/git/ + env: + LABEL_NAME: ${{ github.event.label.name }} + GITHUB_TOKEN: ${{ github.token }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + run: | + python3 ./github-automation.py \ + --token $GITHUB_TOKEN \ + commit-request-greeter \ + --issue-number $ISSUE_NUMBER diff --git a/.github/workflows/containers/github-action-ci-windows/Dockerfile b/.github/workflows/containers/github-action-ci-windows/Dockerfile index 2295e39d62c30..9a1fab694c9df 100644 --- a/.github/workflows/containers/github-action-ci-windows/Dockerfile +++ b/.github/workflows/containers/github-action-ci-windows/Dockerfile @@ -108,7 +108,7 @@ RUN choco install -y handle RUN pip3 install pywin32 buildbot-worker==2.8.4 -ARG RUNNER_VERSION=2.321.0 +ARG RUNNER_VERSION=2.322.0 ENV RUNNER_VERSION=$RUNNER_VERSION RUN powershell -Command \ diff --git a/.github/workflows/containers/github-action-ci/Dockerfile b/.github/workflows/containers/github-action-ci/Dockerfile index 35a0f1f6020dc..377b8f14402ee 100644 --- a/.github/workflows/containers/github-action-ci/Dockerfile +++ b/.github/workflows/containers/github-action-ci/Dockerfile @@ -96,7 +96,7 @@ WORKDIR /home/gha FROM ci-container as ci-container-agent -ENV GITHUB_RUNNER_VERSION=2.321.0 +ENV GITHUB_RUNNER_VERSION=2.322.0 RUN mkdir actions-runner && \ cd actions-runner && \ diff --git a/.github/workflows/libc-fullbuild-tests.yml b/.github/workflows/libc-fullbuild-tests.yml index 2c88da653aae4..d93ac84116240 100644 --- a/.github/workflows/libc-fullbuild-tests.yml +++ b/.github/workflows/libc-fullbuild-tests.yml @@ -15,6 +15,7 @@ jobs: strategy: fail-fast: false matrix: + build_type: [Debug, Release, MinSizeRel] include: - os: ubuntu-24.04 ccache-variant: sccache @@ -68,7 +69,7 @@ jobs: cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} - -DCMAKE_BUILD_TYPE=MinSizeRel + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_C_COMPILER_LAUNCHER=${{ matrix.ccache-variant }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ matrix.ccache-variant }} -DCMAKE_INSTALL_PREFIX=${{ steps.strings.outputs.build-install-dir }} diff --git a/.github/workflows/libc-overlay-tests.yml b/.github/workflows/libc-overlay-tests.yml index 0a0916084b18c..de4b58c008ee4 100644 --- a/.github/workflows/libc-overlay-tests.yml +++ b/.github/workflows/libc-overlay-tests.yml @@ -16,6 +16,7 @@ jobs: # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. fail-fast: false matrix: + build_type: [Debug, Release, MinSizeRel] include: # TODO: add linux gcc when it is fixed - os: ubuntu-24.04 @@ -95,7 +96,7 @@ jobs: cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cpp_compiler }} -DCMAKE_C_COMPILER=${{ matrix.compiler.c_compiler }} - -DCMAKE_BUILD_TYPE=MinSizeRel + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_C_COMPILER_LAUNCHER=${{ matrix.ccache-variant }} -DCMAKE_CXX_COMPILER_LAUNCHER=${{ matrix.ccache-variant }} -DCMAKE_POLICY_DEFAULT_CMP0141=NEW diff --git a/.github/workflows/libclc-tests.yml b/.github/workflows/libclc-tests.yml deleted file mode 100644 index 23192f776a985..0000000000000 --- a/.github/workflows/libclc-tests.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: libclc Tests - -permissions: - contents: read - -on: - workflow_dispatch: - push: - branches: - - 'release/**' - paths: - - 'libclc/**' - - '.github/workflows/libclc-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - pull_request: - branches: - - 'release/**' - paths: - - 'libclc/**' - - '.github/workflows/libclc-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - check_libclc: - if: github.repository_owner == 'llvm' - name: Test libclc - uses: ./.github/workflows/llvm-project-tests.yml - with: - projects: clang;libclc diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml index a28bf4d5daf6d..ee77e83363d37 100644 --- a/.github/workflows/libcxx-build-and-test.yaml +++ b/.github/workflows/libcxx-build-and-test.yaml @@ -48,8 +48,8 @@ jobs: 'generic-cxx26', 'generic-modules' ] - cc: [ 'clang-19' ] - cxx: [ 'clang++-19' ] + cc: [ 'clang-20' ] + cxx: [ 'clang++-20' ] include: - config: 'generic-gcc' cc: 'gcc-14' @@ -88,18 +88,18 @@ jobs: 'generic-cxx20', 'generic-cxx23' ] - cc: [ 'clang-19' ] - cxx: [ 'clang++-19' ] + cc: [ 'clang-20' ] + cxx: [ 'clang++-20' ] include: - config: 'generic-gcc-cxx11' cc: 'gcc-14' cxx: 'g++-14' - config: 'generic-cxx23' - cc: 'clang-17' - cxx: 'clang++-17' - - config: 'generic-cxx26' cc: 'clang-18' cxx: 'clang++-18' + - config: 'generic-cxx26' + cc: 'clang-19' + cxx: 'clang++-19' steps: - uses: actions/checkout@v4 - name: ${{ matrix.config }} @@ -169,8 +169,8 @@ jobs: - name: ${{ matrix.config }} run: libcxx/utils/ci/run-buildbot ${{ matrix.config }} env: - CC: clang-19 - CXX: clang++-19 + CC: clang-20 + CXX: clang++-20 - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 if: always() with: diff --git a/.github/workflows/libcxx-build-containers.yml b/.github/workflows/libcxx-build-containers.yml index 2d040f712ce59..bb4bd8843772f 100644 --- a/.github/workflows/libcxx-build-containers.yml +++ b/.github/workflows/libcxx-build-containers.yml @@ -9,7 +9,6 @@ name: Build Docker images for libc++ CI permissions: contents: read - packages: write on: push: diff --git a/.github/workflows/lld-tests.yml b/.github/workflows/lld-tests.yml deleted file mode 100644 index 599c0975fa685..0000000000000 --- a/.github/workflows/lld-tests.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: LLD Tests - -permissions: - contents: read - -on: - workflow_dispatch: - push: - branches: - - 'release/**' - paths: - - 'lld/**' - - '.github/workflows/lld-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - pull_request: - branches: - - 'release/**' - paths: - - 'lld/**' - - '.github/workflows/lld-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - check_lld: - if: github.repository_owner == 'llvm' - name: Test lld - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-lld - projects: lld diff --git a/.github/workflows/lldb-tests.yml b/.github/workflows/lldb-tests.yml deleted file mode 100644 index 6bb9721956258..0000000000000 --- a/.github/workflows/lldb-tests.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: lldb Tests - -permissions: - contents: read - -on: - workflow_dispatch: - push: - branches: - - 'release/**' - paths: - - 'lldb/**' - - '.github/workflows/lldb-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - pull_request: - branches: - - 'release/**' - paths: - - 'lldb/**' - - '.github/workflows/lldb-tests.yml' - - '.github/workflows/llvm-project-tests.yml' - - '!clang/**' - - '!llvm/**' - -concurrency: - # Skip intermediate builds: always. - # Cancel intermediate builds: only if it is a pull request build. - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - -jobs: - build_lldb: - if: github.repository_owner == 'llvm' - name: Build lldb - uses: ./.github/workflows/llvm-project-tests.yml - with: - projects: clang;lldb diff --git a/.github/workflows/llvm-tests.yml b/.github/workflows/llvm-tests.yml index 4e570a7cb1455..9b3d49d4e99b9 100644 --- a/.github/workflows/llvm-tests.yml +++ b/.github/workflows/llvm-tests.yml @@ -11,14 +11,12 @@ on: paths: - 'llvm/**' - '.github/workflows/llvm-tests.yml' - - '.github/workflows/llvm-project-tests.yml' pull_request: branches: - 'release/**' paths: - 'llvm/**' - '.github/workflows/llvm-tests.yml' - - '.github/workflows/llvm-project-tests.yml' concurrency: # Skip intermediate builds: always. @@ -27,14 +25,6 @@ concurrency: cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} jobs: - check-all: - if: github.repository_owner == 'llvm' - name: Build and Test - uses: ./.github/workflows/llvm-project-tests.yml - with: - build_target: check-all - projects: clang;lld;libclc;lldb - abi-dump-setup: if: github.repository_owner == 'llvm' runs-on: ubuntu-latest diff --git a/.github/workflows/premerge.yaml b/.github/workflows/premerge.yaml index 30f4fc807f3a5..178ab191a58be 100644 --- a/.github/workflows/premerge.yaml +++ b/.github/workflows/premerge.yaml @@ -5,19 +5,32 @@ permissions: on: pull_request: + types: + - opened + - synchronize + - reopened + # When a PR is closed, we still start this workflow, but then skip + # all the jobs, which makes it effectively a no-op. The reason to + # do this is that it allows us to take advantage of concurrency groups + # to cancel in progress CI jobs whenever the PR is closed. + - closed paths: - .github/workflows/premerge.yaml push: branches: - 'main' + - 'release/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true jobs: premerge-checks-linux: - if: github.repository_owner == 'llvm' + if: >- + github.repository_owner == 'llvm' && + (github.event_name != 'pull_request' || github.event.action != 'closed') runs-on: llvm-premerge-linux-runners - concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true steps: - name: Checkout LLVM uses: actions/checkout@v4 @@ -70,3 +83,132 @@ jobs: export CXX=/opt/llvm/bin/clang++ ./.ci/monolithic-linux.sh "$(echo ${linux_projects} | tr ' ' ';')" "$(echo ${linux_check_targets})" "$(echo ${linux_runtimes} | tr ' ' ';')" "$(echo ${linux_runtime_check_targets})" + + premerge-checks-windows: + if: >- + github.repository_owner == 'llvm' && + (github.event_name != 'pull_request' || github.event.action != 'closed') + runs-on: llvm-premerge-windows-runners + defaults: + run: + shell: bash + steps: + - name: Checkout LLVM + uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2.14 + with: + variant: "sccache" + max-size: "2000M" + - name: Compute Projects + id: vars + run: | + modified_files=$(git diff --name-only HEAD~1...HEAD) + modified_dirs=$(echo "$modified_files" | cut -d'/' -f1 | sort | uniq) + + echo $modified_files + echo $modified_dirs + + . ./.ci/compute-projects.sh + + all_projects="bolt clang clang-tools-extra compiler-rt cross-project-tests flang libc libclc lld lldb llvm mlir openmp polly pstl" + modified_projects="$(keep-modified-projects ${all_projects})" + + windows_projects_to_test=$(exclude-windows $(compute-projects-to-test 1 ${modified_projects})) + windows_check_targets=$(check-targets ${windows_projects_to_test} | sort | uniq | tr -d '\r' | tr '\n' ' ') + windows_projects=$(add-dependencies ${windows_projects_to_test} | sort | uniq | tr -d '\r' | tr '\n' ';') + + if [[ "${windows_projects}" == "" ]]; then + echo "No projects to build" + fi + + echo "Building projects: ${windows_projects}" + echo "Running project checks targets: ${windows_check_targets}" + + echo "windows-projects=${windows_projects}" >> $GITHUB_OUTPUT + echo "windows-check-targets=${windows_check_targets}" >> $GITHUB_OUTPUT + - name: Build and Test + # Mark the job as a success even if the step fails so that people do + # not get notified while the new premerge pipeline is in an + # experimental state. + # TODO(boomanaiden154): Remove this once the pipeline is stable and we + # are ready for people to start recieving notifications. + continue-on-error: true + if: ${{ steps.vars.outputs.windows-projects != '' }} + shell: cmd + run: | + set MAX_PARALLEL_COMPILE_JOBS=64 + set MAX_PARALLEL_LINK_JOBS=64 + call C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat -arch=amd64 -host_arch=amd64 + bash .ci/monolithic-windows.sh "${{ steps.vars.outputs.windows-projects }}" "${{ steps.vars.outputs.windows-check-targets }}" + + permerge-check-macos: + runs-on: macos-14 + if: >- + github.repository_owner == 'llvm' && + (startswith(github.ref_name, 'release/') || + startswith(github.base_ref, 'release/')) && + (github.event_name != 'pull_request' || github.event.action != 'closed') + steps: + - name: Checkout LLVM + uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2.14 + with: + max-size: "2000M" + - name: Install Ninja + uses: llvm/actions/install-ninja@main + - name: Build and Test + run: | + modified_files=$(git diff --name-only HEAD~1...HEAD) + modified_dirs=$(echo "$modified_files" | cut -d'/' -f1 | sort -u) + + echo $modified_files + echo $modified_dirs + + . ./.ci/compute-projects.sh + + all_projects="clang clang-tools-extra lld lldb llvm mlir" + modified_projects="$(keep-modified-projects ${all_projects})" + + # We have to disable the runtimes builds due to https://github.com/llvm/llvm-project/issues/90568 + # and the lldb tests depend on libcxx, so we need to skip them. + mac_check_targets=$(check-targets ${modified_projects} | sort | uniq | tr '\n' ' ' | sed -e 's/check-lldb //g') + mac_projects=$(add-dependencies ${modified_projects} | sort | uniq | tr '\n' ' ') + + mac_runtimes_to_test=$(compute-runtimes-to-test ${modified_projects}) + mac_runtime_check_targets=$(check-targets ${mac_runtimes_to_test} | sort | uniq | tr '\n' ' ') + mac_runtimes=$(echo ${mac_runtimes_to_test} | tr ' ' '\n' | sort | uniq | tr '\n' ' ') + + if [[ "${mac_projects}" == "" ]]; then + echo "No projects to build" + exit 0 + fi + + echo "Projects to test: ${modified_projects}" + echo "Runtimes to test: ${mac_runtimes_to_test}" + echo "Building projects: ${mac_projects}" + echo "Running project checks targets: ${mac_check_targets}" + echo "Building runtimes: ${mac_runtimes}" + echo "Running runtimes checks targets: ${mac_runtime_check_targets}" + + # -DLLVM_DISABLE_ASSEMBLY_FILES=ON is for + # https://github.com/llvm/llvm-project/issues/81967 + # Disable sharding in lit so that the LIT_XFAIL environment var works. + cmake -G Ninja \ + -B build \ + -S llvm \ + -DLLVM_ENABLE_PROJECTS="$(echo ${mac_projects} | tr ' ' ';')" \ + -DLLVM_DISABLE_ASSEMBLY_FILES=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLDB_INCLUDE_TESTS=OFF \ + -DLLVM_ENABLE_ASSERTIONS=ON \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + + # The libcxx tests fail, so we are skipping the runtime targets. + ninja -C build $mac_check_targets diff --git a/.github/workflows/release-binaries-all.yml b/.github/workflows/release-binaries-all.yml index d5b2d33286101..d18b9b0b5c2ff 100644 --- a/.github/workflows/release-binaries-all.yml +++ b/.github/workflows/release-binaries-all.yml @@ -83,6 +83,7 @@ jobs: matrix: runs-on: - ubuntu-22.04 + - ubuntu-22.04-arm - macos-13 - macos-14 diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index f9a264e7cf48f..204ee6405382f 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -18,6 +18,7 @@ on: type: choice options: - ubuntu-22.04 + - ubuntu-22.04-arm - macos-13 - macos-14 @@ -55,8 +56,8 @@ jobs: ref: ${{ steps.vars.outputs.ref }} upload: ${{ steps.vars.outputs.upload }} target-cmake-flags: ${{ steps.vars.outputs.target-cmake-flags }} + ccache: ${{ steps.vars.outputs.ccache }} build-flang: ${{ steps.vars.outputs.build-flang }} - enable-pgo: ${{ steps.vars.outputs.enable-pgo }} release-binary-basename: ${{ steps.vars.outputs.release-binary-basename }} release-binary-filename: ${{ steps.vars.outputs.release-binary-filename }} build-runs-on: ${{ steps.vars.outputs.build-runs-on }} @@ -119,10 +120,15 @@ jobs: echo "release-binary-basename=$release_binary_basename" >> $GITHUB_OUTPUT echo "release-binary-filename=$release_binary_basename.tar.xz" >> $GITHUB_OUTPUT - # Detect necessary CMake flags target="$RUNNER_OS-$RUNNER_ARCH" - echo "enable-pgo=false" >> $GITHUB_OUTPUT - target_cmake_flags="-DLLVM_RELEASE_ENABLE_PGO=OFF" + # The hendrikmuhs/ccache-action action does not support installing sccache + # on arm64 Linux. + if [ "$target" = "Linux-ARM64" ]; then + echo ccache=ccache >> $GITHUB_OUTPUT + else + echo ccache=sccache >> $GITHUB_OUTPUT + fi + # The macOS builds try to cross compile some libraries so we need to # add extra CMake args to disable them. # See https://github.com/llvm/llvm-project/issues/99767 @@ -146,7 +152,7 @@ jobs: echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT echo "build-flang=$build_flang" >> $GITHUB_OUTPUT case "${{ inputs.runs-on }}" in - ubuntu-22.04) + ubuntu-22.04*) build_runs_on="depot-${{ inputs.runs-on }}-16" test_runs_on=$build_runs_on ;; @@ -216,17 +222,11 @@ jobs: id: setup-stage uses: ./workflows-main/.github/workflows/release-binaries-setup-stage - - name: Setup sccache - uses: hendrikmuhs/ccache-action@ca3acd2731eef11f1572ccb126356c2f9298d35e # v1.2.9 - with: - # Default to 2G to workaround: https://github.com/hendrikmuhs/ccache-action/issues/174 - max-size: 2G - key: sccache-${{ runner.os }}-${{ runner.arch }}-release - variant: sccache - - name: Configure id: build shell: bash + env: + CCACHE_BIN: ${{ needs.prepare.outputs.ccache }} run: | # There were some issues on the ARM64 MacOS runners with trying to build x86 object, # so we need to set some extra cmake flags to disable this. @@ -234,14 +234,14 @@ jobs: ${{ needs.prepare.outputs.target-cmake-flags }} \ -C clang/cmake/caches/Release.cmake \ -DBOOTSTRAP_LLVM_PARALLEL_LINK_JOBS=1 \ - -DBOOTSTRAP_CPACK_PACKAGE_FILE_NAME="${{ needs.prepare.outputs.release-binary-basename }}" \ - -DCMAKE_C_COMPILER_LAUNCHER=sccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + -DBOOTSTRAP_BOOTSTRAP_CPACK_PACKAGE_FILE_NAME="${{ needs.prepare.outputs.release-binary-basename }}" + - name: Build shell: bash run: | ninja -v -C ${{ steps.setup-stage.outputs.build-prefix }}/build stage2-package - mv ${{ steps.setup-stage.outputs.build-prefix }}/build/tools/clang/stage2-bins/${{ needs.prepare.outputs.release-binary-filename }} . + release_dir=`find ${{ steps.setup-stage.outputs.build-prefix }}/build -iname 'stage2-bins'` + mv $release_dir/${{ needs.prepare.outputs.release-binary-filename }} . - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0 with: @@ -256,7 +256,7 @@ jobs: shell: bash run: | find ${{ steps.setup-stage.outputs.build-prefix }}/build -iname ${{ needs.prepare.outputs.release-binary-filename }} -delete - rm -Rf ${{ steps.setup-stage.outputs.build-prefix }}/build/tools/clang/stage2-bins/_CPack_Packages + find ${{ steps.setup-stage.outputs.build-prefix }}/build -iname _CPack_Packages -prune -exec rm -r {} + - name: Save Stage uses: ./workflows-main/.github/workflows/release-binaries-save-stage diff --git a/.github/workflows/release-tasks.yml b/.github/workflows/release-tasks.yml index 780dd0ff6325c..52076ea1821b0 100644 --- a/.github/workflows/release-tasks.yml +++ b/.github/workflows/release-tasks.yml @@ -89,20 +89,10 @@ jobs: needs: - validate-tag - release-create - strategy: - fail-fast: false - matrix: - runs-on: - - ubuntu-22.04 - - windows-2022 - - macos-13 - - macos-14 - - uses: ./.github/workflows/release-binaries.yml + uses: ./.github/workflows/release-binaries-all.yml with: release-version: ${{ needs.validate-tag.outputs.release-version }} upload: true - runs-on: ${{ matrix.runs-on }} # Called workflows don't have access to secrets by default, so we need to explicitly pass secrets that we use. secrets: RELEASE_TASKS_USER_TOKEN: ${{ secrets.RELEASE_TASKS_USER_TOKEN }} diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index 94fe4aa8aa0e5..8bec1db70e25a 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -1435,6 +1435,17 @@ class BinaryContext { bool PrintRelocations = false, StringRef Endl = "\n") const; + /// Print data when embedded in the instruction stream keeping the format + /// similar to printInstruction(). + void printData(raw_ostream &OS, ArrayRef Data, + uint64_t Offset) const; + + /// Extract data from the binary corresponding to [Address, Address + Size) + /// range. Return an empty ArrayRef if the address range does not belong to + /// any section in the binary, crosses a section boundary, or falls into a + /// virtual section. + ArrayRef extractData(uint64_t Address, uint64_t Size) const; + /// Print a range of instructions. template uint64_t diff --git a/bolt/include/bolt/Core/BinaryFunction.h b/bolt/include/bolt/Core/BinaryFunction.h index e8b2757f7db21..942840a7621fd 100644 --- a/bolt/include/bolt/Core/BinaryFunction.h +++ b/bolt/include/bolt/Core/BinaryFunction.h @@ -2060,6 +2060,11 @@ class BinaryFunction { return Islands ? Islands->getAlignment() : 1; } + /// If there is a constant island in the range [StartOffset, EndOffset), + /// return its address. + std::optional getIslandInRange(uint64_t StartOffset, + uint64_t EndOffset) const; + uint64_t estimateConstantIslandSize(const BinaryFunction *OnBehalfOf = nullptr) const { if (!Islands) diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h b/bolt/include/bolt/Core/MCPlusBuilder.h index 5d77e6faff2fc..c1460b2aac8a6 100644 --- a/bolt/include/bolt/Core/MCPlusBuilder.h +++ b/bolt/include/bolt/Core/MCPlusBuilder.h @@ -1426,11 +1426,12 @@ class MCPlusBuilder { } /// Creates an indirect call to the function within the \p DirectCall PLT - /// stub. The function's memory location is pointed by the \p TargetLocation + /// stub. The function's address location is pointed by the \p TargetLocation /// symbol. + /// Move instruction annotations from \p DirectCall to the indirect call. virtual InstructionListType - createIndirectPltCall(const MCInst &DirectCall, - const MCSymbol *TargetLocation, MCContext *Ctx) { + createIndirectPLTCall(MCInst &&DirectCall, const MCSymbol *TargetLocation, + MCContext *Ctx) { llvm_unreachable("not implemented"); return {}; } diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index f5e11358daaa3..f9fc536f3569a 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -1759,7 +1759,11 @@ void BinaryContext::preprocessDebugInfo() { dwarf::toString(CU->getUnitDIE().find(dwarf::DW_AT_name), nullptr); if (std::optional DWOID = CU->getDWOId()) { auto Iter = DWOCUs.find(*DWOID); - assert(Iter != DWOCUs.end() && "DWO CU was not found."); + if (Iter == DWOCUs.end()) { + this->errs() << "BOLT-ERROR: DWO CU was not found for " << Name + << '\n'; + exit(1); + } Name = dwarf::toString( Iter->second->getUnitDIE().find(dwarf::DW_AT_name), nullptr); } @@ -1942,6 +1946,43 @@ static void printDebugInfo(raw_ostream &OS, const MCInst &Instruction, OS << " discriminator:" << Row.Discriminator; } +ArrayRef BinaryContext::extractData(uint64_t Address, + uint64_t Size) const { + ArrayRef Res; + + const ErrorOr Section = getSectionForAddress(Address); + if (!Section || Section->isVirtual()) + return Res; + + if (!Section->containsRange(Address, Size)) + return Res; + + auto *Bytes = + reinterpret_cast(Section->getContents().data()); + return ArrayRef(Bytes + Address - Section->getAddress(), Size); +} + +void BinaryContext::printData(raw_ostream &OS, ArrayRef Data, + uint64_t Offset) const { + DataExtractor DE(Data, AsmInfo->isLittleEndian(), + AsmInfo->getCodePointerSize()); + uint64_t DataOffset = 0; + while (DataOffset + 4 <= Data.size()) { + OS << format(" %08" PRIx64 ": \t.word\t0x", Offset + DataOffset); + const auto Word = DE.getUnsigned(&DataOffset, 4); + OS << Twine::utohexstr(Word) << '\n'; + } + if (DataOffset + 2 <= Data.size()) { + OS << format(" %08" PRIx64 ": \t.short\t0x", Offset + DataOffset); + const auto Short = DE.getUnsigned(&DataOffset, 2); + OS << Twine::utohexstr(Short) << '\n'; + } + if (DataOffset + 1 == Data.size()) { + OS << format(" %08" PRIx64 ": \t.byte\t0x%x\n", Offset + DataOffset, + Data[DataOffset]); + } +} + void BinaryContext::printInstruction(raw_ostream &OS, const MCInst &Instruction, uint64_t Offset, const BinaryFunction *Function, diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index 1c5cd62a095b2..bc45caf3ec8b7 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -491,11 +491,27 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation) { // Offset of the instruction in function. uint64_t Offset = 0; + auto printConstantIslandInRange = [&](uint64_t Start, uint64_t End) { + assert(Start <= End && "Invalid range"); + std::optional IslandOffset = getIslandInRange(Start, End); + + if (!IslandOffset) + return; + + const size_t IslandSize = getSizeOfDataInCodeAt(*IslandOffset); + BC.printData(OS, BC.extractData(getAddress() + *IslandOffset, IslandSize), + *IslandOffset); + }; + if (BasicBlocks.empty() && !Instructions.empty()) { // Print before CFG was built. + uint64_t PrevOffset = 0; for (const std::pair &II : Instructions) { Offset = II.first; + // Print any constant islands inbeetween the instructions. + printConstantIslandInRange(PrevOffset, Offset); + // Print label if exists at this offset. auto LI = Labels.find(Offset); if (LI != Labels.end()) { @@ -506,7 +522,12 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation) { } BC.printInstruction(OS, II.second, Offset, this); + + PrevOffset = Offset; } + + // Print any data at the end of the function. + printConstantIslandInRange(PrevOffset, getMaxSize()); } StringRef SplitPointMsg = ""; @@ -795,7 +816,6 @@ BinaryFunction::processIndirectBranch(MCInst &Instruction, unsigned Size, auto Begin = Instructions.begin(); if (BC.isAArch64()) { - PreserveNops = BC.HasRelocations; // Start at the last label as an approximation of the current basic block. // This is a heuristic, since the full set of labels have yet to be // determined @@ -1049,6 +1069,19 @@ size_t BinaryFunction::getSizeOfDataInCodeAt(uint64_t Offset) const { return getSize() - Offset; } +std::optional +BinaryFunction::getIslandInRange(uint64_t StartOffset, + uint64_t EndOffset) const { + if (!Islands) + return std::nullopt; + + auto Iter = llvm::lower_bound(Islands->DataOffsets, StartOffset); + if (Iter != Islands->DataOffsets.end() && *Iter < EndOffset) + return *Iter; + + return std::nullopt; +} + bool BinaryFunction::isZeroPaddingAt(uint64_t Offset) const { ArrayRef FunctionData = *getData(); uint64_t EndOfCode = getSize(); @@ -2300,6 +2333,10 @@ Error BinaryFunction::buildCFG(MCPlusBuilder::AllocatorIdTy AllocatorId) { BC.errs() << "BOLT-WARNING: failed to post-process indirect branches for " << *this << '\n'; } + + if (BC.isAArch64()) + PreserveNops = BC.HasRelocations; + // In relocation mode we want to keep processing the function but avoid // optimizing it. setSimple(false); diff --git a/bolt/lib/Passes/PLTCall.cpp b/bolt/lib/Passes/PLTCall.cpp index 2ed996fadbb99..31c2d92ebc204 100644 --- a/bolt/lib/Passes/PLTCall.cpp +++ b/bolt/lib/Passes/PLTCall.cpp @@ -70,8 +70,8 @@ Error PLTCall::runOnFunctions(BinaryContext &BC) { const BinaryFunction *CalleeBF = BC.getFunctionForSymbol(CallSymbol); if (!CalleeBF || !CalleeBF->isPLTFunction()) continue; - const InstructionListType NewCode = BC.MIB->createIndirectPltCall( - *II, CalleeBF->getPLTSymbol(), BC.Ctx.get()); + const InstructionListType NewCode = BC.MIB->createIndirectPLTCall( + std::move(*II), CalleeBF->getPLTSymbol(), BC.Ctx.get()); II = BB.replaceInstruction(II, NewCode); assert(!NewCode.empty() && "PLT Call replacement must be non-empty"); std::advance(II, NewCode.size() - 1); diff --git a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp index 336c6768a7f71..8f5719e84ecea 100644 --- a/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp +++ b/bolt/lib/RuntimeLibs/RuntimeLibrary.cpp @@ -18,6 +18,7 @@ #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" #define DEBUG_TYPE "bolt-rtlib" @@ -38,6 +39,23 @@ std::string RuntimeLibrary::getLibPathByToolPath(StringRef ToolPath, llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX); } llvm::sys::path::append(LibPath, LibFileName); + if (!llvm::sys::fs::exists(LibPath)) { + // If it is a symlink, check the directory that the symlink points to. + if (llvm::sys::fs::is_symlink_file(ToolPath)) { + SmallString<256> RealPath; + llvm::sys::fs::real_path(ToolPath, RealPath); + if (llvm::ErrorOr P = + llvm::sys::findProgramByName(RealPath)) { + outs() << "BOLT-INFO: library not found: " << LibPath << "\n" + << "BOLT-INFO: " << ToolPath << " is a symlink; will look up " + << LibFileName + << " at the target directory that the symlink points to\n"; + return getLibPath(*P, LibFileName); + } + } + errs() << "BOLT-ERROR: library not found: " << LibPath << "\n"; + exit(1); + } return std::string(LibPath); } diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index 0b6f21527f0ac..4b21ff719b3ab 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -834,6 +834,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { /// # of this BB) /// br x0 # Indirect jump instruction /// + /// Return true on successful jump table instruction sequence match, false + /// otherwise. bool analyzeIndirectBranchFragment( const MCInst &Inst, DenseMap> &UDChain, @@ -842,6 +844,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { // Expect AArch64 BR assert(Inst.getOpcode() == AArch64::BR && "Unexpected opcode"); + JumpTable = nullptr; + // Match the indirect branch pattern for aarch64 SmallVector &UsesRoot = UDChain[&Inst]; if (UsesRoot.size() == 0 || UsesRoot[0] == nullptr) @@ -879,8 +883,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { // Parsed as ADDXrs reg:x8 reg:x8 reg:x12 imm:0 return false; } - assert(DefAdd->getOpcode() == AArch64::ADDXrx && - "Failed to match indirect branch!"); + if (DefAdd->getOpcode() != AArch64::ADDXrx) + return false; // Validate ADD operands int64_t OperandExtension = DefAdd->getOperand(3).getImm(); @@ -897,8 +901,8 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { // ldr w7, [x6] // add x6, x6, w7, sxtw => no shift amount // br x6 - errs() << "BOLT-WARNING: " - "Failed to match indirect branch: ShiftVAL != 2 \n"; + LLVM_DEBUG(dbgs() << "BOLT-DEBUG: " + "failed to match indirect branch: ShiftVAL != 2\n"); return false; } @@ -909,7 +913,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { else if (ExtendType == AArch64_AM::SXTW) ScaleValue = 4LL; else - llvm_unreachable("Failed to match indirect branch! (fragment 3)"); + return false; // Match an ADR to load base address to be used when addressing JT targets SmallVector &UsesAdd = UDChain[DefAdd]; @@ -920,18 +924,15 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { return false; } MCInst *DefBaseAddr = UsesAdd[1]; - assert(DefBaseAddr->getOpcode() == AArch64::ADR && - "Failed to match indirect branch pattern! (fragment 3)"); + if (DefBaseAddr->getOpcode() != AArch64::ADR) + return false; PCRelBase = DefBaseAddr; // Match LOAD to load the jump table (relative) target const MCInst *DefLoad = UsesAdd[2]; - assert(mayLoad(*DefLoad) && - "Failed to match indirect branch load pattern! (1)"); - assert((ScaleValue != 1LL || isLDRB(*DefLoad)) && - "Failed to match indirect branch load pattern! (2)"); - assert((ScaleValue != 2LL || isLDRH(*DefLoad)) && - "Failed to match indirect branch load pattern! (3)"); + if (!mayLoad(*DefLoad) || (ScaleValue == 1LL && !isLDRB(*DefLoad)) || + (ScaleValue == 2LL && !isLDRH(*DefLoad))) + return false; // Match ADD that calculates the JumpTable Base Address (not the offset) SmallVector &UsesLoad = UDChain[DefLoad]; @@ -941,7 +942,6 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { isRegToRegMove(*DefJTBaseAdd, From, To)) { // Sometimes base address may have been defined in another basic block // (hoisted). Return with no jump table info. - JumpTable = nullptr; return true; } @@ -953,24 +953,27 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { // adr x12, 0x247b30 <__gettextparse+0x5b0> // add x13, x12, w13, sxth #2 // br x13 - errs() << "BOLT-WARNING: Failed to match indirect branch: " - "nop/adr instead of adrp/add \n"; + LLVM_DEBUG(dbgs() << "BOLT-DEBUG: failed to match indirect branch: " + "nop/adr instead of adrp/add\n"); return false; } - assert(DefJTBaseAdd->getOpcode() == AArch64::ADDXri && - "Failed to match jump table base address pattern! (1)"); + if (DefJTBaseAdd->getOpcode() != AArch64::ADDXri) { + LLVM_DEBUG(dbgs() << "BOLT-DEBUG: failed to match jump table base " + "address pattern! (1)\n"); + return false; + } if (DefJTBaseAdd->getOperand(2).isImm()) Offset = DefJTBaseAdd->getOperand(2).getImm(); SmallVector &UsesJTBaseAdd = UDChain[DefJTBaseAdd]; const MCInst *DefJTBasePage = UsesJTBaseAdd[1]; if (DefJTBasePage == nullptr || isLoadFromStack(*DefJTBasePage)) { - JumpTable = nullptr; return true; } - assert(DefJTBasePage->getOpcode() == AArch64::ADRP && - "Failed to match jump table base page pattern! (2)"); + if (DefJTBasePage->getOpcode() != AArch64::ADRP) + return false; + if (DefJTBasePage->getOperand(1).isExpr()) JumpTable = DefJTBasePage->getOperand(1).getExpr(); return true; @@ -1263,7 +1266,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { return true; } - InstructionListType createIndirectPltCall(const MCInst &DirectCall, + InstructionListType createIndirectPLTCall(MCInst &&DirectCall, const MCSymbol *TargetLocation, MCContext *Ctx) override { const bool IsTailCall = isTailCall(DirectCall); @@ -1297,8 +1300,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder { MCInst InstCall; InstCall.setOpcode(IsTailCall ? AArch64::BR : AArch64::BLR); InstCall.addOperand(MCOperand::createReg(AArch64::X17)); - if (IsTailCall) - setTailCall(InstCall); + moveAnnotations(std::move(DirectCall), InstCall); Code.emplace_back(InstCall); return Code; diff --git a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp index 63086c06d74fd..465533ee71f2b 100644 --- a/bolt/lib/Target/X86/X86MCPlusBuilder.cpp +++ b/bolt/lib/Target/X86/X86MCPlusBuilder.cpp @@ -1605,7 +1605,7 @@ class X86MCPlusBuilder : public MCPlusBuilder { return true; } - InstructionListType createIndirectPltCall(const MCInst &DirectCall, + InstructionListType createIndirectPLTCall(MCInst &&DirectCall, const MCSymbol *TargetLocation, MCContext *Ctx) override { assert((DirectCall.getOpcode() == X86::CALL64pcrel32 || diff --git a/bolt/test/AArch64/data-in-code.s b/bolt/test/AArch64/data-in-code.s new file mode 100644 index 0000000000000..8d3179a0c3350 --- /dev/null +++ b/bolt/test/AArch64/data-in-code.s @@ -0,0 +1,31 @@ +## Check that llvm-bolt prints data embedded in code. + +# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags -fno-PIC -no-pie %t.o -o %t.exe -nostdlib \ +# RUN: -fuse-ld=lld -Wl,-q + +## Check disassembly of BOLT input. +# RUN: llvm-objdump %t.exe -d | FileCheck %s + +# RUN: llvm-bolt %t.exe -o %t.bolt --print-disasm | FileCheck %s + +.text +.balign 4 + +.global _start +.type _start, %function +_start: + mov x0, #0x0 + .word 0x4f82e010 + ret + .byte 0x0, 0xff, 0x42 +# CHECK-LABEL: _start +# CHECK: mov x0, #0x0 +# CHECK-NEXT: .word 0x4f82e010 +# CHECK-NEXT: ret +# CHECK-NEXT: .short 0xff00 +# CHECK-NEXT: .byte 0x42 +.size _start, .-_start + +## Force relocation mode. + .reloc 0, R_AARCH64_NONE diff --git a/bolt/test/AArch64/exceptions-plt.cpp b/bolt/test/AArch64/exceptions-plt.cpp new file mode 100644 index 0000000000000..33c28406ca8d6 --- /dev/null +++ b/bolt/test/AArch64/exceptions-plt.cpp @@ -0,0 +1,23 @@ +// Verify that PLT optimization in BOLT preserves exception-handling info. + +// REQUIRES: system-linux + +// RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so +// Link against a DSO to ensure PLT entries. +// RUN: %clangxx %cxxflags -O1 -Wl,-q,-znow %s %t.so -o %t.exe +// RUN: llvm-bolt %t.exe -o %t.bolt.exe --plt=all --print-only=.*main.* \ +// RUN: --print-finalized 2>&1 | FileCheck %s + +// CHECK-LABEL: Binary Function +// CHECK: adrp {{.*}}__cxa_throw +// CHECK-NEXT: ldr {{.*}}__cxa_throw +// CHECK-NEXT: blr x17 {{.*}} handler: {{.*}} PLTCall: + +int main() { + try { + throw new int; + } catch (...) { + return 0; + } + return 1; +} diff --git a/bolt/test/AArch64/jump-table-heuristic-fail.s b/bolt/test/AArch64/jump-table-heuristic-fail.s new file mode 100644 index 0000000000000..724171ac39925 --- /dev/null +++ b/bolt/test/AArch64/jump-table-heuristic-fail.s @@ -0,0 +1,29 @@ +## Verify that BOLT does not crash while encountering instruction sequence that +## does not perfectly match jump table pattern. + +# REQUIRES: system-linux + +# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg 2>&1 | FileCheck %s + + .section .text + .align 4 + .globl _start + .type _start, %function +_start: + sub w0, w0, #0x4a +## The address loaded into x22 is undefined. However, the instructions that +## follow ldr, use the x22 address as a regular jump table. + ldr x22, [x29, #0x98] + ldrb w0, [x22, w0, uxtw] + adr x1, #12 + add x0, x1, w0, sxtb #2 + br x0 +# CHECK: br x0 # UNKNOWN +.L0: + ret +.size _start, .-_start + +## Force relocation mode. + .reloc 0, R_AARCH64_NONE diff --git a/bolt/test/AArch64/pad-before-funcs.s b/bolt/test/AArch64/pad-before-funcs.s index f3e8a23ddfdda..c1b92063d6fa4 100644 --- a/bolt/test/AArch64/pad-before-funcs.s +++ b/bolt/test/AArch64/pad-before-funcs.s @@ -15,7 +15,7 @@ # RUN: llvm-bolt %t.exe -o %t.bolt.4.4 --pad-funcs-before=_start:4 --pad-funcs=_start:4 # RUN: llvm-bolt %t.exe -o %t.bolt.4.8 --pad-funcs-before=_start:4 --pad-funcs=_start:8 -# RUN: not llvm-bolt %t.exe -o %t.bolt.8 --pad-funcs-before=_start:1 2>&1 | FileCheck --check-prefix=CHECK-BAD-ALIGN %s +# RUN: not llvm-bolt %t.exe -o %t.bolt.1 --pad-funcs-before=_start:1 2>&1 | FileCheck --check-prefix=CHECK-BAD-ALIGN %s # CHECK-BAD-ALIGN: user-requested 1 padding bytes before function _start(*2) is not a multiple of the minimum function alignment (4). diff --git a/bolt/test/AArch64/plt-call.test b/bolt/test/AArch64/plt-call.test index da307d4a6c01e..1fa62c4a36aaf 100644 --- a/bolt/test/AArch64/plt-call.test +++ b/bolt/test/AArch64/plt-call.test @@ -1,6 +1,8 @@ // Verify that PLTCall optimization works. -RUN: %clang %cflags %p/../Inputs/plt-tailcall.c \ +RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so +// Link against a DSO to ensure PLT entries. +RUN: %clang %cflags %p/../Inputs/plt-tailcall.c %t.so \ RUN: -o %t -Wl,-q RUN: llvm-bolt %t -o %t.bolt --plt=all --print-plt --print-only=foo | FileCheck %s diff --git a/bolt/test/AArch64/remove-nops.s b/bolt/test/AArch64/remove-nops.s new file mode 100644 index 0000000000000..0f02a4b273dda --- /dev/null +++ b/bolt/test/AArch64/remove-nops.s @@ -0,0 +1,28 @@ +## Verify that llvm-bolt removes nop instructions from functions with indirect +## branches that have defined control flow. + +# REQUIRES: system-linux + +# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --print-normalized 2>&1 | FileCheck %s +# RUN: llvm-objdump -d --disassemble-symbols=_start %t.bolt \ +# RUN: | FileCheck %s --check-prefix=CHECK-OBJDUMP + +# CHECK-OBJDUMP-LABEL: _start +# CHECK-OBJDUMP-NOT: nop + + .section .text + .align 4 + .globl _start + .type _start, %function +_start: +# CHECK-LABEL: Binary Function "_start" + nop +# CHECK-NOT: nop + br x0 +# CHECK: br x0 # TAILCALL +.size _start, .-_start + +## Force relocation mode. + .reloc 0, R_AARCH64_NONE diff --git a/bolt/test/AArch64/test-indirect-branch.s b/bolt/test/AArch64/test-indirect-branch.s index 168e50c8f47f5..1e16e76b11530 100644 --- a/bolt/test/AArch64/test-indirect-branch.s +++ b/bolt/test/AArch64/test-indirect-branch.s @@ -3,10 +3,11 @@ // clang-format off -// REQUIRES: system-linux +// REQUIRES: system-linux, asserts + // RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o // RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q -// RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg --strict\ +// RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg --strict --debug-only=mcplus \ // RUN: -v=1 2>&1 | FileCheck %s // Pattern 1: there is no shift amount after the 'add' instruction. @@ -39,7 +40,7 @@ _start: // svc #0 // Pattern 1 -// CHECK: BOLT-WARNING: Failed to match indirect branch: ShiftVAL != 2 +// CHECK: BOLT-DEBUG: failed to match indirect branch: ShiftVAL != 2 .globl test1 .type test1, %function test1: @@ -57,7 +58,7 @@ test1_2: ret // Pattern 2 -// CHECK: BOLT-WARNING: Failed to match indirect branch: nop/adr instead of adrp/add +// CHECK: BOLT-DEBUG: failed to match indirect branch: nop/adr instead of adrp/add .globl test2 .type test2, %function test2: diff --git a/bolt/test/X86/callcont-fallthru.s b/bolt/test/X86/callcont-fallthru.s index 31a7910d7fa3f..d76f869c971fd 100644 --- a/bolt/test/X86/callcont-fallthru.s +++ b/bolt/test/X86/callcont-fallthru.s @@ -1,7 +1,9 @@ ## Ensures that a call continuation fallthrough count is set when using ## pre-aggregated perf data. -# RUN: %clangxx %cxxflags %s -o %t -Wl,-q -nostdlib +# RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so +## Link against a DSO to ensure PLT entries. +# RUN: %clangxx %cxxflags %s %t.so -o %t -Wl,-q -nostdlib # RUN: link_fdata %s %t %t.pa1 PREAGG # RUN: link_fdata %s %t %t.pa2 PREAGG2 # RUN: link_fdata %s %t %t.pa3 PREAGG3 diff --git a/bolt/test/X86/cfi-instrs-reordered.s b/bolt/test/X86/cfi-instrs-reordered.s index c325aaf1ad8b1..5173fa6c3c7d0 100644 --- a/bolt/test/X86/cfi-instrs-reordered.s +++ b/bolt/test/X86/cfi-instrs-reordered.s @@ -3,7 +3,9 @@ # RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o # RUN: llvm-strip --strip-unneeded %t.o -# RUN: %clangxx %cflags %t.o -o %t.exe +# RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so +## Link against a DSO to ensure PLT entries. +# RUN: %clangxx %cflags %t.o %t.so -o %t.exe # RUN: llvm-bolt %t.exe -o %t --reorder-blocks=cache --print-after-lowering \ # RUN: --print-only=_Z10SolveCubicddddPiPd 2>&1 | FileCheck %s # diff --git a/bolt/test/X86/dynamic-relocs-on-entry.s b/bolt/test/X86/dynamic-relocs-on-entry.s index 2a29a43c4939a..4ec8ba4ad4460 100644 --- a/bolt/test/X86/dynamic-relocs-on-entry.s +++ b/bolt/test/X86/dynamic-relocs-on-entry.s @@ -4,12 +4,12 @@ # RUN: %clang %cflags -fPIC -pie %s -o %t.exe -nostdlib -Wl,-q # RUN: llvm-bolt %t.exe -o %t.bolt > %t.out.txt -# RUN: readelf -r %t.bolt >> %t.out.txt +# RUN: llvm-readelf -r %t.bolt >> %t.out.txt # RUN: llvm-objdump --disassemble-symbols=chain %t.bolt >> %t.out.txt # RUN: FileCheck %s --input-file=%t.out.txt ## Check if the new address in `chain` is correctly updated by BOLT -# CHECK: Relocation section '.rela.dyn' at offset 0x{{.*}} contains 1 entry: +# CHECK: Relocation section '.rela.dyn' at offset 0x{{.*}} contains 1 entries: # CHECK: {{.*}} R_X86_64_RELATIVE [[#%x,ADDR:]] # CHECK: [[#ADDR]]: c3 retq .text @@ -29,4 +29,4 @@ _start: .data .Lfoo: - .quad Label \ No newline at end of file + .quad Label diff --git a/bolt/test/X86/plt-call.test b/bolt/test/X86/plt-call.test index e6ae86c179d27..aeee3024ac170 100644 --- a/bolt/test/X86/plt-call.test +++ b/bolt/test/X86/plt-call.test @@ -1,6 +1,8 @@ // Verify that PLTCall optimization works. -RUN: %clang %cflags %p/../Inputs/plt-tailcall.c \ +RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so +// Link against a DSO to ensure PLT entries. +RUN: %clang %cflags %p/../Inputs/plt-tailcall.c %t.so \ RUN: -o %t -Wl,-q RUN: llvm-bolt %t -o %t.bolt --plt=all --print-plt --print-only=foo | FileCheck %s diff --git a/bolt/test/runtime/exceptions-plt.cpp b/bolt/test/runtime/exceptions-plt.cpp new file mode 100644 index 0000000000000..3d8e7a5133e2c --- /dev/null +++ b/bolt/test/runtime/exceptions-plt.cpp @@ -0,0 +1,18 @@ +// Verify that PLT optimization in BOLT preserves exception-handling info. + +// REQUIRES: system-linux + +// RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so +// Link against a DSO to ensure PLT entries. +// RUN: %clangxx %cxxflags -O1 -Wl,-q,-znow %s %t.so -o %t.exe +// RUN: llvm-bolt %t.exe -o %t.bolt.exe --plt=all +// RUN: %t.bolt.exe + +int main() { + try { + throw new int; + } catch (...) { + return 0; + } + return 1; +} diff --git a/bolt/test/runtime/plt-lld.test b/bolt/test/runtime/plt-lld.test index b505a191f90ab..3432e18bf4daf 100644 --- a/bolt/test/runtime/plt-lld.test +++ b/bolt/test/runtime/plt-lld.test @@ -1,14 +1,15 @@ // This test checks that the pointers to PLT are properly updated. -// The test is using lld linker. +// The test uses lld and links against a DSO to ensure PLT entries. +RUN: %clang %cflags -fpic -shared -xc /dev/null -o %t.so // Non-PIE: -RUN: %clang %cflags -no-pie %p/../Inputs/plt.c -fuse-ld=lld \ +RUN: %clang %cflags -no-pie %p/../Inputs/plt.c %t.so -fuse-ld=lld \ RUN: -o %t.lld.exe -Wl,-q RUN: llvm-bolt %t.lld.exe -o %t.lld.bolt.exe --use-old-text=0 --lite=0 RUN: %t.lld.bolt.exe | FileCheck %s // PIE: -RUN: %clang %cflags -fPIC -pie %p/../Inputs/plt.c -fuse-ld=lld \ +RUN: %clang %cflags -fPIC -pie %p/../Inputs/plt.c %t.so -fuse-ld=lld \ RUN: -o %t.lld.pie.exe -Wl,-q RUN: llvm-bolt %t.lld.pie.exe -o %t.lld.bolt.pie.exe --use-old-text=0 --lite=0 RUN: %t.lld.bolt.pie.exe | FileCheck %s diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index e3532559a32fc..18a0de826630c 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -494,18 +494,31 @@ genReferencesBlock(const std::vector &References, static std::unique_ptr writeFileDefinition(const Location &L, std::optional RepositoryUrl = std::nullopt) { - if (!L.IsFileInRootDir || !RepositoryUrl) + if (!L.IsFileInRootDir && !RepositoryUrl) return std::make_unique( HTMLTag::TAG_P, "Defined at line " + std::to_string(L.LineNumber) + " of file " + L.Filename); SmallString<128> FileURL(*RepositoryUrl); - llvm::sys::path::append(FileURL, llvm::sys::path::Style::posix, L.Filename); + llvm::sys::path::append( + FileURL, llvm::sys::path::Style::posix, + // If we're on Windows, the file name will be in the wrong format, and + // append won't convert the full path being appended to the correct + // format, so we need to do that here. + llvm::sys::path::convert_to_slash( + L.Filename, + // The style here is the current style of the path, not the one we're + // targeting. If the string is already in the posix style, it will do + // nothing. + llvm::sys::path::Style::windows)); auto Node = std::make_unique(HTMLTag::TAG_P); Node->Children.emplace_back(std::make_unique("Defined at line ")); auto LocNumberNode = std::make_unique(HTMLTag::TAG_A, std::to_string(L.LineNumber)); // The links to a specific line in the source code use the github / // googlesource notation so it won't work for all hosting pages. + // FIXME: we probably should have a configuration setting for line number + // rendering in the HTML. For example, GitHub uses #L22, while googlesource + // uses #22 for line numbers. LocNumberNode->Attributes.emplace_back( "href", (FileURL + "#" + std::to_string(L.LineNumber)).str()); Node->Children.emplace_back(std::move(LocNumberNode)); @@ -964,7 +977,7 @@ HTMLGenerator::generateDocs(StringRef RootDir, for (const auto &Group : FileToInfos) { std::error_code FileErr; llvm::raw_fd_ostream InfoOS(Group.getKey(), FileErr, - llvm::sys::fs::OF_None); + llvm::sys::fs::OF_Text); if (FileErr) { return llvm::createStringError(FileErr, "Error opening file '%s'", Group.getKey().str().c_str()); @@ -1047,7 +1060,7 @@ static llvm::Error serializeIndex(ClangDocContext &CDCtx) { llvm::SmallString<128> FilePath; llvm::sys::path::native(CDCtx.OutDirectory, FilePath); llvm::sys::path::append(FilePath, "index_json.js"); - llvm::raw_fd_ostream OS(FilePath, FileErr, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream OS(FilePath, FileErr, llvm::sys::fs::OF_Text); if (FileErr != OK) { return llvm::createStringError(llvm::inconvertibleErrorCode(), "error creating index file: " + @@ -1108,7 +1121,7 @@ static llvm::Error genIndex(const ClangDocContext &CDCtx) { llvm::SmallString<128> IndexPath; llvm::sys::path::native(CDCtx.OutDirectory, IndexPath); llvm::sys::path::append(IndexPath, "index.html"); - llvm::raw_fd_ostream IndexOS(IndexPath, FileErr, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream IndexOS(IndexPath, FileErr, llvm::sys::fs::OF_Text); if (FileErr != OK) { return llvm::createStringError(llvm::inconvertibleErrorCode(), "error creating main index: " + diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index 28b645cf021dd..7bef2c0db04d8 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -300,7 +300,7 @@ static llvm::Error serializeIndex(ClangDocContext &CDCtx) { llvm::SmallString<128> FilePath; llvm::sys::path::native(CDCtx.OutDirectory, FilePath); llvm::sys::path::append(FilePath, "all_files.md"); - llvm::raw_fd_ostream OS(FilePath, FileErr, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream OS(FilePath, FileErr, llvm::sys::fs::OF_Text); if (FileErr) return llvm::createStringError(llvm::inconvertibleErrorCode(), "error creating index file: " + @@ -323,7 +323,7 @@ static llvm::Error genIndex(ClangDocContext &CDCtx) { llvm::SmallString<128> FilePath; llvm::sys::path::native(CDCtx.OutDirectory, FilePath); llvm::sys::path::append(FilePath, "index.md"); - llvm::raw_fd_ostream OS(FilePath, FileErr, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream OS(FilePath, FileErr, llvm::sys::fs::OF_Text); if (FileErr) return llvm::createStringError(llvm::inconvertibleErrorCode(), "error creating index file: " + @@ -407,7 +407,7 @@ MDGenerator::generateDocs(StringRef RootDir, for (const auto &Group : FileToInfos) { std::error_code FileErr; llvm::raw_fd_ostream InfoOS(Group.getKey(), FileErr, - llvm::sys::fs::OF_None); + llvm::sys::fs::OF_Text); if (FileErr) { return llvm::createStringError(FileErr, "Error opening file '%s'", Group.getKey().str().c_str()); diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp index b612380a3cfa7..ffabd2fd82229 100644 --- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp @@ -347,7 +347,7 @@ YAMLGenerator::generateDocs(StringRef RootDir, } std::error_code FileErr; - llvm::raw_fd_ostream InfoOS(Path, FileErr, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream InfoOS(Path, FileErr, llvm::sys::fs::OF_Text); if (FileErr) { return llvm::createStringError(FileErr, "Error opening file '%s'", Path.c_str()); diff --git a/clang-tools-extra/clang-include-fixer/FuzzySymbolIndex.cpp b/clang-tools-extra/clang-include-fixer/FuzzySymbolIndex.cpp index 91e2a9396a559..98987ad380196 100644 --- a/clang-tools-extra/clang-include-fixer/FuzzySymbolIndex.cpp +++ b/clang-tools-extra/clang-include-fixer/FuzzySymbolIndex.cpp @@ -131,7 +131,7 @@ FuzzySymbolIndex::queryRegexp(const std::vector &Tokens) { llvm::Expected> FuzzySymbolIndex::createFromYAML(StringRef FilePath) { - auto Buffer = llvm::MemoryBuffer::getFile(FilePath); + auto Buffer = llvm::MemoryBuffer::getFile(FilePath, /*IsText=*/true); if (!Buffer) return llvm::errorCodeToError(Buffer.getError()); return std::make_unique( diff --git a/clang-tools-extra/clang-include-fixer/YamlSymbolIndex.cpp b/clang-tools-extra/clang-include-fixer/YamlSymbolIndex.cpp index 4271d9aa4e677..7f570ee917197 100644 --- a/clang-tools-extra/clang-include-fixer/YamlSymbolIndex.cpp +++ b/clang-tools-extra/clang-include-fixer/YamlSymbolIndex.cpp @@ -22,7 +22,7 @@ namespace include_fixer { llvm::ErrorOr> YamlSymbolIndex::createFromFile(llvm::StringRef FilePath) { - auto Buffer = llvm::MemoryBuffer::getFile(FilePath); + auto Buffer = llvm::MemoryBuffer::getFile(FilePath, /*IsText=*/true); if (!Buffer) return Buffer.getError(); diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp index 298b02e77cb0a..6bac717bbb013 100644 --- a/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp +++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp @@ -95,7 +95,7 @@ bool Merge(llvm::StringRef MergeDir, llvm::StringRef OutputFile) { // Parse YAML files in parallel. Pool.async( [&AddSymbols](std::string Path) { - auto Buffer = llvm::MemoryBuffer::getFile(Path); + auto Buffer = llvm::MemoryBuffer::getFile(Path, /*IsText=*/true); if (!Buffer) { llvm::errs() << "Can't open " << Path << "\n"; return; @@ -114,7 +114,7 @@ bool Merge(llvm::StringRef MergeDir, llvm::StringRef OutputFile) { } } - llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::OF_Text); if (EC) { llvm::errs() << "Can't open '" << OutputFile << "': " << EC.message() << '\n'; diff --git a/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp b/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp index 3a11a22def194..6e51f25a66407 100644 --- a/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp +++ b/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp @@ -415,7 +415,7 @@ int includeFixerMain(int argc, const char **argv) { llvm::errs() << llvm::toString(InsertStyle.takeError()) << "\n"; return 1; } - auto Buffer = llvm::MemoryBuffer::getFile(FilePath); + auto Buffer = llvm::MemoryBuffer::getFile(FilePath, /*IsText=*/true); if (!Buffer) { errs() << "Couldn't open file: " + FilePath.str() + ": " << Buffer.getError().message() + "\n"; diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830..d1902b658061b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -82,7 +82,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxConstructExpr( hasDeclaration(cxxMethodDecl(hasName("basic_string"))), - hasArgument(0, hasType(qualType(isInteger()))), + argumentCountIs(2), hasArgument(0, hasType(qualType(isInteger()))), hasArgument(1, hasType(qualType(isInteger()))), anyOf( // Detect the expression: string('x', 40); @@ -102,7 +102,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { cxxConstructExpr( hasDeclaration(cxxConstructorDecl(ofClass( cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)))))), - hasArgument(0, hasType(CharPtrType)), + argumentCountIs(2), hasArgument(0, hasType(CharPtrType)), hasArgument(1, hasType(isInteger())), anyOf( // Detect the expression: string("...", 0); @@ -114,7 +114,34 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { // Detect the expression: string("lit", 5) allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), hasArgument(1, ignoringParenImpCasts( - integerLiteral().bind("int")))))) + integerLiteral().bind("length")))))) + .bind("constructor"), + this); + + // Check the literal string constructor with char pointer, start position and + // length parameters. [i.e. string (const char* s, size_t pos, size_t count);] + Finder->addMatcher( + cxxConstructExpr( + hasDeclaration(cxxConstructorDecl(ofClass( + cxxRecordDecl(hasAnyName(removeNamespaces(StringNames)))))), + argumentCountIs(3), hasArgument(0, hasType(CharPtrType)), + hasArgument(1, hasType(qualType(isInteger()))), + hasArgument(2, hasType(qualType(isInteger()))), + anyOf( + // Detect the expression: string("...", 1, 0); + hasArgument(2, ZeroExpr.bind("empty-string")), + // Detect the expression: string("...", -4, 1); + hasArgument(1, NegativeExpr.bind("negative-pos")), + // Detect the expression: string("...", 0, -4); + hasArgument(2, NegativeExpr.bind("negative-length")), + // Detect the expression: string("lit", 0, 0x1234567); + hasArgument(2, LargeLengthExpr.bind("large-length")), + // Detect the expression: string("lit", 1, 5) + allOf(hasArgument(0, ConstStrLiteral.bind("literal-with-length")), + hasArgument( + 1, ignoringParenImpCasts(integerLiteral().bind("pos"))), + hasArgument(2, ignoringParenImpCasts( + integerLiteral().bind("length")))))) .bind("constructor"), this); @@ -155,14 +182,27 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { diag(Loc, "constructor creating an empty string"); } else if (Result.Nodes.getNodeAs("negative-length")) { diag(Loc, "negative value used as length parameter"); + } else if (Result.Nodes.getNodeAs("negative-pos")) { + diag(Loc, "negative value used as position of the " + "first character parameter"); } else if (Result.Nodes.getNodeAs("large-length")) { if (WarnOnLargeLength) diag(Loc, "suspicious large length parameter"); } else if (Result.Nodes.getNodeAs("literal-with-length")) { const auto *Str = Result.Nodes.getNodeAs("str"); - const auto *Lit = Result.Nodes.getNodeAs("int"); - if (Lit->getValue().ugt(Str->getLength())) { + const auto *Length = Result.Nodes.getNodeAs("length"); + if (Length->getValue().ugt(Str->getLength())) { diag(Loc, "length is bigger than string literal size"); + return; + } + if (const auto *Pos = Result.Nodes.getNodeAs("pos")) { + if (Pos->getValue().uge(Str->getLength())) { + diag(Loc, "position of the first character parameter is bigger than " + "string literal character range"); + } else if (Length->getValue().ugt( + (Str->getLength() - Pos->getValue()).getZExtValue())) { + diag(Loc, "length is bigger than remaining string literal size"); + } } } else if (const auto *Ptr = Result.Nodes.getNodeAs("from-ptr")) { Expr::EvalResult ConstPtr; diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp index 604a7cac0e490..a45949314a4ca 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp @@ -256,13 +256,32 @@ void UnsafeFunctionsCheck::registerMatchers(MatchFinder *Finder) { .bind(CustomFunctionNamesId))) .bind(DeclRefId), this); + // C++ member calls do not contain a DeclRefExpr to the function decl. + // Instead, they contain a MemberExpr that refers to the decl. + Finder->addMatcher(memberExpr(member(functionDecl(CustomFunctionsMatcher) + .bind(CustomFunctionNamesId))) + .bind(DeclRefId), + this); } } void UnsafeFunctionsCheck::check(const MatchFinder::MatchResult &Result) { - const auto *DeclRef = Result.Nodes.getNodeAs(DeclRefId); - const auto *FuncDecl = cast(DeclRef->getDecl()); - assert(DeclRef && FuncDecl && "No valid matched node in check()"); + const Expr *SourceExpr; + const FunctionDecl *FuncDecl; + + if (const auto *DeclRef = Result.Nodes.getNodeAs(DeclRefId)) { + SourceExpr = DeclRef; + FuncDecl = cast(DeclRef->getDecl()); + } else if (const auto *Member = + Result.Nodes.getNodeAs(DeclRefId)) { + SourceExpr = Member; + FuncDecl = cast(Member->getMemberDecl()); + } else { + llvm_unreachable("No valid matched node in check()"); + return; + } + + assert(SourceExpr && FuncDecl && "No valid matched node in check()"); // Only one of these are matched at a time. const auto *AnnexK = Result.Nodes.getNodeAs( @@ -286,14 +305,15 @@ void UnsafeFunctionsCheck::check(const MatchFinder::MatchResult &Result) { Entry.Reason.empty() ? "is marked as unsafe" : Entry.Reason.c_str(); if (Entry.Replacement.empty()) { - diag(DeclRef->getExprLoc(), "function %0 %1; it should not be used") + diag(SourceExpr->getExprLoc(), + "function %0 %1; it should not be used") << FuncDecl << Reason << Entry.Replacement - << DeclRef->getSourceRange(); + << SourceExpr->getSourceRange(); } else { - diag(DeclRef->getExprLoc(), + diag(SourceExpr->getExprLoc(), "function %0 %1; '%2' should be used instead") << FuncDecl << Reason << Entry.Replacement - << DeclRef->getSourceRange(); + << SourceExpr->getSourceRange(); } return; @@ -323,9 +343,9 @@ void UnsafeFunctionsCheck::check(const MatchFinder::MatchResult &Result) { if (!ReplacementFunctionName) return; - diag(DeclRef->getExprLoc(), "function %0 %1; '%2' should be used instead") + diag(SourceExpr->getExprLoc(), "function %0 %1; '%2' should be used instead") << FuncDecl << getRationaleFor(FunctionName) - << ReplacementFunctionName.value() << DeclRef->getSourceRange(); + << ReplacementFunctionName.value() << SourceExpr->getSourceRange(); } void UnsafeFunctionsCheck::registerPPCallbacks( diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.h b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.h index 63058c326ef29..9b2ec990be01f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.h @@ -43,7 +43,7 @@ class UnsafeFunctionsCheck : public ClangTidyCheck { private: const std::vector CustomFunctions; - // If true, the default set of functions are reported. + /// If true, the default set of functions are reported. const bool ReportDefaultFunctions; /// If true, additional functions from widely used API-s (such as POSIX) are /// added to the list of reported functions. diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp index fc35bc22c52e0..c249244b1a1b2 100644 --- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp @@ -139,10 +139,8 @@ static bool areEquivalentExpr(const Expr *Left, const Expr *Right) { return cast(Left)->getOpcode() == cast(Right)->getOpcode(); case Stmt::UnaryExprOrTypeTraitExprClass: - const auto *LeftUnaryExpr = - cast(Left); - const auto *RightUnaryExpr = - cast(Right); + const auto *LeftUnaryExpr = cast(Left); + const auto *RightUnaryExpr = cast(Right); if (LeftUnaryExpr->isArgumentType() && RightUnaryExpr->isArgumentType()) return LeftUnaryExpr->getKind() == RightUnaryExpr->getKind() && LeftUnaryExpr->getArgumentType() == @@ -699,7 +697,8 @@ static bool retrieveRelationalIntegerConstantExpr( Symbol = OverloadedOperatorExpr->getArg(IntegerConstantIsFirstArg ? 1 : 0); OperandExpr = OverloadedOperatorExpr; - Opcode = BinaryOperator::getOverloadedOpcode(OverloadedOperatorExpr->getOperator()); + Opcode = BinaryOperator::getOverloadedOpcode( + OverloadedOperatorExpr->getOperator()); if (!retrieveIntegerConstantExpr(Result, Id, Value, ConstExpr)) return false; @@ -728,7 +727,8 @@ static bool retrieveRelationalIntegerConstantExpr( } // Checks for expressions like (X == 4) && (Y != 9) -static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, const ASTContext *AstCtx) { +static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, + const ASTContext *AstCtx) { const auto *LhsBinOp = dyn_cast(BinOp->getLHS()); const auto *RhsBinOp = dyn_cast(BinOp->getRHS()); @@ -747,6 +747,28 @@ static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, const A return false; } +static bool areSidesBinaryConstExpressionsOrDefinesOrIntegerConstant( + const BinaryOperator *&BinOp, const ASTContext *AstCtx) { + if (areSidesBinaryConstExpressions(BinOp, AstCtx)) + return true; + + const Expr *Lhs = BinOp->getLHS(); + const Expr *Rhs = BinOp->getRHS(); + + if (!Lhs || !Rhs) + return false; + + auto IsDefineExpr = [AstCtx](const Expr *E) { + const SourceRange Lsr = E->getSourceRange(); + if (!Lsr.getBegin().isMacroID() || E->isValueDependent() || + !E->isIntegerConstantExpr(*AstCtx)) + return false; + return true; + }; + + return IsDefineExpr(Lhs) || IsDefineExpr(Rhs); +} + // Retrieves integer constant subexpressions from binary operator expressions // that have two equivalent sides. // E.g.: from (X == 5) && (X == 5) retrieves 5 and 5. @@ -785,7 +807,7 @@ static bool retrieveConstExprFromBothSides(const BinaryOperator *&BinOp, } static bool isSameRawIdentifierToken(const Token &T1, const Token &T2, - const SourceManager &SM) { + const SourceManager &SM) { if (T1.getKind() != T2.getKind()) return false; if (T1.isNot(tok::raw_identifier)) @@ -808,8 +830,8 @@ static bool areExprsFromDifferentMacros(const Expr *LhsExpr, const ASTContext *AstCtx) { if (!LhsExpr || !RhsExpr) return false; - SourceRange Lsr = LhsExpr->getSourceRange(); - SourceRange Rsr = RhsExpr->getSourceRange(); + const SourceRange Lsr = LhsExpr->getSourceRange(); + const SourceRange Rsr = RhsExpr->getSourceRange(); if (!Lsr.getBegin().isMacroID() || !Rsr.getBegin().isMacroID()) return false; @@ -847,11 +869,83 @@ static bool areExprsMacroAndNonMacro(const Expr *&LhsExpr, if (!LhsExpr || !RhsExpr) return false; - SourceLocation LhsLoc = LhsExpr->getExprLoc(); - SourceLocation RhsLoc = RhsExpr->getExprLoc(); + const SourceLocation LhsLoc = LhsExpr->getExprLoc(); + const SourceLocation RhsLoc = RhsExpr->getExprLoc(); return LhsLoc.isMacroID() != RhsLoc.isMacroID(); } + +static bool areStringsSameIgnoreSpaces(const llvm::StringRef Left, + const llvm::StringRef Right) { + if (Left == Right) + return true; + + // Do running comparison ignoring spaces + llvm::StringRef L = Left.trim(); + llvm::StringRef R = Right.trim(); + while (!L.empty() && !R.empty()) { + L = L.ltrim(); + R = R.ltrim(); + if (L.empty() && R.empty()) + return true; + // If symbol compared are different ==> strings are not the same + if (L.front() != R.front()) + return false; + L = L.drop_front(); + R = R.drop_front(); + } + return L.empty() && R.empty(); +} + +static bool areExprsSameMacroOrLiteral(const BinaryOperator *BinOp, + const ASTContext *Context) { + + if (!BinOp) + return false; + + const Expr *Lhs = BinOp->getLHS(); + const Expr *Rhs = BinOp->getRHS(); + const SourceManager &SM = Context->getSourceManager(); + + const SourceRange Lsr = Lhs->getSourceRange(); + const SourceRange Rsr = Rhs->getSourceRange(); + if (Lsr.getBegin().isMacroID()) { + // Left is macro so right macro too + if (Rsr.getBegin().isMacroID()) { + // Both sides are macros so they are same macro or literal + const llvm::StringRef L = Lexer::getSourceText( + CharSourceRange::getTokenRange(Lsr), SM, Context->getLangOpts(), 0); + const llvm::StringRef R = Lexer::getSourceText( + CharSourceRange::getTokenRange(Rsr), SM, Context->getLangOpts(), 0); + return areStringsSameIgnoreSpaces(L, R); + } + // Left is macro but right is not so they are not same macro or literal + return false; + } + const auto *Lil = dyn_cast(Lhs); + const auto *Ril = dyn_cast(Rhs); + if (Lil && Ril) + return Lil->getValue() == Ril->getValue(); + + const auto *LStrl = dyn_cast(Lhs); + const auto *RStrl = dyn_cast(Rhs); + if (Lil && Ril) { + const llvm::StringRef L = Lexer::getSourceText( + CharSourceRange::getTokenRange(LStrl->getBeginLoc()), SM, + Context->getLangOpts(), 0); + const llvm::StringRef R = Lexer::getSourceText( + CharSourceRange::getTokenRange(RStrl->getBeginLoc()), SM, + Context->getLangOpts(), 0); + return L.compare(R) == 0; + } + + const auto *Lbl = dyn_cast(Lhs); + const auto *Rbl = dyn_cast(Rhs); + if (Lbl && Rbl) + return Lbl->getValue() == Rbl->getValue(); + + return false; +} } // namespace void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) { @@ -1089,7 +1183,6 @@ static bool exprEvaluatesToSymbolic(BinaryOperatorKind Opcode, APSInt Value) { ((Opcode == BO_And || Opcode == BO_AndAssign) && ~Value == 0); } - void RedundantExpressionCheck::checkBitwiseExpr( const MatchFinder::MatchResult &Result) { if (const auto *ComparisonOperator = Result.Nodes.getNodeAs( @@ -1134,8 +1227,8 @@ void RedundantExpressionCheck::checkBitwiseExpr( ConstExpr)) return; - if((Value != 0 && ~Value != 0) || Sym->getExprLoc().isMacroID()) - return; + if ((Value != 0 && ~Value != 0) || Sym->getExprLoc().isMacroID()) + return; SourceLocation Loc = IneffectiveOperator->getOperatorLoc(); @@ -1276,19 +1369,23 @@ void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) { return; } - if (areSidesBinaryConstExpressions(BinOp, Result.Context)) { + if (areSidesBinaryConstExpressionsOrDefinesOrIntegerConstant( + BinOp, Result.Context)) { const Expr *LhsConst = nullptr, *RhsConst = nullptr; BinaryOperatorKind MainOpcode{}, SideOpcode{}; - - if (!retrieveConstExprFromBothSides(BinOp, MainOpcode, SideOpcode, - LhsConst, RhsConst, Result.Context)) - return; - - if (areExprsFromDifferentMacros(LhsConst, RhsConst, Result.Context) || - areExprsMacroAndNonMacro(LhsConst, RhsConst)) - return; + if (areSidesBinaryConstExpressions(BinOp, Result.Context)) { + if (!retrieveConstExprFromBothSides(BinOp, MainOpcode, SideOpcode, + LhsConst, RhsConst, Result.Context)) + return; + + if (areExprsFromDifferentMacros(LhsConst, RhsConst, Result.Context) || + areExprsMacroAndNonMacro(LhsConst, RhsConst)) + return; + } else { + if (!areExprsSameMacroOrLiteral(BinOp, Result.Context)) + return; + } } - diag(BinOp->getOperatorLoc(), "both sides of operator are equivalent"); } diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp index a59d1e7ac8409..28bb994a9e99a 100644 --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -577,7 +577,17 @@ std::vector StoreDiags::take(const clang::tidy::ClangTidyContext *Tidy) { for (auto &Diag : Output) { if (const char *ClangDiag = getDiagnosticCode(Diag.ID)) { // Warnings controlled by -Wfoo are better recognized by that name. - StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(Diag.ID); + StringRef Warning = [&] { + if (OrigSrcMgr) { + return OrigSrcMgr->getDiagnostics() + .getDiagnosticIDs() + ->getWarningOptionForDiag(Diag.ID); + } + if (!DiagnosticIDs::IsCustomDiag(Diag.ID)) + return DiagnosticIDs{}.getWarningOptionForDiag(Diag.ID); + return StringRef{}; + }(); + if (!Warning.empty()) { Diag.Name = ("-W" + Warning).str(); } else { @@ -894,20 +904,23 @@ void StoreDiags::flushLastDiag() { Output.push_back(std::move(*LastDiag)); } -bool isBuiltinDiagnosticSuppressed(unsigned ID, - const llvm::StringSet<> &Suppress, - const LangOptions &LangOpts) { +bool isDiagnosticSuppressed(const clang::Diagnostic &Diag, + const llvm::StringSet<> &Suppress, + const LangOptions &LangOpts) { // Don't complain about header-only stuff in mainfiles if it's a header. // FIXME: would be cleaner to suppress in clang, once we decide whether the // behavior should be to silently-ignore or respect the pragma. - if (ID == diag::pp_pragma_sysheader_in_main_file && LangOpts.IsHeaderFile) + if (Diag.getID() == diag::pp_pragma_sysheader_in_main_file && + LangOpts.IsHeaderFile) return true; - if (const char *CodePtr = getDiagnosticCode(ID)) { + if (const char *CodePtr = getDiagnosticCode(Diag.getID())) { if (Suppress.contains(normalizeSuppressedCode(CodePtr))) return true; } - StringRef Warning = DiagnosticIDs::getWarningOptionForDiag(ID); + StringRef Warning = + Diag.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag( + Diag.getID()); if (!Warning.empty() && Suppress.contains(Warning)) return true; return false; diff --git a/clang-tools-extra/clangd/Diagnostics.h b/clang-tools-extra/clangd/Diagnostics.h index d4c0478c63a5c..c45d8dc3aa6ce 100644 --- a/clang-tools-extra/clangd/Diagnostics.h +++ b/clang-tools-extra/clangd/Diagnostics.h @@ -181,11 +181,11 @@ class StoreDiags : public DiagnosticConsumer { }; /// Determine whether a (non-clang-tidy) diagnostic is suppressed by config. -bool isBuiltinDiagnosticSuppressed(unsigned ID, - const llvm::StringSet<> &Suppressed, - const LangOptions &); +bool isDiagnosticSuppressed(const clang::Diagnostic &Diag, + const llvm::StringSet<> &Suppressed, + const LangOptions &); /// Take a user-specified diagnostic code, and convert it to a normalized form -/// stored in the config and consumed by isBuiltinDiagnosticsSuppressed. +/// stored in the config and consumed by isDiagnosticsSuppressed. /// /// (This strips err_ and -W prefix so we can match with or without them.) llvm::StringRef normalizeSuppressedCode(llvm::StringRef); diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 89d6f26d0f150..3f63daaf400db 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -342,7 +342,7 @@ void applyWarningOptions(llvm::ArrayRef ExtraArgs, if (Enable) { if (Diags.getDiagnosticLevel(ID, SourceLocation()) < DiagnosticsEngine::Warning) { - auto Group = DiagnosticIDs::getGroupForDiag(ID); + auto Group = Diags.getDiagnosticIDs()->getGroupForDiag(ID); if (!Group || !EnabledGroups(*Group)) continue; Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation()); @@ -585,8 +585,8 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs, ASTDiags.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) { if (Cfg.Diagnostics.SuppressAll || - isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress, - Clang->getLangOpts())) + isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress, + Clang->getLangOpts())) return DiagnosticsEngine::Ignored; auto It = OverriddenSeverity.find(Info.getID()); diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index ce88ec0eb88c1..b247e608eece3 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -622,8 +622,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI, PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) { if (Cfg.Diagnostics.SuppressAll || - isBuiltinDiagnosticSuppressed(Info.getID(), Cfg.Diagnostics.Suppress, - CI.getLangOpts())) + isDiagnosticSuppressed(Info, Cfg.Diagnostics.Suppress, + CI.getLangOpts())) return DiagnosticsEngine::Ignored; switch (Info.getID()) { case diag::warn_no_newline_eof: diff --git a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp index 179960a02cade..c3e484a1a79c4 100644 --- a/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp +++ b/clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp @@ -298,20 +298,41 @@ TEST_F(ConfigCompileTests, DiagnosticSuppression) { "unreachable-code", "unused-variable", "typecheck_bool_condition", "unexpected_friend", "warn_alloca")); - EXPECT_TRUE(isBuiltinDiagnosticSuppressed( - diag::warn_unreachable, Conf.Diagnostics.Suppress, LangOptions())); + clang::DiagnosticsEngine DiagEngine(new DiagnosticIDs, nullptr, + new clang::IgnoringDiagConsumer); + + using Diag = clang::Diagnostic; + { + auto D = DiagEngine.Report(diag::warn_unreachable); + EXPECT_TRUE(isDiagnosticSuppressed( + Diag{&DiagEngine, D}, Conf.Diagnostics.Suppress, LangOptions())); + } // Subcategory not respected/suppressed. - EXPECT_FALSE(isBuiltinDiagnosticSuppressed( - diag::warn_unreachable_break, Conf.Diagnostics.Suppress, LangOptions())); - EXPECT_TRUE(isBuiltinDiagnosticSuppressed( - diag::warn_unused_variable, Conf.Diagnostics.Suppress, LangOptions())); - EXPECT_TRUE(isBuiltinDiagnosticSuppressed(diag::err_typecheck_bool_condition, - Conf.Diagnostics.Suppress, - LangOptions())); - EXPECT_TRUE(isBuiltinDiagnosticSuppressed( - diag::err_unexpected_friend, Conf.Diagnostics.Suppress, LangOptions())); - EXPECT_TRUE(isBuiltinDiagnosticSuppressed( - diag::warn_alloca, Conf.Diagnostics.Suppress, LangOptions())); + { + auto D = DiagEngine.Report(diag::warn_unreachable_break); + EXPECT_FALSE(isDiagnosticSuppressed( + Diag{&DiagEngine, D}, Conf.Diagnostics.Suppress, LangOptions())); + } + { + auto D = DiagEngine.Report(diag::warn_unused_variable); + EXPECT_TRUE(isDiagnosticSuppressed( + Diag{&DiagEngine, D}, Conf.Diagnostics.Suppress, LangOptions())); + } + { + auto D = DiagEngine.Report(diag::err_typecheck_bool_condition); + EXPECT_TRUE(isDiagnosticSuppressed( + Diag{&DiagEngine, D}, Conf.Diagnostics.Suppress, LangOptions())); + } + { + auto D = DiagEngine.Report(diag::err_unexpected_friend); + EXPECT_TRUE(isDiagnosticSuppressed( + Diag{&DiagEngine, D}, Conf.Diagnostics.Suppress, LangOptions())); + } + { + auto D = DiagEngine.Report(diag::warn_alloca); + EXPECT_TRUE(isDiagnosticSuppressed( + Diag{&DiagEngine, D}, Conf.Diagnostics.Suppress, LangOptions())); + } Frag.Diagnostics.Suppress.emplace_back("*"); EXPECT_TRUE(compileAndApply()); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index cc5f64a3f9fa3..6b8fe22242417 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -43,21 +43,12 @@ infrastructure are described first, followed by tool-specific sections. Major New Features ------------------ -- The ``clang-pseudo`` tool is incomplete and does not have active maintainers, - so it has been removed. See - `the RFC `_ for - more details. - -... - Improvements to clangd ---------------------- Inlay hints ^^^^^^^^^^^ -- Added `DefaultArguments` Inlay Hints option. - Diagnostics ^^^^^^^^^^^ @@ -73,16 +64,9 @@ Hover Code completion ^^^^^^^^^^^^^^^ -- Added completion for C++20 keywords. - Code actions ^^^^^^^^^^^^ -- Added `Swap operands` tweak for certain binary operators. - -- Improved the extract-to-function code action to allow extracting statements - with overloaded operators like ``<<`` of ``std::ostream``. - Signature help ^^^^^^^^^^^^^^ @@ -95,312 +79,36 @@ Objective-C Miscellaneous ^^^^^^^^^^^^^ -- The DefineOutline tweak now handles member functions of class templates. - Improvements to clang-doc ------------------------- Improvements to clang-query --------------------------- -- Added `set enable-profile true/false` command for basic matcher profiling. - Improvements to clang-tidy -------------------------- -- Improved :program:`clang-tidy-diff.py` script. Add the `-only-check-in-db` - option to exclude files not present in the compilation database, avoiding - false-negative results. - -- Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise - happening on certain platforms when interrupting the script. - -- Improved :program:`clang-tidy`: - - - add support for `--verify-config` flag to check the configuration options of - the `Clang Static Analyzer Checks `_. - - accept parameters file in command line. - - fix incorrect configuration file path resolving when file paths contain ``..``. - - remove global options for most of checks. All options are changed to local - options except `IncludeStyle`, `StrictMode` and `IgnoreMacros`. Global scoped - `StrictMode` and `IgnoreMacros` are deprecated and will be removed in further - releases. - -.. csv-table:: - :header: "Check", "Options removed from global option" - - :doc:`bugprone-reserved-identifier `, AggressiveDependentMemberLookup - :doc:`bugprone-unchecked-optional-access `, IgnoreSmartPointerDereference - :doc:`cppcoreguidelines-pro-type-member-init `, UseAssignment - :doc:`cppcoreguidelines-rvalue-reference-param-not-moved `, AllowPartialMove; IgnoreUnnamedParams; IgnoreNonDeducedTemplateTypes - :doc:`misc-include-cleaner `, IgnoreHeaders; DeduplicateFindings - :doc:`performance-inefficient-vector-operation `, EnableProto - :doc:`readability-identifier-naming `, AggressiveDependentMemberLookup - :doc:`readability-inconsistent-declaration-parameter-name `, Strict - :doc:`readability-redundant-access-specifiers `, CheckFirstDeclaration - :doc:`readability-redundant-casting `, IgnoreTypeAliases - New checks ^^^^^^^^^^ -- New :doc:`bugprone-bitwise-pointer-cast - ` check. - - Warns about code that tries to cast between pointers by means of - ``std::bit_cast`` or ``memcpy``. - -- New :doc:`bugprone-incorrect-enable-shared-from-this - ` check. - - Detect classes or structs that do not publicly inherit from - ``std::enable_shared_from_this``, because unintended behavior will - otherwise occur when calling ``shared_from_this``. - -- New :doc:`bugprone-nondeterministic-pointer-iteration-order - ` - check. - - Finds nondeterministic usages of pointers in unordered containers. - -- New :doc:`bugprone-tagged-union-member-count - ` check. - - Gives warnings for tagged unions, where the number of tags is - different from the number of data members inside the union. - -- New :doc:`modernize-use-integer-sign-comparison - ` check. - - Replace comparisons between signed and unsigned integers with their safe - C++20 ``std::cmp_*`` alternative, if available. - -- New :doc:`portability-template-virtual-member-function - ` check. - - Finds cases when an uninstantiated virtual member function in a template class - causes cross-compiler incompatibility. - New check aliases ^^^^^^^^^^^^^^^^^ -- New alias :doc:`cert-arr39-c ` to - :doc:`bugprone-sizeof-expression - ` was added. - Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Improved :doc:`altera-id-dependent-backward-branch - ` check by fixing - crashes from invalid code. - -- Improved :doc:`bugprone-branch-clone - ` check to improve detection of - branch clones by now detecting duplicate inner and outer if statements. - -- Improved :doc:`bugprone-casting-through-void - ` check to suggest replacing - the offending code with ``reinterpret_cast``, to more clearly express intent. - -- Improved :doc:`bugprone-dangling-handle - ` check to treat ``std::span`` as a - handle class. - -- Improved :doc:`bugprone-exception-escape - ` by fixing false positives - when a consteval function with throw statements. - -- Improved :doc:`bugprone-forwarding-reference-overload - ` check by fixing - a crash when determining if an ``enable_if[_t]`` was found. - -- Improve :doc:`bugprone-narrowing-conversions - ` to avoid incorrect check - results when floating point type is not ``float``, ``double`` and - ``long double``. - -- Improved :doc:`bugprone-optional-value-conversion - ` to support detecting - conversion directly by ``std::make_unique`` and ``std::make_shared``. - -- Improved :doc:`bugprone-posix-return - ` check to support integer literals - as LHS and posix call as RHS of comparison. - -- Improved :doc:`bugprone-return-const-ref-from-parameter - ` check to - diagnose potential dangling references when returning a ``const &`` parameter - by using the conditional operator ``cond ? var1 : var2`` and fixing false - positives for functions which contain lambda and ignore parameters - with ``[[clang::lifetimebound]]`` attribute. - -- Improved :doc:`bugprone-sizeof-expression - ` check to find suspicious - usages of ``sizeof()``, ``alignof()``, and ``offsetof()`` when adding or - subtracting from a pointer directly or when used to scale a numeric value and - fix false positive when sizeof expression with template types. - -- Improved :doc:`bugprone-throw-keyword-missing - ` by fixing a false positive - when using non-static member initializers and a constructor. - -- Improved :doc:`bugprone-unchecked-optional-access - ` to support - ``bsl::optional`` and ``bdlb::NullableValue`` from - _. - -- Improved :doc:`bugprone-unhandled-self-assignment - ` check by fixing smart - pointer check against std::unique_ptr type. +- Improved :doc:`bugprone-string-constructor + ` check to find suspicious + calls of ``std::string`` constructor with char pointer, start position and + length parameters. - Improved :doc:`bugprone-unsafe-functions ` check to allow specifying - additional functions to match. - -- Improved :doc:`bugprone-unused-local-non-trivial-variable - ` check to avoid - false positives when using name-independent variables after C++26. - -- Improved :doc:`bugprone-use-after-move - ` to avoid triggering on - ``reset()`` calls on moved-from ``std::optional`` and ``std::any`` objects, - similarly to smart pointers. - -- Improved :doc:`cert-flp30-c ` check to - fix false positive that floating point variable is only used in increment - expression. - -- Improved :doc:`cppcoreguidelines-avoid-const-or-ref-data-members - ` check to - avoid false positives when detecting a templated class with inheritance. - -- Improved :doc:`cppcoreguidelines-init-variables - ` check by fixing the - insertion location for function pointers. - -- Improved :doc:`cppcoreguidelines-prefer-member-initializer - ` check to - avoid false positive when member initialization depends on a structured - binding variable. - -- Fixed :doc:`cppcoreguidelines-pro-type-union-access - ` check to - report a location even when the member location is not valid. - -- Improved :doc:`misc-definitions-in-headers - ` check by rewording the - diagnostic note that suggests adding ``inline``. + additional C++ member functions to match. - Improved :doc:`misc-redundant-expression - ` check by extending the - checker to detect floating point and integer literals in redundant - expressions. - -- Improved :doc:`misc-unconventional-assign-operator - ` check to avoid - false positive for C++23 deducing this. - -- Improved :doc:`misc-use-internal-linkage - ` check to insert ``static`` - keyword before type qualifiers such as ``const`` and ``volatile``. Also, fix - false positives for function declaration without body, C++20 consteval - functions, C++20 export declarations, and global scoped - overloaded ``operator new`` and ``operator delete``. - -- Improved :doc:`modernize-avoid-c-arrays - ` check to suggest using - ``std::span`` as a replacement for parameters of incomplete C array type in - C++20 and ``std::array`` or ``std::vector`` before C++20. - -- Improved :doc:`modernize-loop-convert - ` check to fix false positive when - using loop variable in initializer of lambda capture. - -- Improved :doc:`modernize-min-max-use-initializer-list - ` check by fixing - a false positive when only an implicit conversion happened inside an - initializer list. - -- Improved :doc:`modernize-raw-string-literal - ` check to fix incorrect - fix-it when the string contains a user-defined suffix. - -- Improved :doc:`modernize-use-designated-initializers - ` check to fix a - crash when a class is declared but not defined. - -- Improved :doc:`modernize-use-integer-sign-comparison - ` check to - add an option ``EnableQtSupport``, that makes C++17 ``q20::cmp_*`` alternative - available for Qt-based applications. - -- Improved :doc:`modernize-use-nullptr - ` check to also recognize - ``NULL``/``__null`` (but not ``0``) when used with a templated type. - -- Improved :doc:`modernize-use-starts-ends-with - ` check to handle two new - cases from ``rfind`` and ``compare`` to ``ends_with``, and one new case from - ``substr`` to ``starts_with``, and a small adjustment to the diagnostic message. - -- Improved :doc:`modernize-use-std-format - ` check to support replacing - member function calls too and to only expand macros starting with ``PRI`` - and ``__PRI`` from ```` in the format string. - -- Improved :doc:`modernize-use-std-print - ` check to support replacing - member function calls too and to only expand macros starting with ``PRI`` - and ``__PRI`` from ```` in the format string. - -- Improved :doc:`modernize-use-using - ` check by not expanding macros. - -- Improved :doc:`performance-avoid-endl - ` check to use ``std::endl`` as - placeholder when lexer cannot get source text. - -- Improved :doc:`performance-move-const-arg - ` check to fix a crash when - an argument type is declared but not defined. - -- Improved :doc:`performance-unnecessary-copy-initialization - ` check - to consider static member functions the same way as free functions. - -- Improved :doc:`readability-container-contains - ` check to let it work on - any class that has a ``contains`` method. Fix some false negatives in the - ``find()`` case. - -- Improved :doc:`readability-enum-initial-value - ` check by only issuing - diagnostics for the definition of an ``enum``, by not emitting a redundant - file path for anonymous enums in the diagnostic, and by fixing a typo in the - diagnostic. - -- Improved :doc:`readability-identifier-naming - ` check to - validate ``namespace`` aliases. - -- Improved :doc:`readability-implicit-bool-conversion - ` check - by adding the option `UseUpperCaseLiteralSuffix` to select the - case of the literal suffix in fixes and fixing false positive for implicit - conversion of comparison result in C23. - -- Improved :doc:`readability-redundant-casting - ` check - by addressing a false positive in aggregate initialization through - parenthesized list. - -- Improved :doc:`readability-redundant-smartptr-get - ` check to - remove ``->``, when redundant ``get()`` is removed. - -- Improved :doc:`readability-use-std-min-max - ` check to use correct template - type in ``std::min`` and ``std::max`` when operand is integer literal. + ` check by providing additional + examples and fixing some macro related false positives. Removed checks ^^^^^^^^^^^^^^ @@ -408,13 +116,6 @@ Removed checks Miscellaneous ^^^^^^^^^^^^^ -- The :doc:`bugprone-narrowing-conversions ` - check is no longer an alias of :doc:`cppcoreguidelines-narrowing-conversions - `. Instead, - :doc:`cppcoreguidelines-narrowing-conversions - ` is now an alias - of :doc:`bugprone-narrowing-conversions `. - Improvements to include-fixer ----------------------------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/assert-side-effect.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/assert-side-effect.rst index 8ba84ff61c6a9..1355afae92e4f 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/assert-side-effect.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/assert-side-effect.rst @@ -26,8 +26,8 @@ Options A semicolon-separated list of the names of functions or methods to be considered as not having side-effects. Regular expressions are accepted, - e.g. `[Rr]ef(erence)?$` matches every type with suffix `Ref`, `ref`, - `Reference` and `reference`. The default is empty. If a name in the list - contains the sequence `::` it is matched against the qualified typename - (i.e. `namespace::Type`, otherwise it is matched against only - the type name (i.e. `Type`). + e.g. ``[Rr]ef(erence)?$`` matches every type with suffix ``Ref``, ``ref``, + ``Reference`` and ``reference``. The default is empty. If a name in the list + contains the sequence `::` it is matched against the qualified type name + (i.e. ``namespace::Type``), otherwise it is matched against only + the type name (i.e. ``Type``). diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst index b45c2ef4a9312..a0bd1d7c5bc15 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/string-constructor.rst @@ -21,6 +21,7 @@ Examples: .. code-block:: c++ std::string("test", 200); // Will include random characters after "test". + std::string("test", 2, 5); // Will include random characters after "st". std::string_view("test", 200); Creating an empty string from constructors with parameters is considered @@ -31,8 +32,19 @@ Examples: .. code-block:: c++ std::string("test", 0); // Creation of an empty string. + std::string("test", 1, 0); std::string_view("test", 0); +Passing an invalid first character position parameter to constructor will +cause ``std::out_of_range`` exception at runtime. + +Examples: + +.. code-block:: c++ + + std::string("test", -1, 10); // Negative first character position. + std::string("test", 10, 10); // First character position is bigger than string literal character range". + Options ------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst index fb070627e31b1..317db9c5564e2 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unsafe-functions.rst @@ -114,6 +114,17 @@ qualified name (i.e. ``std::original``), otherwise the regex is matched against If the regular expression starts with `::` (or `^::`), it is matched against the fully qualified name (``::std::original``). +.. note:: + + Fully qualified names can contain template parameters on certain C++ classes, but not on C++ functions. + Type aliases are resolved before matching. + + As an example, the member function ``open`` in the class ``std::ifstream`` + has a fully qualified name of ``::std::basic_ifstream::open``. + + The example could also be matched with the regex ``::std::basic_ifstream<[^>]*>::open``, which matches all potential + template parameters, but does not match nested template classes. + Options ------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/redundant-expression.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/redundant-expression.rst index 44f0772d0bedf..cea998d39bd73 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/redundant-expression.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/redundant-expression.rst @@ -19,12 +19,14 @@ Examples: .. code-block:: c++ - ((x+1) | (x+1)) // (x+1) is redundant - (p->x == p->x) // always true - (p->x < p->x) // always false - (speed - speed + 1 == 12) // speed - speed is always zero - int b = a | 4 | a // identical expr on both sides - ((x=1) | (x=1)) // expression is identical + ((x+1) | (x+1)) // (x+1) is redundant + (p->x == p->x) // always true + (p->x < p->x) // always false + (speed - speed + 1 == 12) // speed - speed is always zero + int b = a | 4 | a // identical expr on both sides + ((x=1) | (x=1)) // expression is identical + (DEFINE_1 | DEFINE_1) // same macro on the both sides + ((DEF_1 + DEF_2) | (DEF_1+DEF_2)) // expressions differ in spaces only Floats are handled except in the case that NaNs are checked like so: diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst index 01fde9580e2a0..d740984029482 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance/for-range-copy.rst @@ -23,14 +23,15 @@ Options .. option:: WarnOnAllAutoCopies - When `true`, warns on any use of `auto` as the type of the range-based for + When `true`, warns on any use of ``auto`` as the type of the range-based for loop variable. Default is `false`. .. option:: AllowedTypes A semicolon-separated list of names of types allowed to be copied in each - iteration. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches - every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default - is empty. If a name in the list contains the sequence `::` it is matched - against the qualified typename (i.e. `namespace::Type`, otherwise it is - matched against only the type name (i.e. `Type`). + iteration. Regular expressions are accepted, e.g. ``[Rr]ef(erence)?$`` + matches every type with suffix ``Ref``, ``ref``, ``Reference`` and + ``reference``. The default is empty. If a name in the list contains the + sequence `::`, it is matched against the qualified type name + (i.e. ``namespace::Type``), otherwise it is matched against only the + type name (i.e. ``Type``). diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst index 837283811ddcc..bb4f42c88d62f 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-copy-initialization.rst @@ -42,11 +42,11 @@ Options .. option:: AllowedTypes A semicolon-separated list of names of types allowed to be initialized by - copying. Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches - every type with suffix `Ref`, `ref`, `Reference` and `reference`. The default - is empty. If a name in the list contains the sequence `::` it is matched - against the qualified typename (i.e. `namespace::Type`, otherwise it is - matched against only the type name (i.e. `Type`). + copying. Regular expressions are accepted, e.g. ``[Rr]ef(erence)?$`` matches + every type with suffix ``Ref``, ``ref``, ``Reference`` and ``reference``. + The default is empty. If a name in the list contains the sequence `::`, it + is matched against the qualified type name (i.e. ``namespace::Type``), + otherwise it is matched against only the type name (i.e. ``Type``). .. option:: ExcludedContainerTypes diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst index cc5e1ae73508c..d13c53eea994e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance/unnecessary-value-param.rst @@ -65,8 +65,8 @@ Options .. option:: AllowedTypes A semicolon-separated list of names of types allowed to be passed by value. - Regular expressions are accepted, e.g. `[Rr]ef(erence)?$` matches every type - with suffix `Ref`, `ref`, `Reference` and `reference`. The default is - empty. If a name in the list contains the sequence `::` it is matched against - the qualified typename (i.e. `namespace::Type`, otherwise it is matched - against only the type name (i.e. `Type`). + Regular expressions are accepted, e.g. ``[Rr]ef(erence)?$`` matches every + type with suffix ``Ref``, ``ref``, ``Reference`` and ``reference``. The + default is empty. If a name in the list contains the sequence `::`, it is + matched against the qualified type name (i.e. ``namespace::Type``), + otherwise it is matched against only the type name (i.e. ``Type``). diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index aae3eda519ffd..7a140c991925c 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -22,6 +22,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/STLExtras.h" @@ -32,6 +33,11 @@ namespace clang::include_cleaner { namespace { +bool isOperatorNewDelete(OverloadedOperatorKind OpKind) { + return OpKind == OO_New || OpKind == OO_Delete || OpKind == OO_Array_New || + OpKind == OO_Array_Delete; +} + using DeclCallback = llvm::function_ref; @@ -158,7 +164,15 @@ class ASTWalker : public RecursiveASTVisitor { // the container decl instead, which is preferred as it'll handle // aliases/exports properly. if (!FD->isCXXClassMember() && !llvm::isa(FD)) { - report(DRE->getLocation(), FD); + // Global operator new/delete [] is available implicitly in every + // translation unit, even without including any explicit headers. So treat + // those as ambigious to not force inclusion in TUs that transitively + // depend on those. + RefType RT = + isOperatorNewDelete(FD->getDeclName().getCXXOverloadedOperator()) + ? RefType::Ambiguous + : RefType::Explicit; + report(DRE->getLocation(), FD, RT); return true; } // If the ref is without a qualifier, and is a member, ignore it. As it is diff --git a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp index d2d137a0dfb42..74321c312cb71 100644 --- a/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp +++ b/clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp @@ -397,6 +397,55 @@ TEST_F(AnalyzeTest, SpellingIncludesWithSymlinks) { } } +// Make sure that the references to implicit operator new/delete are reported as +// ambigious. +TEST_F(AnalyzeTest, ImplicitOperatorNewDeleteNotMissing) { + ExtraFS = llvm::makeIntrusiveRefCnt(); + ExtraFS->addFile("header.h", + /*ModificationTime=*/{}, + llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp( + void* operator new(decltype(sizeof(int))); + )cpp"))); + ExtraFS->addFile("wrapper.h", + /*ModificationTime=*/{}, + llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp( + #include "header.h" + )cpp"))); + + Inputs.Code = R"cpp( + #include "wrapper.h" + void bar() { + operator new(3); + })cpp"; + TestAST AST(Inputs); + std::vector DeclsInTU; + for (auto *D : AST.context().getTranslationUnitDecl()->decls()) + DeclsInTU.push_back(D); + auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor()); + EXPECT_THAT(Results.Missing, testing::IsEmpty()); +} + +TEST_F(AnalyzeTest, ImplicitOperatorNewDeleteNotUnused) { + ExtraFS = llvm::makeIntrusiveRefCnt(); + ExtraFS->addFile("header.h", + /*ModificationTime=*/{}, + llvm::MemoryBuffer::getMemBufferCopy(guard(R"cpp( + void* operator new(decltype(sizeof(int))); + )cpp"))); + + Inputs.Code = R"cpp( + #include "header.h" + void bar() { + operator new(3); + })cpp"; + TestAST AST(Inputs); + std::vector DeclsInTU; + for (auto *D : AST.context().getTranslationUnitDecl()->decls()) + DeclsInTU.push_back(D); + auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor()); + EXPECT_THAT(Results.Unused, testing::IsEmpty()); +} + TEST(FixIncludes, Basic) { llvm::StringRef Code = R"cpp(#include "d.h" #include "a.h" diff --git a/clang-tools-extra/test/clang-doc/Inputs/basic-project/src/Circle.cpp b/clang-tools-extra/test/clang-doc/Inputs/basic-project/src/Circle.cpp index 823384a4d97e8..3ddb2fd9ff563 100644 --- a/clang-tools-extra/test/clang-doc/Inputs/basic-project/src/Circle.cpp +++ b/clang-tools-extra/test/clang-doc/Inputs/basic-project/src/Circle.cpp @@ -8,4 +8,5 @@ double Circle::area() const { double Circle::perimeter() const { return 3.141 * radius_; -} \ No newline at end of file +} + diff --git a/clang-tools-extra/test/clang-doc/basic-project.test b/clang-tools-extra/test/clang-doc/basic-project.test index 7c46c52bae687..1f5ba8bdc0703 100644 --- a/clang-tools-extra/test/clang-doc/basic-project.test +++ b/clang-tools-extra/test/clang-doc/basic-project.test @@ -1,6 +1,6 @@ // RUN: rm -rf %t && mkdir -p %t/docs %t/build // RUN: sed 's|$test_dir|%/S|g' %S/Inputs/basic-project/database_template.json > %t/build/compile_commands.json -// RUN: clang-doc --format=html --output=%t/docs --executor=all-TUs %t/build/compile_commands.json +// RUN: clang-doc --format=html --output=%t/docs --executor=all-TUs %t/build/compile_commands.json --repository=https://repository.com // RUN: FileCheck %s -input-file=%t/docs/index_json.js -check-prefix=JSON-INDEX // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Shape.html -check-prefix=HTML-SHAPE // RUN: FileCheck %s -input-file=%t/docs/GlobalNamespace/Calculator.html -check-prefix=HTML-CALC @@ -54,130 +54,183 @@ // JSON-INDEX-NEXT: }; // JSON-INDEX-NEXT: } -// HTML-SHAPE:

class Shape

-// HTML-SHAPE:

Defined at line 8 of file {{.*}}Shape.h

-// HTML-SHAPE:
brief
-// HTML-SHAPE:

Abstract base class for shapes.

-// HTML-SHAPE:

Provides a common interface for different types of shapes.

-// HTML-SHAPE:

Functions

-// HTML-SHAPE:

area

-// HTML-SHAPE:

public double area()

-// HTML-SHAPE:
brief
-// HTML-SHAPE:

Calculates the area of the shape.

-// HTML-SHAPE:

perimeter

-// HTML-SHAPE:

public double perimeter()

-// HTML-SHAPE:
brief
-// HTML-SHAPE:

Calculates the perimeter of the shape.

-// HTML-SHAPE:
return
-// HTML-SHAPE:

double The perimeter of the shape.

-// HTML-SHAPE:

~Shape

-// HTML-SHAPE:

public void ~Shape()

-// HTML-SHAPE:

Defined at line 13 of file {{.*}}Shape.h

-// HTML-SHAPE:
brief
-// HTML-SHAPE:

Virtual destructor.

+// HTML-SHAPE:

class Shape

+// HTML-SHAPE-NEXT:

+// HTML-SHAPE-NEXT: Defined at line +// HTML-SHAPE-NEXT: 8 +// HTML-SHAPE-NEXT: of file +// HTML-SHAPE-NEXT: Shape.h +// HTML-SHAPE-NEXT:

+// HTML-SHAPE:
brief
+// HTML-SHAPE:

Abstract base class for shapes.

+// HTML-SHAPE:

Provides a common interface for different types of shapes.

+// HTML-SHAPE:

Functions

+// HTML-SHAPE:

area

+// HTML-SHAPE:

public double area()

+// HTML-SHAPE:
brief
+// HTML-SHAPE:

Calculates the area of the shape.

+// HTML-SHAPE:

perimeter

+// HTML-SHAPE:

public double perimeter()

+// HTML-SHAPE:
brief
+// HTML-SHAPE:

Calculates the perimeter of the shape.

+// HTML-SHAPE:
return
+// HTML-SHAPE:

double The perimeter of the shape.

+// HTML-SHAPE:

~Shape

+// HTML-SHAPE:

public void ~Shape()

+// HTML-SHAPE: Defined at line +// HTML-SHAPE-NEXT: 13 +// HTML-SHAPE-NEXT: of file +// HTML-SHAPE-NEXT: Shape.h +// HTML-SHAPE:
brief
+// HTML-SHAPE:

Virtual destructor.

-// HTML-CALC:

class Calculator

-// HTML-CALC:

Defined at line 8 of file {{.*}}Calculator.h

-// HTML-CALC:
brief
-// HTML-CALC:

A simple calculator class.

-// HTML-CALC:

Provides basic arithmetic operations.

-// HTML-CALC:

Functions

-// HTML-CALC:

add

-// HTML-CALC:

public int add(int a, int b)

-// HTML-CALC:

Defined at line 3 of file {{.*}}Calculator.cpp

-// HTML-CALC:
brief
-// HTML-CALC:

Adds two integers.

-// HTML-CALC:
return
-// HTML-CALC:

int The sum of a and b.

-// HTML-CALC:

subtract

-// HTML-CALC:

public int subtract(int a, int b)

-// HTML-CALC:

Defined at line 7 of file {{.*}}Calculator.cpp

-// HTML-CALC:
brief
-// HTML-CALC:

Subtracts the second integer from the first.

-// HTML-CALC:
return
-// HTML-CALC:

int The result of a - b.

-// HTML-CALC:

multiply

-// HTML-CALC:

public int multiply(int a, int b)

-// HTML-CALC:

Defined at line 11 of file {{.*}}Calculator.cpp

-// HTML-CALC:
brief
-// HTML-CALC:

Multiplies two integers.

-// HTML-CALC:
return
-// HTML-CALC:

int The product of a and b.

-// HTML-CALC:

divide

-// HTML-CALC:

public double divide(int a, int b)

-// HTML-CALC:

Defined at line 15 of file {{.*}}Calculator.cpp

-// HTML-CALC:
brief
-// HTML-CALC:

Divides the first integer by the second.

-// HTML-CALC:
return
-// HTML-CALC:

double The result of a / b.

-// HTML-CALC:
throw
-// HTML-CALC:

if b is zero.

+// HTML-CALC:

class Calculator

+// HTML-CALC-NEXT:

+// HTML-CALC-NEXT: Defined at line +// HTML-CALC-NEXT: 8 +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: Calculator.h +// HTML-CALC-NEXT:

+// HTML-CALC:
brief
+// HTML-CALC:

A simple calculator class.

+// HTML-CALC:

Provides basic arithmetic operations.

+// HTML-CALC:

Functions

+// HTML-CALC:

add

+// HTML-CALC:

public int add(int a, int b)

+// HTML-CALC: Defined at line +// HTML-CALC-NEXT: 3 +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: Calculator.cpp +// HTML-CALC:
brief
+// HTML-CALC:

Adds two integers.

+// HTML-CALC:
return
+// HTML-CALC:

int The sum of a and b.

+// HTML-CALC:

subtract

+// HTML-CALC:

public int subtract(int a, int b)

+// HTML-CALC: Defined at line +// HTML-CALC-NEXT: 7 +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: Calculator.cpp +// HTML-CALC:
brief
+// HTML-CALC:

Subtracts the second integer from the first.

+// HTML-CALC:
return
+// HTML-CALC:

int The result of a - b.

+// HTML-CALC:

multiply

+// HTML-CALC:

public int multiply(int a, int b)

+// HTML-CALC: Defined at line +// HTML-CALC-NEXT: 11 +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: Calculator.cpp +// HTML-CALC:
brief
+// HTML-CALC:

Multiplies two integers.

+// HTML-CALC:
return
+// HTML-CALC:

int The product of a and b.

+// HTML-CALC:

divide

+// HTML-CALC:

public double divide(int a, int b)

+// HTML-CALC: Defined at line +// HTML-CALC-NEXT: 15 +// HTML-CALC-NEXT: of file +// HTML-CALC-NEXT: Calculator.cpp +// HTML-CALC:
brief
+// HTML-CALC:

Divides the first integer by the second.

+// HTML-CALC:
return
+// HTML-CALC:

double The result of a / b.

+// HTML-CALC:
throw
+// HTML-CALC:

if b is zero.

-// HTML-RECTANGLE:

class Rectangle

-// HTML-RECTANGLE:

Defined at line 10 of file {{.*}}Rectangle.h

-// HTML-RECTANGLE:

Represents a rectangle with a given width and height.

-// HTML-RECTANGLE: Inherits from -// HTML-RECTANGLE: Shape -// HTML-RECTANGLE:

-// HTML-RECTANGLE:

Members

-// HTML-RECTANGLE:

Width of the rectangle.

-// HTML-RECTANGLE:
private double width_
-// HTML-RECTANGLE:

Height of the rectangle.

-// HTML-RECTANGLE:
private double height_
-// HTML-RECTANGLE:

Functions

-// HTML-RECTANGLE:

Rectangle

-// HTML-RECTANGLE:

public void Rectangle(double width, double height)

-// HTML-RECTANGLE:

Defined at line 3 of file {{.*}}Rectangle.cpp

-// HTML-RECTANGLE:
brief
-// HTML-RECTANGLE:

Constructs a new Rectangle object.

-// HTML-RECTANGLE:

area

-// HTML-RECTANGLE:

public double area()

-// HTML-RECTANGLE:

Defined at line 6 of file {{.*}}Rectangle.cpp

-// HTML-RECTANGLE:
brief
-// HTML-RECTANGLE:

Calculates the area of the rectangle.

-// HTML-RECTANGLE:
return
-// HTML-RECTANGLE:

double The area of the rectangle.

-// HTML-RECTANGLE:

perimeter

-// HTML-RECTANGLE:

public double perimeter()

-// HTML-RECTANGLE:

Defined at line 10 of file {{.*}}Rectangle.cpp

-// HTML-RECTANGLE:
brief
-// HTML-RECTANGLE:

Calculates the perimeter of the rectangle.

-// HTML-RECTANGLE:
return
-// HTML-RECTANGLE:

double The perimeter of the rectangle.

+// HTML-RECTANGLE:

class Rectangle

+// HTML-RECTANGLE-NEXT:

+// HTML-RECTANGLE-NEXT: Defined at line +// HTML-RECTANGLE-NEXT: 10 +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: Rectangle.h +// HTML-RECTANGLE-NEXT:

+// HTML-RECTANGLE:

Represents a rectangle with a given width and height.

+// HTML-RECTANGLE:

+// HTML-RECTANGLE: Inherits from +// HTML-RECTANGLE: Shape +// HTML-RECTANGLE:

+// HTML-RECTANGLE:

Members

+// HTML-RECTANGLE:

Width of the rectangle.

+// HTML-RECTANGLE:
private double width_
+// HTML-RECTANGLE:

Height of the rectangle.

+// HTML-RECTANGLE:
private double height_
+// HTML-RECTANGLE:

Functions

+// HTML-RECTANGLE:

Rectangle

+// HTML-RECTANGLE:

public void Rectangle(double width, double height)

+// HTML-RECTANGLE: Defined at line +// HTML-RECTANGLE-NEXT: 3 +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: Rectangle.cpp +// HTML-RECTANGLE:
brief
+// HTML-RECTANGLE:

Constructs a new Rectangle object.

+// HTML-RECTANGLE:

area

+// HTML-RECTANGLE:

public double area()

+// HTML-RECTANGLE: Defined at line +// HTML-RECTANGLE-NEXT: 6 +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: Rectangle.cpp +// HTML-RECTANGLE:
brief
+// HTML-RECTANGLE:

Calculates the area of the rectangle.

+// HTML-RECTANGLE:
return
+// HTML-RECTANGLE:

double The area of the rectangle.

+// HTML-RECTANGLE:

perimeter

+// HTML-RECTANGLE:

public double perimeter()

+// HTML-RECTANGLE: Defined at line +// HTML-RECTANGLE-NEXT: 10 +// HTML-RECTANGLE-NEXT: of file +// HTML-RECTANGLE-NEXT: Rectangle.cpp +// HTML-RECTANGLE:
brief
+// HTML-RECTANGLE:

Calculates the perimeter of the rectangle.

+// HTML-RECTANGLE:
return
+// HTML-RECTANGLE:

double The perimeter of the rectangle.

-// HTML-CIRCLE:

class Circle

-// HTML-CIRCLE:

Defined at line 10 of file {{.*}}Circle.h

-// HTML-CIRCLE:
brief
-// HTML-CIRCLE:

Circle class derived from Shape.

-// HTML-CIRCLE:

Represents a circle with a given radius.

-// HTML-CIRCLE:

-// HTML-CIRCLE: Inherits from -// HTML-CIRCLE: Shape -// HTML-CIRCLE:

-// HTML-CIRCLE:

Members

-// HTML-CIRCLE:

Radius of the circle.

-// HTML-CIRCLE:
private double radius_
-// HTML-CIRCLE:

Functions

-// HTML-CIRCLE:

Circle

-// HTML-CIRCLE:

public void Circle(double radius)

-// HTML-CIRCLE:

Defined at line 3 of file {{.*}}Circle.cpp

-// HTML-CIRCLE:
brief
-// HTML-CIRCLE:

Constructs a new Circle object.

-// HTML-CIRCLE:

area

-// HTML-CIRCLE:

public double area()

-// HTML-CIRCLE:

Defined at line 5 of file {{.*}}Circle.cpp

-// HTML-CIRCLE:
brief
-// HTML-CIRCLE:

Calculates the area of the circle.

-// HTML-CIRCLE:
return
-// HTML-CIRCLE:

double The area of the circle.

-// HTML-CIRCLE:

perimeter

-// HTML-CIRCLE:

public double perimeter()

-// HTML-CIRCLE:

Defined at line 9 of file {{.*}}Circle.cpp

-// HTML-CIRCLE:
brief
-// HTML-CIRCLE:

Calculates the perimeter of the circle.

-// HTML-CIRCLE:
return
-// HTML-CIRCLE:

double The perimeter of the circle.

+// HTML-CIRCLE:

class Circle

+// HTML-CIRCLE-NEXT:

+// HTML-CIRCLE-NEXT: Defined at line +// HTML-CIRCLE-NEXT: 10 +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: Circle.h +// HTML-CIRCLE-NEXT:

+// HTML-CIRCLE:
brief
+// HTML-CIRCLE:

Circle class derived from Shape.

+// HTML-CIRCLE:

Represents a circle with a given radius.

+// HTML-CIRCLE:

+// HTML-CIRCLE: Inherits from +// HTML-CIRCLE: Shape +// HTML-CIRCLE:

+// HTML-CIRCLE:

Members

+// HTML-CIRCLE:

Radius of the circle.

+// HTML-CIRCLE:
private double radius_
+// HTML-CIRCLE:

Functions

+// HTML-CIRCLE:

Circle

+// HTML-CIRCLE:

public void Circle(double radius)

+// HTML-CIRCLE: Defined at line +// HTML-CIRCLE-NEXT: 3 +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: Circle.cpp +// HTML-CIRCLE:
brief
+// HTML-CIRCLE:

Constructs a new Circle object.

+// HTML-CIRCLE:

area

+// HTML-CIRCLE:

public double area()

+// HTML-CIRCLE: Defined at line +// HTML-CIRCLE-NEXT: 5 +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: Circle.cpp +// HTML-CIRCLE:
brief
+// HTML-CIRCLE:

Calculates the area of the circle.

+// HTML-CIRCLE:
return
+// HTML-CIRCLE:

double The area of the circle.

+// HTML-CIRCLE:

perimeter

+// HTML-CIRCLE:

public double perimeter()

+// HTML-CIRCLE: Defined at line +// HTML-CIRCLE-NEXT: 9 +// HTML-CIRCLE-NEXT: of file +// HTML-CIRCLE-NEXT: Circle.cpp +// HTML-CIRCLE:
brief
+// HTML-CIRCLE:

Calculates the perimeter of the circle.

+// HTML-CIRCLE:
return
+// HTML-CIRCLE:

double The perimeter of the circle.

// MD-CALC: # class Calculator // MD-CALC: *Defined at .{{[\/]}}include{{[\/]}}Calculator.h#8* @@ -286,4 +339,4 @@ // MD-ALL-FILES: ## [GlobalNamespace](GlobalNamespace{{[\/]}}index.md) // MD-INDEX: # C/C++ Reference -// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) \ No newline at end of file +// MD-INDEX: * Namespace: [GlobalNamespace](GlobalNamespace) diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor.cpp index a5b6b240ddc66..2576d19916250 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor.cpp @@ -11,6 +11,7 @@ struct basic_string { basic_string(const C*, unsigned int size); basic_string(const C *, const A &allocator = A()); basic_string(unsigned int size, C c); + basic_string(const C*, unsigned int pos, unsigned int size); }; typedef basic_string string; typedef basic_string wstring; @@ -61,6 +62,21 @@ void Test() { // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour std::string q7 = 0; // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour + + std::string r1("test", 1, 0); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string + std::string r2("test", 0, -4); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter + std::string r3("test", -4, 1); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as position of the first character parameter + std::string r4("test", 0, 0x1000000); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter + std::string r5("test", 0, 5); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size + std::string r6("test", 3, 2); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than remaining string literal size + std::string r7("test", 4, 1); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: position of the first character parameter is bigger than string literal character range } void TestView() { @@ -82,6 +98,17 @@ void TestView() { // CHECK-MESSAGES: [[@LINE-1]]:25: warning: constructing string from nullptr is undefined behaviour } +void TestUnsignedArguments() { + std::string s0("test", 0u); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string + std::string s1(0x1000000ull, 'x'); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter + std::string s2("test", 3ull, 2u); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than remaining string literal size + std::string s3("test", 0u, 5ll); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size +} + std::string StringFromZero() { return 0; // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour @@ -101,6 +128,9 @@ void Valid() { std::string s3("test"); std::string s4("test\000", 5); std::string s6("te" "st", 4); + std::string s7("test", 0, 4); + std::string s8("test", 3, 1); + std::string s9("te" "st", 1, 2); std::string_view emptyv(); std::string_view sv1("test", 4); diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom-regex.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom-regex.cpp index fc97d1bc93bc5..ad0ba8739be2b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom-regex.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unsafe-functions-custom-regex.cpp @@ -1,11 +1,19 @@ // RUN: %check_clang_tidy -check-suffix=NON-STRICT-REGEX %s bugprone-unsafe-functions %t --\ -// RUN: -config="{CheckOptions: {bugprone-unsafe-functions.CustomFunctions: '::name_match,replacement,is a qualname match;^::prefix_match,,is matched on qualname prefix'}}" +// RUN: -config="{CheckOptions: {bugprone-unsafe-functions.CustomFunctions: '::name_match,replacement,is a qualname match;^::prefix_match,,is matched on qualname prefix;^::S::member_match_,,is matched on a C++ class member'}}" // RUN: %check_clang_tidy -check-suffix=STRICT-REGEX %s bugprone-unsafe-functions %t --\ -// RUN: -config="{CheckOptions: {bugprone-unsafe-functions.CustomFunctions: '^name_match$,replacement,is matched on function name only;^::prefix_match$,,is a full qualname match'}}" +// RUN: -config="{CheckOptions: {bugprone-unsafe-functions.CustomFunctions: '^name_match$,replacement,is matched on function name only;^::prefix_match$,,is a full qualname match;^::S::member_match_1$,,is matched on a C++ class member'}}" void name_match(); void prefix_match(); +struct S { + static void member_match_1() {} + void member_match_2() {} +}; + +void member_match_1() {} +void member_match_unmatched() {} + namespace regex_test { void name_match(); void prefix_match(); @@ -42,3 +50,25 @@ void f1() { // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:3: warning: function 'prefix_match_regex' is matched on qualname prefix; it should not be used // no-warning STRICT-REGEX } + +void f2() { + S s; + + S::member_match_1(); + // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:3: warning: function 'member_match_1' is matched on a C++ class member; it should not be used + // CHECK-MESSAGES-STRICT-REGEX: :[[@LINE-2]]:3: warning: function 'member_match_1' is matched on a C++ class member; it should not be used + + s.member_match_1(); + // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:5: warning: function 'member_match_1' is matched on a C++ class member; it should not be used + // CHECK-MESSAGES-STRICT-REGEX: :[[@LINE-2]]:5: warning: function 'member_match_1' is matched on a C++ class member; it should not be used + + s.member_match_2(); + // CHECK-MESSAGES-NON-STRICT-REGEX: :[[@LINE-1]]:5: warning: function 'member_match_2' is matched on a C++ class member; it should not be used + // no-warning STRICT-REGEX + + member_match_1(); + // no-warning + + member_match_unmatched(); + // no-warning +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp index 7396d2dce76c4..95d8ecb15a4f1 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp @@ -1,4 +1,5 @@ // RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26 +// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26 -DTEST_MACRO typedef __INT64_TYPE__ I64; @@ -91,6 +92,223 @@ int TestSimpleEquivalent(int X, int Y) { return 0; } +#ifndef TEST_MACRO +#define VAL_1 2 +#define VAL_3 3 +#else +#define VAL_1 3 +#define VAL_3 2 +#endif + +#define VAL_2 2 + +#ifndef TEST_MACRO +#define VAL_4 2 + 1 +#define VAL_6 3 + 1 +#else +#define VAL_4 3 + 1 +#define VAL_6 2 + 1 +#endif + +#define VAL_5 2 + 1 + +struct TestStruct +{ + int mA; + int mB; + int mC[10]; +}; + +int TestDefineEquivalent() { + + int int_val1 = 3; + int int_val2 = 4; + int int_val = 0; + const int cint_val2 = 4; + + // Cases which should not be reported + if (VAL_1 != VAL_2) return 0; + if (VAL_3 != VAL_2) return 0; + if (VAL_1 == VAL_2) return 0; + if (VAL_3 == VAL_2) return 0; + if (VAL_1 >= VAL_2) return 0; + if (VAL_3 >= VAL_2) return 0; + if (VAL_1 <= VAL_2) return 0; + if (VAL_3 <= VAL_2) return 0; + if (VAL_1 < VAL_2) return 0; + if (VAL_3 < VAL_2) return 0; + if (VAL_1 > VAL_2) return 0; + if (VAL_3 > VAL_2) return 0; + + if (VAL_4 != VAL_5) return 0; + if (VAL_6 != VAL_5) return 0; + if (VAL_6 == VAL_5) return 0; + if (VAL_4 >= VAL_5) return 0; + if (VAL_6 >= VAL_5) return 0; + if (VAL_4 <= VAL_5) return 0; + if (VAL_6 <= VAL_5) return 0; + if (VAL_4 > VAL_5) return 0; + if (VAL_6 > VAL_5) return 0; + if (VAL_4 < VAL_5) return 0; + if (VAL_6 < VAL_5) return 0; + + if (VAL_1 != 2) return 0; + if (VAL_3 == 3) return 0; + + if (VAL_1 >= VAL_1) return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent + if (VAL_2 <= VAL_2) return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent + if (VAL_3 > VAL_3) return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent + if (VAL_4 < VAL_4) return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent + if (VAL_6 == VAL_6) return 2; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent + if (VAL_5 != VAL_5) return 2; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent + + // Test prefixes + if (+VAL_6 == +VAL_6) return 2; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent + if (-VAL_6 == -VAL_6) return 2; + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent + if ((+VAL_6) == (+VAL_6)) return 2; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: both sides of operator are equivalent + if ((-VAL_6) == (-VAL_6)) return 2; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: both sides of operator are equivalent + + if (1 >= 1) return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent + if (0xFF <= 0xFF) return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: both sides of operator are equivalent + if (042 > 042) return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: both sides of operator are equivalent + + int_val = (VAL_6 == VAL_6)?int_val1: int_val2; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: both sides of operator are equivalent + int_val = (042 > 042)?int_val1: int_val2; + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent + + + // Ternary operator cases which should not be reported + int_val = (VAL_4 == VAL_5)? int_val1: int_val2; + int_val = (VAL_3 != VAL_2)? int_val1: int_val2; + int_val = (VAL_6 != 10)? int_val1: int_val2; + int_val = (VAL_6 != 3)? int_val1: int_val2; + int_val = (VAL_6 != 4)? int_val1: int_val2; + int_val = (VAL_6 == 3)? int_val1: int_val2; + int_val = (VAL_6 == 4)? int_val1: int_val2; + + TestStruct tsVar1 = { + .mA = 3, + .mB = int_val, + .mC[0 ... VAL_2 - 2] = int_val + 1, + }; + + TestStruct tsVar2 = { + .mA = 3, + .mB = int_val, + .mC[0 ... cint_val2 - 2] = int_val + 1, + }; + + TestStruct tsVar3 = { + .mA = 3, + .mB = int_val, + .mC[0 ... VAL_3 - VAL_3] = int_val + 1, + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: both sides of operator are equivalent + }; + + TestStruct tsVar4 = { + .mA = 3, + .mB = int_val, + .mC[0 ... 5 - 5] = int_val + 1, + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: both sides of operator are equivalent + }; + + return 1 + int_val + sizeof(tsVar1) + sizeof(tsVar2) + + sizeof(tsVar3) + sizeof(tsVar4); +} + +#define LOOP_DEFINE 1 + +unsigned int testLoops(const unsigned int arr1[LOOP_DEFINE]) +{ + unsigned int localIndex; + for (localIndex = LOOP_DEFINE - 1; localIndex > 0; localIndex--) + { + } + for (localIndex = LOOP_DEFINE - 1; 10 > 10; localIndex--) + // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: both sides of operator are equivalent + { + } + + for (localIndex = LOOP_DEFINE - 1; LOOP_DEFINE > LOOP_DEFINE; localIndex--) + // CHECK-MESSAGES: :[[@LINE-1]]:50: warning: both sides of operator are equivalent + { + } + + return localIndex; +} + +#define getValue(a) a +#define getValueM(a) a + +int TestParamDefine() { + int ret = 0; + + // Negative cases + ret += getValue(VAL_6) == getValue(2); + ret += getValue(VAL_6) == getValue(3); + ret += getValue(VAL_5) == getValue(2); + ret += getValue(VAL_5) == getValue(3); + ret += getValue(1) > getValue( 2); + ret += getValue(VAL_1) == getValue(VAL_2); + ret += getValue(VAL_1) != getValue(VAL_2); + ret += getValue(VAL_1) == getValueM(VAL_1); + ret += getValue(VAL_1 + VAL_2) == getValueM(VAL_1 + VAL_2); + ret += getValue(1) == getValueM(1); + ret += getValue(false) == getValueM(false); + ret += -getValue(1) > +getValue( 1); + + // Positive cases + ret += (+getValue(1)) > (+getValue( 1)); + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent + ret += (-getValue(1)) > (-getValue( 1)); + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: both sides of operator are equivalent + + ret += +getValue(1) > +getValue( 1); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent + ret += -getValue(1) > -getValue( 1); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent + + ret += getValue(1) > getValue( 1); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent + ret += getValue(1) > getValue( 1 ); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent + ret += getValue(1) > getValue( 1); + // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: both sides of operator are equivalent + ret += getValue( 1) > getValue( 1); + // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: both sides of operator are equivalent + ret += getValue( 1 ) > getValue( 1); + // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: both sides of operator are equivalent + ret += getValue( VAL_5 ) > getValue(VAL_5); + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent + ret += getValue( VAL_5 ) > getValue( VAL_5); + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent + ret += getValue( VAL_5 ) > getValue( VAL_5 ) ; + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent + ret += getValue(VAL_5) > getValue( VAL_5 ) ; + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent + ret += getValue(VAL_1+VAL_2) > getValue(VAL_1 + VAL_2) ; + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: both sides of operator are equivalent + ret += getValue(VAL_1)+getValue(VAL_2) > getValue(VAL_1) + getValue( VAL_2) ; + // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: both sides of operator are equivalent + ret += (getValue(VAL_1)+getValue(VAL_2)) > (getValue(VAL_1) + getValue( VAL_2) ) ; + // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: both sides of operator are equivalent + return ret; +} + template int TestSimpleEquivalentDependent() { if (DX > 0 && DX > 0) return 1; diff --git a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp index dfd31e6578714..97afa12cab6d3 100644 --- a/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp +++ b/clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp @@ -319,7 +319,12 @@ TEST(HTMLGeneratorTest, emitFunctionHTML) { int P)

-

Defined at line 10 of file dir/test.cpp

+

+ Defined at line + 10 + of file + test.cpp +

diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index b79e570667b2c..c3f30e2a8e9c0 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -331,6 +331,7 @@ if(NOT DEFINED CLANG_VERSION_SUFFIX) set(CLANG_VERSION_SUFFIX ${LLVM_VERSION_SUFFIX}) endif() set(CLANG_VERSION "${CLANG_VERSION_MAJOR}.${CLANG_VERSION_MINOR}.${CLANG_VERSION_PATCHLEVEL}${CLANG_VERSION_SUFFIX}") +set(MAX_CLANG_ABI_COMPAT_VERSION "${LLVM_VERSION_MAJOR}") message(STATUS "Clang version: ${CLANG_VERSION}") # Configure the Version.inc file. @@ -431,18 +432,16 @@ if(NOT LLVM_STATIC_LINK_CXX_STDLIB) set(HAVE_CLANG_REPL_SUPPORT ON) endif() -option(CLANG_ENABLE_ARCMT "Build ARCMT." ON) +option(CLANG_ENABLE_OBJC_REWRITER "Build the Objective-C rewriter tool" OFF) + option(CLANG_ENABLE_STATIC_ANALYZER "Include static analyzer in clang binary." ON) option(CLANG_ENABLE_PROTO_FUZZER "Build Clang protobuf fuzzer." OFF) -if(NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT) - message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3") -endif() - -if(CLANG_ENABLE_ARCMT) - set(CLANG_ENABLE_OBJC_REWRITER ON) +if (DEFINED CLANG_ENABLE_ARCMT) + set(CLANG_ENABLE_OBJC_REWRITER ${CLANG_ENABLE_ARCMT}) + message(DEPRECATION "'CLANG_ENABLE_ARCMT' is deprecated as ARCMigrate has been removed from Clang. Please use 'CLANG_ENABLE_OBJC_REWRITER' instead to enable or disable the Objective-C rewriter.") endif() # This option is a stop-gap, we should commit to removing this as @@ -872,58 +871,6 @@ if (CLANG_ENABLE_BOOTSTRAP) endforeach() endif() -set(CLANG_BOLT OFF CACHE STRING "Apply BOLT optimization to Clang. \ - May be specified as Instrument or Perf or LBR to use a particular profiling \ - mechanism.") -string(TOUPPER "${CLANG_BOLT}" CLANG_BOLT) - -if (CLANG_BOLT AND NOT LLVM_BUILD_INSTRUMENTED) - set(CLANG_PATH ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang) - set(CLANG_INSTRUMENTED ${LLVM_RUNTIME_OUTPUT_INTDIR}/${CLANG_BOLT_INSTRUMENTED}) - set(BOLT_FDATA ${CMAKE_CURRENT_BINARY_DIR}/utils/perf-training/prof.fdata) - - # Pass extra flag in no-LBR mode - if (CLANG_BOLT STREQUAL "PERF") - set(BOLT_NO_LBR "-nl") - endif() - - if (CLANG_BOLT STREQUAL "INSTRUMENT") - # Instrument clang with BOLT - add_custom_target(clang-instrumented - DEPENDS ${CLANG_INSTRUMENTED} - ) - add_custom_command(OUTPUT ${CLANG_INSTRUMENTED} - DEPENDS clang llvm-bolt - COMMAND llvm-bolt ${CLANG_PATH} -o ${CLANG_INSTRUMENTED} - -instrument --instrumentation-file-append-pid - --instrumentation-file=${BOLT_FDATA} - COMMENT "Instrumenting clang binary with BOLT" - USES_TERMINAL - VERBATIM - ) - add_custom_target(clang-bolt-training-deps DEPENDS clang-instrumented) - else() # perf or LBR - add_custom_target(clang-bolt-training-deps DEPENDS clang) - endif() - - # Optimize original (pre-bolt) Clang using the collected profile - add_custom_target(clang-bolt - DEPENDS clang-bolt-profile - COMMAND ${CMAKE_COMMAND} -E rename $ ${CLANG_PATH}-prebolt - COMMAND ${CMAKE_COMMAND} -E create_symlink ${CLANG_PATH}-prebolt ${CLANG_PATH}++-prebolt - COMMAND llvm-bolt ${CLANG_PATH}-prebolt - -o $ - -data ${BOLT_FDATA} - -reorder-blocks=ext-tsp -reorder-functions=cdsort -split-functions - -split-all-cold -split-eh -dyno-stats -use-gnu-stack - -update-debug-sections - ${BOLT_NO_LBR} - COMMENT "Optimizing Clang with BOLT" - USES_TERMINAL - VERBATIM - ) -endif() - if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION) add_subdirectory(utils/ClangVisualizers) endif() diff --git a/clang/cmake/caches/Android.cmake b/clang/cmake/caches/Android.cmake index d5ca6b50d4ada..c89e31f67cc9b 100644 --- a/clang/cmake/caches/Android.cmake +++ b/clang/cmake/caches/Android.cmake @@ -2,7 +2,6 @@ set(LLVM_TARGETS_TO_BUILD X86 CACHE STRING "") -set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") set(CLANG_TIDY_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") set(CLANG_VENDOR Android CACHE STRING "") diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 1cbf691f29d58..99890b8246ad7 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -44,7 +44,6 @@ set(CLANG_DEFAULT_LINKER lld CACHE STRING "") set(CLANG_DEFAULT_OBJCOPY llvm-objcopy CACHE STRING "") set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "") set(CLANG_DEFAULT_UNWINDLIB libunwind CACHE STRING "") -set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") set(CLANG_ENABLE_STATIC_ANALYZER ON CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") @@ -190,6 +189,10 @@ foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unkn set(RUNTIMES_${target}_LLVM_TOOLS_DIR "${CMAKE_BINARY_DIR}/bin" CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") + # Enable FatLTO for Linux and baremetal runtimes + set(RUNTIMES_${target}_LLVM_ENABLE_LTO OFF CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_FATLTO OFF CACHE BOOL "") + # Use .build-id link. list(APPEND RUNTIME_BUILD_ID_LINK "${target}") endif() @@ -272,6 +275,10 @@ if(FUCHSIA_SDK) set(RUNTIMES_${target}+asan+noexcept_LIBCXXABI_ENABLE_EXCEPTIONS OFF CACHE BOOL "") set(RUNTIMES_${target}+asan+noexcept_LIBCXX_ENABLE_EXCEPTIONS OFF CACHE BOOL "") + # Enable FatLTO for Fuchsia runtimes + set(RUNTIMES_${target}_LLVM_ENABLE_LTO OFF CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_FATLTO OFF CACHE BOOL "") + # Use .build-id link. list(APPEND RUNTIME_BUILD_ID_LINK "${target}") endforeach() @@ -369,6 +376,10 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv7em-none-eabi;armv8m.main-n set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "libc;libcxx" CACHE STRING "") + + # Enable FatLTO for baremetal runtimes + set(RUNTIMES_${target}_LLVM_ENABLE_LTO OFF CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_FATLTO OFF CACHE BOOL "") endforeach() foreach(target riscv32-unknown-elf) @@ -420,6 +431,10 @@ foreach(target riscv32-unknown-elf) set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_RUNTIMES "libc;libcxx" CACHE STRING "") + + # Enable FatLTO for baremetal runtimes + set(RUNTIMES_${target}_LLVM_ENABLE_LTO OFF CACHE BOOL "") + set(RUNTIMES_${target}_LLVM_ENABLE_FATLTO OFF CACHE BOOL "") endforeach() set(LLVM_BUILTIN_TARGETS "${BUILTIN_TARGETS}" CACHE STRING "") diff --git a/clang/cmake/caches/Fuchsia.cmake b/clang/cmake/caches/Fuchsia.cmake index 07637cd0ed08f..83336589da305 100644 --- a/clang/cmake/caches/Fuchsia.cmake +++ b/clang/cmake/caches/Fuchsia.cmake @@ -84,7 +84,6 @@ set(CLANG_DEFAULT_LINKER lld CACHE STRING "") set(CLANG_DEFAULT_OBJCOPY llvm-objcopy CACHE STRING "") set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "") set(CLANG_DEFAULT_UNWINDLIB libunwind CACHE STRING "") -set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") diff --git a/clang/docs/BoundsSafety.rst b/clang/docs/BoundsSafety.rst index e24c69d8c7855..cf5b0c75c0387 100644 --- a/clang/docs/BoundsSafety.rst +++ b/clang/docs/BoundsSafety.rst @@ -777,13 +777,13 @@ the transformed pseudo code of function ``alloc_buf()`` in the example below. size_t count; } sized_buf_t; - void alloc_buf(sized_buf_t *sbuf, sized_t nelems) { + void alloc_buf(sized_buf_t *sbuf, size_t nelems) { sbuf->buf = (int *)malloc(sizeof(int) * nelems); sbuf->count = nelems; } // Transformed pseudo code: - void alloc_buf(sized_buf_t *sbuf, sized_t nelems) { + void alloc_buf(sized_buf_t *sbuf, size_t nelems) { // Materialize RHS values: int *tmp_ptr = (int *)malloc(sizeof(int) * nelems); int tmp_count = nelems; @@ -959,7 +959,8 @@ that has the define. #if defined(__has_feature) && __has_feature(bounds_safety) #define __counted_by(T) __attribute__((__counted_by__(T))) // ... other bounds annotations - #else #define __counted_by(T) // defined as nothing + #else + #define __counted_by(T) // defined as nothing // ... other bounds annotations #endif @@ -987,7 +988,7 @@ and it does not guarantee other types of memory safety properties. Consequently, it may not prevent some of the secondary bounds safety violations caused by other types of safety violations such as type confusion. For instance, ``-fbounds-safety`` does not perform type-safety checks on conversions between -`__single`` pointers of different pointee types (e.g., ``char *__single`` → +``__single`` pointers of different pointee types (e.g., ``char *__single`` → ``void *__single`` → ``int *__single``) beyond what the foundation languages (C/C++) already offer. @@ -1003,4 +1004,4 @@ Try it out Your feedback on the programming model is valuable. You may want to follow the instruction in :doc:`BoundsSafetyAdoptionGuide` to play with ``-fbounds-safety`` -and please send your feedback to `Yeoul Na `_. \ No newline at end of file +and please send your feedback to `Yeoul Na `_. diff --git a/clang/docs/BoundsSafetyImplPlans.rst b/clang/docs/BoundsSafetyImplPlans.rst index 93c2ed7b43402..34276c920f31e 100644 --- a/clang/docs/BoundsSafetyImplPlans.rst +++ b/clang/docs/BoundsSafetyImplPlans.rst @@ -134,7 +134,7 @@ same basic block and without side effect in between. int *__counted_by(count) buf; size_t count; } sized_buf_t; - void alloc_buf(sized_buf_t *sbuf, sized_t nelems) { + void alloc_buf(sized_buf_t *sbuf, size_t nelems) { sbuf->buf = (int *)malloc(sizeof(int) * nelems); sbuf->count = nelems; } diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst index 30a2325949f48..bf6dd9e13915f 100644 --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -2182,6 +2182,24 @@ the configuration (without a prefix: ``Auto``). aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa); } +.. _BinPackLongBracedList: + +**BinPackLongBracedList** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ ` + If ``BinPackLongBracedList`` is ``true`` it overrides + ``BinPackArguments`` if there are 20 or more items in a braced + initializer list. + + .. code-block:: c++ + + BinPackLongBracedList: false vs. BinPackLongBracedList: true + vector x{ vector x{1, 2, ..., + 20, 21}; + 1, + 2, + ..., + 20, + 21}; + .. _BinPackParameters: **BinPackParameters** (``BinPackParametersStyle``) :versionbadge:`clang-format 3.7` :ref:`¶ ` @@ -3421,6 +3439,35 @@ the configuration (without a prefix: ``Auto``). +.. _BreakBeforeTemplateCloser: + +**BreakBeforeTemplateCloser** (``Boolean``) :versionbadge:`clang-format 21` :ref:`¶ ` + If ``true``, break before a template closing bracket (``>``) when there is + a line break after the matching opening bracket (``<``). + + .. code-block:: c++ + + true: + template + + template + + template < + typename Foo, + typename Bar + > + + false: + template + + template + + template < + typename Foo, + typename Bar> + .. _BreakBeforeTernaryOperators: **BreakBeforeTernaryOperators** (``Boolean``) :versionbadge:`clang-format 3.7` :ref:`¶ ` @@ -5198,6 +5245,11 @@ the configuration (without a prefix: ``Auto``). **PenaltyBreakBeforeFirstCallParameter** (``Unsigned``) :versionbadge:`clang-format 3.7` :ref:`¶ ` The penalty for breaking a function call after ``call(``. +.. _PenaltyBreakBeforeMemberAccess: + +**PenaltyBreakBeforeMemberAccess** (``Unsigned``) :versionbadge:`clang-format 20` :ref:`¶ ` + The penalty for breaking before a member access operator (``.``, ``->``). + .. _PenaltyBreakComment: **PenaltyBreakComment** (``Unsigned``) :versionbadge:`clang-format 3.7` :ref:`¶ ` diff --git a/clang/docs/ControlFlowIntegrity.rst b/clang/docs/ControlFlowIntegrity.rst index 7de805e2154db..3c97f7da3d7d9 100644 --- a/clang/docs/ControlFlowIntegrity.rst +++ b/clang/docs/ControlFlowIntegrity.rst @@ -336,6 +336,15 @@ cross-DSO function address equality. These properties make KCFI easier to adopt in low-level software. KCFI is limited to checking only function pointers, and isn't compatible with executable-only memory. +``-fsanitize-kcfi-arity`` +----------------------------- + +For supported targets, this feature extends kCFI by telling the compiler to +record information about each indirect-callable function's arity (i.e., the +number of arguments passed in registers) into the binary. Some kernel CFI +techniques, such as FineIBT, may be able to use this information to provide +enhanced security. + Member Function Pointer Call Checking ===================================== diff --git a/clang/docs/HIPSupport.rst b/clang/docs/HIPSupport.rst index e830acd8dd85c..481ed39230813 100644 --- a/clang/docs/HIPSupport.rst +++ b/clang/docs/HIPSupport.rst @@ -27,7 +27,8 @@ AMD GPU Support Clang provides HIP support on AMD GPUs via the ROCm platform ``_. The ROCm runtime forms the base for HIP host APIs, while HIP device APIs are realized through HIP header files and the ROCm device library. The Clang driver uses the HIPAMD toolchain to compile HIP device code -to AMDGPU ISA via the AMDGPU backend. The compiled code is then bundled and embedded in the host executables. +to AMDGPU ISA via the AMDGPU backend, or SPIR-V via the workflow outlined below. +The compiled code is then bundled and embedded in the host executables. Intel GPU Support ================= @@ -285,6 +286,401 @@ Example Usage basePtr->virtualFunction(); // Allowed since obj is constructed in device code } +C++ Standard Parallelism Offload Support: Compiler And Runtime +============================================================== + +Introduction +============ + +This section describes the implementation of support for offloading the +execution of standard C++ algorithms to accelerators that can be targeted via +HIP. Furthermore, it enumerates restrictions on user defined code, as well as +the interactions with runtimes. + +Algorithm Offload: What, Why, Where +=================================== + +C++17 introduced overloads +`for most algorithms in the standard library `_ +which allow the user to specify a desired +`execution policy `_. +The `parallel_unsequenced_policy `_ +maps relatively well to the execution model of AMD GPUs. This, coupled with the +the availability and maturity of GPU accelerated algorithm libraries that +implement most / all corresponding algorithms in the standard library +(e.g. `rocThrust `__), makes +it feasible to provide seamless accelerator offload for supported algorithms, +when an accelerated version exists. Thus, it becomes possible to easily access +the computational resources of an AMD accelerator, via a well specified, +familiar, algorithmic interface, without having to delve into low-level hardware +specific details. Putting it all together: + +- **What**: standard library algorithms, when invoked with the + ``parallel_unsequenced_policy`` +- **Why**: democratise AMDGPU accelerator programming, without loss of user + familiarity +- **Where**: only AMDGPU accelerators targeted by Clang/LLVM via HIP + +Small Example +============= + +Given the following C++ code: + +.. code-block:: C++ + + bool has_the_answer(const std::vector& v) { + return std::find(std::execution::par_unseq, std::cbegin(v), std::cend(v), 42) != std::cend(v); + } + +if Clang is invoked with the ``--hipstdpar --offload-arch=foo`` flags, the call +to ``find`` will be offloaded to an accelerator that is part of the ``foo`` +target family. If either ``foo`` or its runtime environment do not support +transparent on-demand paging (such as e.g. that provided in Linux via +`HMM `_), it is necessary to also include +the ``--hipstdpar-interpose-alloc`` flag. If the accelerator specific algorithm +library ``foo`` uses doesn't have an implementation of a particular algorithm, +execution seamlessly falls back to the host CPU. It is legal to specify multiple +``--offload-arch``\s. All the flags we introduce, as well as a thorough view of +various restrictions an their implementations, will be provided below. + +Implementation - General View +============================= + +We built support for Algorithm Offload support atop the pre-existing HIP +infrastructure. More specifically, when one requests offload via ``--hipstdpar``, +compilation is switched to HIP compilation, as if ``-x hip`` was specified. +Similarly, linking is also switched to HIP linking, as if ``--hip-link`` was +specified. Note that these are implicit, and one should not assume that any +interop with HIP specific language constructs is available e.g. ``__device__`` +annotations are neither necessary nor guaranteed to work. + +Since there are no language restriction mechanisms in place, it is necessary to +relax HIP language specific semantic checks performed by the FE; they would +identify otherwise valid, offloadable code, as invalid HIP code. Given that we +know that the user intended only for certain algorithms to be offloaded, and +encoded this by specifying the ``parallel_unsequenced_policy``, we rely on a +pass over IR to clean up any and all code that was not "meant" for offload. If +requested, allocation interposition is also handled via a separate pass over IR. + +To interface with the client HIP runtime, and to forward offloaded algorithm +invocations to the corresponding accelerator specific library implementation, an +implementation detail forwarding header is implicitly included by the driver, +when compiling with ``--hipstdpar``. In what follows, we will delve into each +component that contributes to implementing Algorithm Offload support. + +Implementation - Driver +======================= + +We augment the ``clang`` driver with the following flags: + +- ``--hipstdpar`` enables algorithm offload, which depending on phase, has the + following effects: + + - when compiling: + + - ``-x hip`` gets prepended to enable HIP support; + - the ``ROCmToolchain`` component checks for the ``hipstdpar_lib.hpp`` + forwarding header, + `rocThrust `_ and + `rocPrim `_ in + their canonical locations, which can be overriden via flags found below; + if all are found, the forwarding header gets implicitly included, + otherwise an error listing the missing component is generated; + - the ``LangOpts.HIPStdPar`` member is set. + + - when linking: + + - ``--hip-link`` and ``-frtlib-add-rpath`` gets appended to enable HIP + support. + +- ``--hipstdpar-interpose-alloc`` enables the interposition of standard + allocation / deallocation functions with accelerator aware equivalents; the + ``LangOpts.HIPStdParInterposeAlloc`` member is set; +- ``--hipstdpar-path=`` specifies a non-canonical path for the forwarding + header; it must point to the folder where the header is located and not to the + header itself; +- ``--hipstdpar-thrust-path=`` specifies a non-canonical path for + `rocThrust `_; it + must point to the folder where the library is installed / built under a + ``/thrust`` subfolder; +- ``--hipstdpar-prim-path=`` specifies a non-canonical path for + `rocPrim `_; it must + point to the folder where the library is installed / built under a + ``/rocprim`` subfolder; + +The `--offload-arch `_ +flag can be used to specify the accelerator for which offload code is to be +generated. + +Implementation - Front-End +========================== + +When ``LangOpts.HIPStdPar`` is set, we relax some of the HIP language specific +``Sema`` checks to account for the fact that we want to consume pure unannotated +C++ code: + +1. ``__device__`` / ``__host__ __device__`` functions (which would originate in + the accelerator specific algorithm library) are allowed to call implicitly + ``__host__`` functions; +2. ``__global__`` functions (which would originate in the accelerator specific + algorithm library) are allowed to call implicitly ``__host__`` functions; +3. resolving ``__builtin`` availability is deferred, because it is possible that + a ``__builtin`` that is unavailable on the target accelerator is not + reachable from any offloaded algorithm, and thus will be safely removed in + the middle-end; +4. ASM parsing / checking is deferred, because it is possible that an ASM block + that e.g. uses some constraints that are incompatible with the target + accelerator is not reachable from any offloaded algorithm, and thus will be + safely removed in the middle-end. + +``CodeGen`` is similarly relaxed, with implicitly ``__host__`` functions being +emitted as well. + +Implementation - Middle-End +=========================== + +We add two ``opt`` passes: + +1. ``HipStdParAcceleratorCodeSelectionPass`` + + - For all kernels in a ``Module``, compute reachability, where a function + ``F`` is reachable from a kernel ``K`` if and only if there exists a direct + call-chain rooted in ``F`` that includes ``K``; + - Remove all functions that are not reachable from kernels; + - This pass is only run when compiling for the accelerator. + +The first pass assumes that the only code that the user intended to offload was +that which was directly or transitively invocable as part of an algorithm +execution. It also assumes that an accelerator aware algorithm implementation +would rely on accelerator specific special functions (kernels), and that these +effectively constitute the only roots for accelerator execution graphs. Both of +these assumptions are based on observing how widespread accelerators, +such as GPUs, work. + +1. ``HipStdParAllocationInterpositionPass`` + + - Iterate through all functions in a ``Module``, and replace standard + allocation / deallocation functions with accelerator-aware equivalents, + based on a pre-established table; the list of functions that can be + interposed is available + `here `__; + - This is only run when compiling for the host. + +The second pass is optional. + +Implementation - Forwarding Header +================================== + +The forwarding header implements two pieces of functionality: + +1. It forwards algorithms to a target accelerator, which is done by relying on + C++ language rules around overloading: + + - overloads taking an explicit argument of type + ``parallel_unsequenced_policy`` are introduced into the ``std`` namespace; + - these will get preferentially selected versus the master template; + - the body forwards to the equivalent algorithm from the accelerator specific + library + +2. It provides allocation / deallocation functions that are equivalent to the + standard ones, but obtain memory by invoking + `hipMallocManaged `_ + and release it via `hipFree `_. + +Predefined Macros +================= + +.. list-table:: + :header-rows: 1 + + * - Macro + - Description + * - ``__HIPSTDPAR__`` + - Defined when Clang is compiling code in algorithm offload mode, enabled + with the ``--hipstdpar`` compiler option. + * - ``__HIPSTDPAR_INTERPOSE_ALLOC__`` + - Defined only when compiling in algorithm offload mode, when the user + enables interposition mode with the ``--hipstdpar-interpose-alloc`` + compiler option, indicating that all dynamic memory allocation / + deallocation functions should be replaced with accelerator aware + variants. + +Restrictions +============ + +We define two modes in which runtime execution can occur: + +1. **HMM Mode** - this assumes that the + `HMM `_ subsystem of the Linux kernel + is used to provide transparent on-demand paging i.e. memory obtained from a + system / OS allocator such as via a call to ``malloc`` or ``operator new`` is + directly accessible to the accelerator and it follows the C++ memory model; +2. **Interposition Mode** - this is a fallback mode for cases where transparent + on-demand paging is unavailable (e.g. in the Windows OS), which means that + memory must be allocated via an accelerator aware mechanism, and system + allocated memory is inaccessible for the accelerator. + +The following restrictions imposed on user code apply to both modes: + +1. Pointers to function, and all associated features, such as e.g. dynamic + polymorphism, cannot be used (directly or transitively) by the user provided + callable passed to an algorithm invocation; +2. Global / namespace scope / ``static`` / ``thread`` storage duration variables + cannot be used (directly or transitively) in name by the user provided + callable; + + - When executing in **HMM Mode** they can be used in address e.g.: + + .. code-block:: C++ + + namespace { int foo = 42; } + + bool never(const std::vector& v) { + return std::any_of(std::execution::par_unseq, std::cbegin(v), std::cend(v), [](auto&& x) { + return x == foo; + }); + } + + bool only_in_hmm_mode(const std::vector& v) { + return std::any_of(std::execution::par_unseq, std::cbegin(v), std::cend(v), + [p = &foo](auto&& x) { return x == *p; }); + } + +3. Only algorithms that are invoked with the ``parallel_unsequenced_policy`` are + candidates for offload; +4. Only algorithms that are invoked with iterator arguments that model + `random_access_iterator `_ + are candidates for offload; +5. `Exceptions `_ cannot + be used by the user provided callable; +6. Dynamic memory allocation (e.g. ``operator new``) cannot be used by the user + provided callable; +7. Selective offload is not possible i.e. it is not possible to indicate that + only some algorithms invoked with the ``parallel_unsequenced_policy`` are to + be executed on the accelerator. + +In addition to the above, using **Interposition Mode** imposes the following +additional restrictions: + +1. All code that is expected to interoperate has to be recompiled with the + ``--hipstdpar-interpose-alloc`` flag i.e. it is not safe to compose libraries + that have been independently compiled; +2. automatic storage duration (i.e. stack allocated) variables cannot be used + (directly or transitively) by the user provided callable e.g. + + .. code-block:: c++ + + bool never(const std::vector& v, int n) { + return std::any_of(std::execution::par_unseq, std::cbegin(v), std::cend(v), + [p = &n](auto&& x) { return x == *p; }); + } + +Current Support +=============== + +At the moment, C++ Standard Parallelism Offload is only available for AMD GPUs, +when the `ROCm `_ stack is used, on the +Linux operating system. Support is synthesised in the following table: + +.. list-table:: + :header-rows: 1 + + * - `Processor `_ + - HMM Mode + - Interposition Mode + * - GCN GFX9 (Vega) + - YES + - YES + * - GCN GFX10.1 (RDNA 1) + - *NO* + - YES + * - GCN GFX10.3 (RDNA 2) + - *NO* + - YES + * - GCN GFX11 (RDNA 3) + - *NO* + - YES + * - GCN GFX12 (RDNA 4) + - *NO* + - YES + +The minimum Linux kernel version for running in HMM mode is 6.4. + +The forwarding header can be obtained from +`its GitHub repository `_. +It will be packaged with a future `ROCm `_ +release. Because accelerated algorithms are provided via +`rocThrust `_, a +transitive dependency on +`rocPrim `_ exists. Both +can be obtained either by installing their associated components of the +`ROCm `_ stack, or from their respective +repositories. The list algorithms that can be offloaded is available +`here `_. + +HIP Specific Elements +--------------------- + +1. There is no defined interop with the + `HIP kernel language `_; + whilst things like using `__device__` annotations might accidentally "work", + they are not guaranteed to, and thus cannot be relied upon by user code; + + - A consequence of the above is that both bitcode linking and linking + relocatable object files will "work", but it is not guaranteed to remain + working or actively tested at the moment; this restriction might be relaxed + in the future. + +2. Combining explicit HIP, CUDA or OpenMP Offload compilation with + ``--hipstdpar`` based offloading is not allowed or supported in any way. +3. There is no way to target different accelerators via a standard algorithm + invocation (`this might be addressed in future C++ standards `_); + an unsafe (per the point above) way of achieving this is to spawn new threads + and invoke the `hipSetDevice `_ + interface e.g.: + + .. code-block:: c++ + + int accelerator_0 = ...; + int accelerator_1 = ...; + + bool multiple_accelerators(const std::vector& u, const std::vector& v) { + std::atomic r{0u}; + + thread t0{[&]() { + hipSetDevice(accelerator_0); + + r += std::count(std::execution::par_unseq, std::cbegin(u), std::cend(u), 42); + }}; + thread t1{[&]() { + hitSetDevice(accelerator_1); + + r += std::count(std::execution::par_unseq, std::cbegin(v), std::cend(v), 314152) + }}; + + t0.join(); + t1.join(); + + return r; + } + + Note that this is a temporary, unsafe workaround for a deficiency in the C++ + Standard. + +Open Questions / Future Developments +==================================== + +1. The restriction on the use of global / namespace scope / ``static`` / + ``thread`` storage duration variables in offloaded algorithms will be lifted + in the future, when running in **HMM Mode**; +2. The restriction on the use of dynamic memory allocation in offloaded + algorithms will be lifted in the future. +3. The restriction on the use of pointers to function, and associated features + such as dynamic polymorphism might be lifted in the future, when running in + **HMM Mode**; +4. Offload support might be extended to cases where the ``parallel_policy`` is + used for some or all targets. + SPIR-V Support on HIPAMD ToolChain ================================== @@ -316,13 +712,6 @@ Using ``--offload-arch=amdgcnspirv`` - **Clang Offload Bundler**: The resulting SPIR-V is embedded in the Clang offload bundler with the bundle ID ``hip-spirv64-amd-amdhsa--amdgcnspirv``. -Mixed with Normal ``--offload-arch`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -**Mixing ``amdgcnspirv`` and concrete ``gfx###`` targets via ``--offload-arch`` -is not currently supported; this limitation is temporary and will be removed in -a future release** - Architecture Specific Macros ---------------------------- diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index c42b88015e269..973cf8f9d091c 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -514,9 +514,7 @@ available in all language modes. __nullptr --------- -``__nullptr`` is an alternate spelling for ``nullptr``, but is also available in -C++ modes prior to C++11. Note that it's currently not availbale in C despite -C23 having support for ``nullptr``. +``__nullptr`` is an alternate spelling for ``nullptr``. It is available in all C and C++ language modes. __signed, __signed__ -------------------- @@ -759,6 +757,9 @@ The integer elementwise intrinsics, including ``__builtin_elementwise_popcount`` ``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``, ``__builtin_elementwise_sub_sat`` can be called in a ``constexpr`` context. +No implicit promotion of integer types takes place. The mixing of integer types +of different sizes and signs is forbidden in binary and ternary builtins. + ============================================== ====================================================================== ========================================= Name Operation Supported element types ============================================== ====================================================================== ========================================= @@ -1802,10 +1803,6 @@ The following type trait primitives are supported by Clang. Those traits marked * ``__is_pointer_interconvertible_base_of`` (C++, GNU, Microsoft) * ``__is_polymorphic`` (C++, GNU, Microsoft, Embarcadero) * ``__is_reference`` (C++, Embarcadero) -* ``__is_referenceable`` (C++, GNU, Microsoft, Embarcadero): - Returns true if a type is referenceable, and false otherwise. A referenceable - type is a type that's either an object type, a reference type, or an unqualified - function type. This trait is deprecated and will be removed in Clang 21. * ``__is_rvalue_reference`` (C++, Embarcadero) * ``__is_same`` (C++, Embarcadero) * ``__is_same_as`` (GCC): Synonym for ``__is_same``. diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index 673c34bf08a4a..725624ee8c66c 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -364,6 +364,8 @@ implementation. +=============================================================+===========================+===========================+==========================================================================+ | free-agent threads | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ +| threadset clause | :`worked on` | :none:`unclaimed` | | ++-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | Recording of task graphs | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | Parallel inductions | :none:`unclaimed` | :none:`unclaimed` | | @@ -410,13 +412,13 @@ implementation. +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | Extensions to interop construct | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ -| no_openmp_constructs | :none:`unclaimed` | :none:`unclaimed` | | +| no_openmp_constructs | :good:`done` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/125933 | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | safe_sync and progress with identifier and API | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ -| OpenMP directives in concurrent loop regions | :none:`unclaimed` | :none:`unclaimed` | | +| OpenMP directives in concurrent loop regions | :good:`done` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/125621 | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ -| atomics constructs on concurrent loop regions | :none:`unclaimed` | :none:`unclaimed` | | +| atomics constructs on concurrent loop regions | :good:`done` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/125621 | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | Loop construct with DO CONCURRENT | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ @@ -454,9 +456,7 @@ implementation. +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | map-type modifiers in arbitrary position | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ -| atomic constructs in loop region | :none:`unclaimed` | :none:`unclaimed` | | -+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ -| Lift nesting restriction on concurrent loop | :none:`unclaimed` | :none:`unclaimed` | | +| Lift nesting restriction on concurrent loop | :good:`done` | :none:`unclaimed` | https://github.com/llvm/llvm-project/pull/125621 | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ | priority clause for target constructs | :none:`unclaimed` | :none:`unclaimed` | | +-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f110b8cf76507..6344c4b36e357 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -33,218 +33,23 @@ latest release, please see the `Clang Web Site `_ or the Potentially Breaking Changes ============================ -These changes are ones which we think may surprise users when upgrading to -Clang |release| because of the opportunity they pose for disruption to existing -code bases. - -- The ``le32`` and ``le64`` targets have been removed. - -- ``clang -m32`` defaults to ``-mcpu=v9`` on SPARC Linux now. Distros - still supporting SPARC V8 CPUs need to specify ``-mcpu=v8`` with a - `config file - `_. - -- The ``clang-rename`` tool has been removed. - -- Removed support for RenderScript targets. This technology is - `officially deprecated `_ - and users are encouraged to - `migrate to Vulkan `_ - or other options. - -- Clang now emits distinct type-based alias analysis tags for incompatible - pointers by default, enabling more powerful alias analysis when accessing - pointer types. This change may silently change code behavior for code - containing strict-aliasing violations. The new default behavior can be - disabled using ``-fno-pointer-tbaa``. - -- Clang will now more aggressively use undefined behavior on pointer addition - overflow for optimization purposes. For example, a check like - ``ptr + unsigned_offset < ptr`` will now optimize to ``false``, because - ``ptr + unsigned_offset`` will cause undefined behavior if it overflows (or - advances past the end of the object). - - Previously, ``ptr + unsigned_offset < ptr`` was optimized (by both Clang and - GCC) to ``(ssize_t)unsigned_offset < 0``. This also results in an incorrect - overflow check, but in a way that is less apparent when only testing with - pointers in the low half of the address space. - - To avoid pointer addition overflow, it is necessary to perform the addition - on integers, for example using - ``(uintptr_t)ptr + unsigned_offset < (uintptr_t)ptr``. Sometimes, it is also - possible to rewrite checks by only comparing the offset. For example, - ``ptr + offset < end_ptr && ptr + offset >= ptr`` can be written as - ``offset < (uintptr_t)(end_ptr - ptr)``. - - Undefined behavior due to pointer addition overflow can be reliably detected - using ``-fsanitize=pointer-overflow``. It is also possible to use - ``-fno-strict-overflow`` to opt-in to a language dialect where signed integer - and pointer overflow are well-defined. + +- The Objective-C ARC migrator (ARCMigrate) has been removed. C/C++ Language Potentially Breaking Changes ------------------------------------------- -- Clang now rejects ``_Complex _BitInt`` types. - C++ Specific Potentially Breaking Changes ----------------------------------------- -- The type trait builtin ``__is_nullptr`` has been removed, since it has very - few users and can be written as ``__is_same(__remove_cv(T), decltype(nullptr))``, - which GCC supports as well. - -- The type trait builtin ``__is_referenceable`` has been deprecated, since it has +- The type trait builtin ``__is_referenceable`` has been removed, since it has very few users and all the type traits that could benefit from it in the - standard library already have their own bespoke builtins. It will be removed in - Clang 21. - -- Clang will now correctly diagnose as ill-formed a constant expression where an - enum without a fixed underlying type is set to a value outside the range of - the enumeration's values. - - .. code-block:: c++ - - enum E { Zero, One, Two, Three, Four }; - constexpr E Val1 = (E)3; // Ok - constexpr E Val2 = (E)7; // Ok - constexpr E Val3 = (E)8; // Now ill-formed, out of the range [0, 7] - constexpr E Val4 = (E)-1; // Now ill-formed, out of the range [0, 7] - - Since Clang 16, it has been possible to suppress the diagnostic via - `-Wno-enum-constexpr-conversion`, to allow for a transition period for users. - Now, in Clang 20, **it is no longer possible to suppress the diagnostic**. - -- Extraneous template headers are now ill-formed by default. - This error can be disable with ``-Wno-error=extraneous-template-head``. - - .. code-block:: c++ - - template <> // error: extraneous template head - template - void f(); - -- During constant evaluation, comparisons between different evaluations of the - same string literal are now correctly treated as non-constant, and comparisons - between string literals that cannot possibly overlap in memory are now treated - as constant. This updates Clang to match the anticipated direction of open core - issue `CWG2765 `, but is subject to change once that - issue is resolved. - - .. code-block:: c++ - - constexpr const char *f() { return "hello"; } - constexpr const char *g() { return "world"; } - // Used to evaluate to false, now error: non-constant comparison. - constexpr bool a = f() == f(); - // Might evaluate to true or false, as before. - bool at_runtime() { return f() == f(); } - // Was error, now evaluates to false. - constexpr bool b = f() == g(); - -- Clang will now correctly not consider pointers to non classes for covariance - and disallow changing return type to a type that doesn't have the same or less cv-qualifications. - - .. code-block:: c++ - - struct A { - virtual const int *f() const; - virtual const std::string *g() const; - }; - struct B : A { - // Return type has less cv-qualification but doesn't point to a class. - // Error will be generated. - int *f() const override; - - // Return type doesn't have more cv-qualification also not the same or - // less cv-qualification. - // Error will be generated. - volatile std::string *g() const override; - }; - -- The warning ``-Wdeprecated-literal-operator`` is now on by default, as this is - something that WG21 has shown interest in removing from the language. The - result is that anyone who is compiling with ``-Werror`` should see this - diagnostic. To fix this diagnostic, simply removing the space character from - between the ``operator""`` and the user defined literal name will make the - source no longer deprecated. This is consistent with `CWG2521 _`. - - .. code-block:: c++ - - // Now diagnoses by default. - unsigned operator"" _udl_name(unsigned long long); - // Fixed version: - unsigned operator""_udl_name(unsigned long long); - -- Clang will now produce an error diagnostic when ``[[clang::lifetimebound]]`` is - applied on a parameter or an implicit object parameter of a function that - returns void. This was previously ignored and had no effect. (#GH107556) - - .. code-block:: c++ - - // Now diagnoses with an error. - void f(int& i [[clang::lifetimebound]]); - -- Clang will now produce an error diagnostic when ``[[clang::lifetimebound]]`` - is applied on a type (instead of a function parameter or an implicit object - parameter); this includes the case when the attribute is specified for an - unnamed function parameter. These were previously ignored and had no effect. - (#GH118281) - - .. code-block:: c++ - - // Now diagnoses with an error. - int* [[clang::lifetimebound]] x; - // Now diagnoses with an error. - void f(int* [[clang::lifetimebound]] i); - // Now diagnoses with an error. - void g(int* [[clang::lifetimebound]]); - -- Clang now rejects all field accesses on null pointers in constant expressions. The following code - used to work but will now be rejected: - - .. code-block:: c++ - - struct S { int a; int b; }; - constexpr const int *p = &((S*)nullptr)->b; - - Previously, this code was erroneously accepted. - -- Clang will now consider the implicitly deleted destructor of a union or - a non-union class without virtual base class to be ``constexpr`` in C++20 - mode (Clang 19 only did so in C++23 mode but the standard specification for - this changed in C++20). (#GH85550) - - .. code-block:: c++ - - struct NonLiteral { - NonLiteral() {} - ~NonLiteral() {} - }; - - template - struct Opt { - union { - char c; - T data; - }; - bool engaged = false; - - constexpr Opt() {} - constexpr ~Opt() { - if (engaged) - data.~T(); - } - }; - - // Previously only accepted in C++23 and later, now also accepted in C++20. - consteval void foo() { Opt{}; } + standard library already have their own bespoke builtins. ABI Changes in This Version --------------------------- -- Fixed Microsoft name mangling of placeholder, auto and decltype(auto), return types for MSVC 1920+. This change resolves incompatibilities with code compiled by MSVC 1920+ but will introduce incompatibilities with code compiled by earlier versions of Clang unless such code is built with the compiler option -fms-compatibility-version=19.14 to imitate the MSVC 1914 mangling behavior. -- Fixed the Itanium mangling of the construction vtable name. This change will introduce incompatibilities with code compiled by Clang 19 and earlier versions, unless the -fclang-abi-compat=19 option is used. (#GH108015) -- Mangle member-like friend function templates as members of the enclosing class. (#GH110247, #GH110503) +- Return larger CXX records in memory instead of using AVX registers. Code compiled with older clang will be incompatible with newer version of the clang unless -fclang-abi-compat=20 is provided. (#GH120670) AST Dumping Potentially Breaking Changes ---------------------------------------- @@ -254,569 +59,82 @@ Clang Frontend Potentially Breaking Changes Clang Python Bindings Potentially Breaking Changes -------------------------------------------------- -- Parts of the interface returning string results will now return - the empty string ``""`` when no result is available, instead of ``None``. -- Calling a property on the ``CompletionChunk`` or ``CompletionString`` class - statically now leads to an error, instead of returning a ``CachedProperty`` object - that is used internally. Properties are only available on instances. -- For a single-line ``SourceRange`` and a ``SourceLocation`` in the same line, - but after the end of the ``SourceRange``, ``SourceRange.__contains__`` - used to incorrectly return ``True``. (#GH22617), (#GH52827) What's New in Clang |release|? ============================== -Some of the major new features and improvements to Clang are listed -here. Generic improvements to Clang as a whole or to its underlying -infrastructure are described first, followed by language-specific -sections with improvements to Clang's support for those languages. C++ Language Changes -------------------- -- Allow single element access of GCC vector/ext_vector_type object to be - constant expression. Supports the `V.xyzw` syntax and other tidbits - as seen in OpenCL. Selecting multiple elements is left as a future work. -- Implement `CWG1815 `_. Support lifetime extension - of temporary created by aggregate initialization using a default member - initializer. - -- Accept C++26 user-defined ``static_assert`` messages in C++11 as an extension. - -- Add ``__builtin_elementwise_popcount`` builtin for integer types only. - -- Add ``__builtin_elementwise_fmod`` builtin for floating point types only. - -- Add ``__builtin_elementwise_minimum`` and ``__builtin_elementwise_maximum`` - builtin for floating point types only. - -- The builtin type alias ``__builtin_common_type`` has been added to improve the - performance of ``std::common_type``. C++2c Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- Add ``__builtin_is_virtual_base_of`` intrinsic, which supports - `P2985R0 A type trait for detecting virtual base classes `_ - -- Implemented `P2893R3 Variadic Friends `_ - -- Implemented `P2747R2 constexpr placement new `_. - -- Added the ``__builtin_is_within_lifetime`` builtin, which supports - `P2641R4 Checking if a union alternative is active `_ - -- Implemented `P3176R1 The Oxford variadic comma `_ - C++23 Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- Removed the restriction to literal types in constexpr functions in C++23 mode. - -- Extend lifetime of temporaries in mem-default-init for P2718R0. Clang now fully - supports `P2718R0 Lifetime extension in range-based for loops `_. - -- ``__cpp_explicit_this_parameter`` is now defined. (#GH82780) - -- Add ``__builtin_is_implicit_lifetime`` intrinsic, which supports - `P2674R1 A trait for implicit lifetime types `_ - -- Add support for `P2280R4 Using unknown pointers and references in constant expressions `_. (#GH63139) C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- Implemented module level lookup for C++20 modules. (#GH90154) - C++17 Feature Support ^^^^^^^^^^^^^^^^^^^^^ -- The implementation of the relaxed template template argument matching rules is - more complete and reliable, and should provide more accurate diagnostics. Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Allow calling initializer list constructors from initializer lists with - a single element of the same type instead of always copying. - (`CWG2137: List-initialization from object of same type `) - -- Speculative resolution for CWG2311 implemented so that the implementation of CWG2137 doesn't remove - previous cases where guaranteed copy elision was done. Given a prvalue ``e`` of class type - ``T``, ``T{e}`` will try to resolve an initializer list constructor and will use it if successful. - Otherwise, if there is no initializer list constructor, the copy will be elided as if it was ``T(e)``. - (`CWG2311: Missed case for guaranteed copy elision `) - -- Casts from a bit-field to an integral type is now not considered narrowing if the - width of the bit-field means that all potential values are in the range - of the target type, even if the type of the bit-field is larger. - (`CWG2627: Bit-fields and narrowing conversions `_) - -- ``nullptr`` is now promoted to ``void*`` when passed to a C-style variadic function. - (`CWG722: Can nullptr be passed to an ellipsis? `_) - -- Allow ``void{}`` as a prvalue of type ``void``. - (`CWG2351: void{} `_). - -- Clang now has improved resolution to CWG2398, allowing class templates to have - default arguments deduced when partial ordering, and better backwards compatibility - in overload resolution. - -- Clang now allows comparing unequal object pointers that have been cast to ``void *`` - in constant expressions. These comparisons always worked in non-constant expressions. - (`CWG2749: Treatment of "pointer to void" for relational comparisons `_). - -- Reject explicit object parameters with type ``void`` (``this void``). - (`CWG2915: Explicit object parameters of type void `_). - -- Clang now allows trailing requires clause on explicit deduction guides. - (`CWG2707: Deduction guides cannot have a trailing requires-clause `_). - -- Respect constructor constraints during CTAD. - (`CWG2628: Implicit deduction guides should propagate constraints `_). - -- Clang now diagnoses a space in the first production of a ``literal-operator-id`` - by default. - (`CWG2521: User-defined literals and reserved identifiers `_). - -- Fix name lookup for a dependent base class that is the current instantiation. - (`CWG591: When a dependent base class is the current instantiation `_). - -- Clang now allows calling explicit object member functions directly with prvalues - instead of always materializing a temporary, meaning by-value explicit object parameters - do not need to move from a temporary. - (`CWG2813: Class member access with prvalues `_). +- The flag `-frelaxed-template-template-args` + and its negation have been removed, having been deprecated since the previous + two releases. The improvements to template template parameter matching implemented + in the previous release, as described in P3310 and P3579, made this flag unnecessary. C Language Changes ------------------ -- Extend clang's ```` to define ``LONG_LONG_*`` macros for Android's bionic. +- Clang now allows an ``inline`` specifier on a typedef declaration of a + function type in Microsoft compatibility mode. #GH124869 C2y Feature Support ^^^^^^^^^^^^^^^^^^^ -- Updated conformance for `N3298 `_ - which adds the ``i`` and ``j`` suffixes for the creation of a ``_Complex`` - constant value. Clang has always supported these suffixes as a GNU extension, - so ``-Wgnu-imaginary-constant`` no longer has effect in C modes, as this is - now a C2y extension in C. ``-Wgnu-imaginary-constant`` still applies in C++ - modes. - -- Clang updated conformance for `N3370 `_ - case range expressions. This feature was previously supported by Clang as a - GNU extension, so ``-Wgnu-case-range`` no longer has effect in C modes, as - this is now a C2y extension in C. ``-Wgnu-case-range`` still applies in C++ - modes. - -- Clang implemented support for `N3344 `_ - which disallows a ``void`` parameter from having a qualifier or storage class - specifier. Note that ``register void`` was previously accepted in all C - language modes but is now rejected (all of the other qualifiers and storage - class specifiers were previously rejected). - -- Updated conformance for `N3364 `_ - on floating-point translation-time initialization with signaling NaN. This - paper adopts Clang's existing practice, so there were no changes to compiler - behavior. - -- Implemented support for `N3341 `_ - which makes empty structure and union objects implementation-defined in C. - ``-Wgnu-empty-struct`` will be emitted in C23 and earlier modes because the - behavior is a conforming GNU extension in those modes, but will no longer - have an effect in C2y mode. - -- Updated conformance for `N3342 `_ - which made qualified function types implementation-defined rather than - undefined. Clang has always accepted ``const`` and ``volatile`` qualified - function types by ignoring the qualifiers. - -- Updated conformance for `N3346 `_ - which changes some undefined behavior around initialization to instead be - constraint violations. This paper adopts Clang's existing practice, so there - were no changes to compiler behavior. - C23 Feature Support ^^^^^^^^^^^^^^^^^^^ -- Clang now supports `N3029 `_ Improved Normal Enumerations. -- Clang now officially supports `N3030 `_ Enhancements to Enumerations. Clang already supported it as an extension, so there were no changes to compiler behavior. -- Fixed the value of ``BOOL_WIDTH`` in ```` to return ``1`` - explicitly, as mandated by the standard. Fixes #GH117348 - Non-comprehensive list of changes in this release ------------------------------------------------- -- The floating point comparison builtins (``__builtin_isgreater``, - ``__builtin_isgreaterequal``, ``__builtin_isless``, etc.) and - ``__builtin_signbit`` can now be used in constant expressions. -- Plugins can now define custom attributes that apply to statements - as well as declarations. -- ``__builtin_abs`` function can now be used in constant expressions. - -- The new builtin ``__builtin_counted_by_ref`` was added. In contexts where the - programmer needs access to the ``counted_by`` attribute's field, but it's not - available --- e.g. in macros. For instance, it can be used to automatically - set the counter during allocation in the Linux kernel: - - .. code-block:: c - - /* A simplified version of Linux allocation macros */ - #define alloc(PTR, FAM, COUNT) ({ \ - sizeof_t __ignored_assignment; \ - typeof(P) __p; \ - size_t __size = sizeof(*P) + sizeof(*P->FAM) * COUNT; \ - __p = malloc(__size); \ - *_Generic( \ - __builtin_counted_by_ref(__p->FAM), \ - void *: &__ignored_assignment, \ - default: __builtin_counted_by_ref(__p->FAM)) = COUNT; \ - __p; \ - }) - - The flexible array member (FAM) can now be accessed immediately without causing - issues with the sanitizer because the counter is automatically set. - -- The following builtins can now be used in constant expressions: ``__builtin_reduce_add``, - ``__builtin_reduce_mul``, ``__builtin_reduce_and``, ``__builtin_reduce_or``, - ``__builtin_reduce_xor``, ``__builtin_elementwise_popcount``, - ``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``, - ``__builtin_elementwise_sub_sat``, ``__builtin_reduce_min`` (For integral element type), - ``__builtin_reduce_max`` (For integral element type). - -- Clang now rejects ``_BitInt`` matrix element types if the bit width is less than ``CHAR_WIDTH`` or - not a power of two, matching preexisting behaviour for vector types. - -- Matrix types (a Clang extension) can now be used in pseudo-destructor expressions, - which allows them to be stored in STL containers. - -- In the ``-ftime-report`` output, the new "Clang time report" group replaces - the old "Clang front-end time report" and includes "Front end", "LLVM IR - generation", "Optimizer", and "Machine code generation". - New Compiler Flags ------------------ -- The ``-fc++-static-destructors={all,thread-local,none}`` flag was - added to control which C++ variables have static destructors - registered: all (the default) does so for all variables, thread-local - only for thread-local variables, and none (which corresponds to the - existing ``-fno-c++-static-destructors`` flag) skips all static - destructors registration. - -- The ``-Warray-compare`` warning has been added to warn about array comparison - on versions older than C++20. - -- The ``-Warray-compare-cxx26`` warning has been added to warn about array comparison - starting from C++26, this warning is enabled as an error by default. - -- clang-cl and clang-dxc now support ``-fdiagnostics-color=[auto|never|always]`` - in addition to ``-f[no-]color-diagnostics``. +- New option ``-fprofile-continuous`` added to enable continuous profile syncing to file (#GH124353, `docs `_). + The feature has `existed `_) + for a while and this is just a user facing option. Deprecated Compiler Flags ------------------------- -- ``-fheinous-gnu-extensions`` is deprecated; it is now equivalent to - specifying ``-Wno-error=invalid-gnu-asm-cast`` and may be removed in the - future. - Modified Compiler Flags ----------------------- -- The ``-ffp-model`` option has been updated to enable a more limited set of - optimizations when the ``fast`` argument is used and to accept a new argument, - ``aggressive``. The behavior of ``-ffp-model=aggressive`` is equivalent - to the previous behavior of ``-ffp-model=fast``. The updated - ``-ffp-model=fast`` behavior no longer assumes finite math only and uses - the ``promoted`` algorithm for complex division when possible rather than the - less basic (limited range) algorithm. - -- The ``-fveclib`` option has been updated to enable ``-fno-math-errno`` for - ``-fveclib=ArmPL`` and ``-fveclib=SLEEF``. This gives Clang more opportunities - to utilize these vector libraries. The behavior for all other vector function - libraries remains unchanged. - -- The ``-Wnontrivial-memcall`` warning has been added to warn about - passing non-trivially-copyable destination parameter to ``memcpy``, - ``memset`` and similar functions for which it is a documented undefined - behavior. It is implied by ``-Wnontrivial-memaccess`` - -- Added ``-fmodules-reduced-bmi`` flag corresponding to - ``-fexperimental-modules-reduced-bmi`` flag. The ``-fmodules-reduced-bmi`` flag - is intended to be enabled by default in the future. - Removed Compiler Flags ------------------------- -- The compiler flag `-Wenum-constexpr-conversion` (and the `Wno-`, `Wno-error-` - derivatives) is now removed, since it's no longer possible to suppress the - diagnostic (see above). Users can expect an `unknown warning` diagnostic if - it's still in use. - Attribute Changes in Clang -------------------------- -- The ``swift_attr`` can now be applied to types. To make it possible to use imported APIs - in Swift safely there has to be a way to annotate individual parameters and result types - with relevant attributes that indicate that e.g. a block is called on a particular actor - or it accepts a Sendable or global-actor (i.e. ``@MainActor``) isolated parameter. - - For example: - - .. code-block:: objc - - @interface MyService - -(void) handle: (void (^ __attribute__((swift_attr("@Sendable"))))(id)) handler; - @end - -- Clang now disallows more than one ``__attribute__((ownership_returns(class, idx)))`` with - different class names attached to one function. - -- Introduced a new format attribute ``__attribute__((format(syslog, 1, 2)))`` from OpenBSD. - -- The ``hybrid_patchable`` attribute is now supported on ARM64EC targets. It can be used to specify - that a function requires an additional x86-64 thunk, which may be patched at runtime. - -- The attribute ``[[clang::no_specializations]]`` has been added to warn - users that a specific template shouldn't be specialized. This is useful for - e.g. standard library type traits, where adding a specialization results in - undefined behaviour. - -- ``[[clang::lifetimebound]]`` is now explicitly disallowed on explicit object member functions - where they were previously silently ignored. - -- Clang now automatically adds ``[[clang::lifetimebound]]`` to the parameters of - ``std::span, std::string_view`` constructors, this enables Clang to capture - more cases where the returned reference outlives the object. - (#GH100567) - -- Clang now correctly diagnoses the use of ``btf_type_tag`` in C++ and ignores - it; this attribute is a C-only attribute, and caused crashes with template - instantiation by accidentally allowing it in C++ in some circumstances. - (#GH106864) - -- Introduced a new attribute ``[[clang::coro_await_elidable]]`` on coroutine return types - to express elideability at call sites where the coroutine is invoked under a safe elide context. - -- Introduced a new attribute ``[[clang::coro_await_elidable_argument]]`` on function parameters - to propagate safe elide context to arguments if such function is also under a safe elide context. - -- The documentation of the ``[[clang::musttail]]`` attribute was updated to - note that the lifetimes of all local variables end before the call. This does - not change the behaviour of the compiler, as this was true for previous - versions. - -- Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or - ``[[gsl::Pointer]]`` to STL explicit template specialization decls. (#GH109442) - -- Clang now supports ``[[clang::lifetime_capture_by(X)]]``. Similar to lifetimebound, this can be - used to specify when a reference to a function parameter is captured by another capturing entity ``X``. - -- The ``target_version`` attribute is now only supported for AArch64 and RISC-V architectures. - -- Clang now permits the usage of the placement new operator in ``[[msvc::constexpr]]`` - context outside of the std namespace. (#GH74924) - -- Clang now disallows the use of attributes after the namespace name. (#GH121407) +- The ``no_sanitize`` attribute now accepts both ``gnu`` and ``clang`` names. +- Clang now diagnoses use of declaration attributes on void parameters. (#GH108819) Improvements to Clang's diagnostics ----------------------------------- -- Some template related diagnostics have been improved. - - .. code-block:: c++ - - void foo() { template int i; } // error: templates can only be declared in namespace or class scope - - struct S { - template int i; // error: non-static data member 'i' cannot be declared as a template - }; - -- Clang now has improved diagnostics for functions with explicit 'this' parameters. Fixes #GH97878 - -- Clang now diagnoses dangling references to fields of temporary objects. Fixes #GH81589. - -- Clang now diagnoses undefined behavior in constant expressions more consistently. This includes invalid shifts, and signed overflow in arithmetic. - -- -Wdangling-assignment-gsl is enabled by default. -- Clang now always preserves the template arguments as written used - to specialize template type aliases. - -- Clang now diagnoses the use of ``main`` in an ``extern`` context as invalid according to [basic.start.main] p3. Fixes #GH101512. - -- Clang now diagnoses when the result of a [[nodiscard]] function is discarded after being cast in C. Fixes #GH104391. - -- Clang now properly explains the reason a template template argument failed to - match a template template parameter, in terms of the C++17 relaxed matching rules - instead of the old ones. - -- Don't emit duplicated dangling diagnostics. (#GH93386). - -- Improved diagnostic when trying to befriend a concept. (#GH45182). - -- Added the ``-Winvalid-gnu-asm-cast`` diagnostic group to control warnings - about use of "noop" casts for lvalues (a GNU extension). This diagnostic is - a warning which defaults to being an error, is enabled by default, and is - also controlled by the now-deprecated ``-fheinous-gnu-extensions`` flag. - -- Added the ``-Wdecls-in-multiple-modules`` option to assist users to identify - multiple declarations in different modules, which is the major reason of the slow - compilation speed with modules. This warning is disabled by default and it needs - to be explicitly enabled or by ``-Weverything``. - -- Improved diagnostic when trying to overload a function in an ``extern "C"`` context. (#GH80235) - -- Clang now respects lifetimebound attribute for the assignment operator parameter. (#GH106372). - -- The lifetimebound and GSL analysis in clang are coherent, allowing clang to - detect more use-after-free bugs. (#GH100549). - -- Clang now diagnoses dangling cases where a gsl-pointer is constructed from a gsl-owner object inside a container (#GH100384). - -- Clang now warns for u8 character literals used in C23 with ``-Wpre-c23-compat`` instead of ``-Wpre-c++17-compat``. - -- Clang now diagnose when importing module implementation partition units in module interface units. - -- Don't emit bogus dangling diagnostics when ``[[gsl::Owner]]`` and `[[clang::lifetimebound]]` are used together (#GH108272). - -- Don't emit bogus dignostic about an undefined behavior on ``reinterpret_cast`` for non-instantiated template functions without sufficient knowledge whether it can actually lead to undefined behavior for ``T`` (#GH109430). - -- The ``-Wreturn-stack-address`` warning now also warns about addresses of - local variables passed to function calls using the ``[[clang::musttail]]`` - attribute. - -- Clang now diagnoses cases where a dangling ``GSLOwner`` object is constructed, e.g. ``std::vector v = {std::string()};`` (#GH100526). - -- Clang now diagnoses when a ``requires`` expression has a local parameter of void type, aligning with the function parameter (#GH109831). - -- Clang now emits a diagnostic note at the class declaration when the method definition does not match any declaration (#GH110638). - -- Clang now omits warnings for extra parentheses in fold expressions with single expansion (#GH101863). - -- The warning for an unsupported type for a named register variable is now phrased ``unsupported type for named register variable``, - instead of ``bad type for named register variable``. This makes it clear that the type is not supported at all, rather than being - suboptimal in some way the error fails to mention (#GH111550). - -- Clang now emits a ``-Wdepredcated-literal-operator`` diagnostic, even if the - name was a reserved name, which we improperly allowed to suppress the - diagnostic. - -- Clang now diagnoses ``[[deprecated]]`` attribute usage on local variables (#GH90073). - -- Fix false positives when `[[gsl::Owner/Pointer]]` and `[[clang::lifetimebound]]` are used together. - -- Improved diagnostic message for ``__builtin_bit_cast`` size mismatch (#GH115870). - -- Clang now omits shadow warnings for enum constants in separate class scopes (#GH62588). - -- When diagnosing an unused return value of a type declared ``[[nodiscard]]``, the type - itself is now included in the diagnostic. - -- Clang will now prefer the ``[[nodiscard]]`` declaration on function declarations over ``[[nodiscard]]`` - declaration on the return type of a function. Previously, when both have a ``[[nodiscard]]`` declaration attached, - the one on the return type would be preferred. This may affect the generated warning message: - - .. code-block:: c++ - - struct [[nodiscard("Reason 1")]] S {}; - [[nodiscard("Reason 2")]] S getS(); - void use() - { - getS(); // Now diagnoses "Reason 2", previously diagnoses "Reason 1" - } - -- Clang now diagnoses ``= delete("reason")`` extension warnings only in pedantic mode rather than on by default. (#GH109311). - -- Clang now diagnoses missing return value in functions containing ``if consteval`` (#GH116485). - -- Clang now correctly recognises code after a call to a ``[[noreturn]]`` constructor - as unreachable (#GH63009). - -- Clang now omits shadowing warnings for parameter names in explicit object member functions (#GH95707). - -- Improved error recovery for function call arguments with trailing commas (#GH100921). - -- For an rvalue reference bound to a temporary struct with an integer member, Clang will detect constant integer overflow - in the initializer for the integer member (#GH46755). - -- Fixed a false negative ``-Wunused-private-field`` diagnostic when a defaulted comparison operator is defined out of class (#GH116961). - -- Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957). - -- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings when an unrelated class - defined a defaulted comparison operator (#GH116270). - - .. code-block:: c++ - - class A { - private: - int a; // warning: private field 'a' is not used, no diagnostic previously - }; - - class C { - bool operator==(const C&) = default; - }; - -- Clang now emits `-Wdangling-capture` diangostic when a STL container captures a dangling reference. - - .. code-block:: c++ - - void test() { - std::vector views; - views.push_back(std::string("123")); // warning - } - -- Clang now emits a ``-Wtautological-compare`` diagnostic when a check for - pointer addition overflow is always true or false, because overflow would - be undefined behavior. - - .. code-block:: c++ - - bool incorrect_overflow_check(const char *ptr, size_t index) { - return ptr + index < ptr; // warning - } - -- Clang now emits a ``-Wvarargs`` diagnostic when the second argument - to ``va_arg`` is of array type, which is an undefined behavior (#GH119360). - - .. code-block:: c++ - - void test() { - va_list va; - va_arg(va, int[10]); // warning - } - -- Fix -Wdangling false positives on conditional operators (#120206). - -- Fixed a bug where Clang hung on an unsupported optional scope specifier ``::`` when parsing - Objective-C. Clang now emits a diagnostic message instead of hanging. - -- The :doc:`ThreadSafetyAnalysis` now supports passing scoped capabilities into functions: - an attribute on the scoped capability parameter indicates both the expected associated capabilities and, - like in the case of attributes on the function declaration itself, their state before and after the call. - - .. code-block:: c++ - - #include "mutex.h" - - Mutex mu1, mu2; - int a GUARDED_BY(mu1); - - void require(MutexLocker& scope REQUIRES(mu1)) { - scope.Unlock(); - a = 0; // Warning! Requires mu1. - scope.Lock(); - } - - void testParameter() { - MutexLocker scope(&mu1), scope2(&mu2); - require(scope2); // Warning! Mutex managed by 'scope2' is 'mu2' instead of 'mu1' - require(scope); // OK. - scope.Unlock(); - require(scope); // Warning! Requires mu1. - } -- Diagnose invalid declarators in the declaration of constructors and destructors (#GH121706). - -- Fix false positives warning for non-std functions with name `infinity` (#123231). - -- Clang now emits a ``-Wignored-qualifiers`` diagnostic when a base class includes cv-qualifiers (#GH55474). - -- Clang now diagnoses the use of attribute names reserved by the C++ standard (#GH92196). +- Improve the diagnostics for deleted default constructor errors for C++ class + initializer lists that don't explicitly list a class member and thus attempt + to implicitly default construct that member. +- The ``-Wunique-object-duplication`` warning has been added to warn about objects + which are supposed to only exist once per program, but may get duplicated when + built into a shared library. +- Fixed a bug where Clang's Analysis did not correctly model the destructor behavior of ``union`` members (#GH119415). +- A statement attribute applied to a ``case`` label no longer suppresses + 'bypassing variable initialization' diagnostics (#84072). Improvements to Clang's time-trace ---------------------------------- @@ -827,365 +145,78 @@ Improvements to Coverage Mapping Bug Fixes in This Version ------------------------- -- Fixed the definition of ``ATOMIC_FLAG_INIT`` in ```` so it can - be used in C++. -- Fixed a failed assertion when checking required literal types in C context. (#GH101304). -- Fixed a crash when trying to transform a dependent address space type. Fixes #GH101685. -- Fixed a crash when diagnosing format strings and encountering an empty - delimited escape sequence (e.g., ``"\o{}"``). #GH102218 -- Fixed a crash using ``__array_rank`` on 64-bit targets. (#GH113044). -- The warning emitted for an unsupported register variable type now points to - the unsupported type instead of the ``register`` keyword (#GH109776). -- Fixed a crash when emit ctor for global variant with flexible array init (#GH113187). -- Fixed a crash when GNU statement expression contains invalid statement (#GH113468). -- Fixed a crash when passing the variable length array type to ``va_arg`` (#GH119360). -- Fixed a failed assertion when using ``__attribute__((noderef))`` on an - ``_Atomic``-qualified type (#GH116124). -- No longer incorrectly diagnosing use of a deleted destructor when the - selected overload of ``operator delete`` for that type is a destroying delete - (#GH46818). -- No longer return ``false`` for ``noexcept`` expressions involving a - ``delete`` which resolves to a destroying delete but the type of the object - being deleted has a potentially throwing destructor (#GH118660). - Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Fix crash when atomic builtins are called with pointer to zero-size struct (#GH90330) - -- Clang now allows pointee types of atomic builtin arguments to be complete template types - that was not instantiated elsewhere. - -- ``__noop`` can now be used in a constant expression. (#GH102064) - -- Fix ``__has_builtin`` incorrectly returning ``false`` for some C++ type traits. (#GH111477) - -- Fix ``__builtin_source_location`` incorrectly returning wrong column for method chains. (#GH119129) +- The behvaiour of ``__add_pointer`` and ``__remove_pointer`` for Objective-C++'s ``id`` and interfaces has been fixed. Bug Fixes to Attribute Support ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + - Fixed crash when a parameter to the ``clang::annotate`` attribute evaluates to ``void``. See #GH119125 Bug Fixes to C++ Support ^^^^^^^^^^^^^^^^^^^^^^^^ -- Fixed a crash when an expression with a dependent ``__typeof__`` type is used as the operand of a unary operator. (#GH97646) -- Fixed incorrect pack expansion of init-capture references in requires expresssions. -- Fixed a failed assertion when checking invalid delete operator declaration. (#GH96191) -- Fix a crash when checking destructor reference with an invalid initializer. (#GH97230) -- Clang now correctly parses potentially declarative nested-name-specifiers in pointer-to-member declarators. -- Fix a crash when checking the initializer of an object that was initialized - with a string literal. (#GH82167) -- Fix a crash when matching template template parameters with templates which have - parameters of different class type. (#GH101394) -- Clang now correctly recognizes the correct context for parameter - substitutions in concepts, so it doesn't incorrectly complain of missing - module imports in those situations. (#GH60336) -- Fix init-capture packs having a size of one before being instantiated. (#GH63677) -- Clang now preserves the unexpanded flag in a lambda transform used for pack expansion. (#GH56852), (#GH85667), - (#GH99877), (#GH122417). -- Fixed a bug when diagnosing ambiguous explicit specializations of constrained member functions. -- Fixed an assertion failure when selecting a function from an overload set that includes a - specialization of a conversion function template. -- Correctly diagnose attempts to use a concept name in its own definition; - A concept name is introduced to its scope sooner to match the C++ standard. (#GH55875) -- Properly reject defaulted relational operators with invalid types for explicit object parameters, - e.g., ``bool operator==(this int, const Foo&)`` (#GH100329), and rvalue reference parameters. -- Properly reject defaulted copy/move assignment operators that have a non-reference explicit object parameter. -- Clang now properly handles the order of attributes in `extern` blocks. (#GH101990). -- Fixed an assertion failure by preventing null explicit object arguments from being deduced. (#GH102025). -- Correctly check constraints of explicit instantiations of member functions. (#GH46029) -- When performing partial ordering of function templates, clang now checks that - the deduction was consistent. Fixes (#GH18291). -- Fixes to several issues in partial ordering of template template parameters, which - were documented in the test suite. -- Fixed an assertion failure about a constraint of a friend function template references to a value with greater - template depth than the friend function template. (#GH98258) -- Clang now rebuilds the template parameters of out-of-line declarations and specializations in the context - of the current instantiation in all cases. -- Fix evaluation of the index of dependent pack indexing expressions/types specifiers (#GH105900) -- Correctly handle subexpressions of an immediate invocation in the presence of implicit casts. (#GH105558) -- Clang now correctly handles direct-list-initialization of a structured bindings from an array. (#GH31813) -- Mangle placeholders for deduced types as a template-prefix, such that mangling - of template template parameters uses the correct production. (#GH106182) -- Fixed an assertion failure when converting vectors to int/float with invalid expressions. (#GH105486) -- Template parameter names are considered in the name lookup of out-of-line class template - specialization right before its declaration context. (#GH64082) -- Fixed a constraint comparison bug for friend declarations. (#GH78101) -- Fix handling of ``_`` as the name of a lambda's init capture variable. (#GH107024) -- Fix an issue with dependent source location expressions (#GH106428), (#GH81155), (#GH80210), (#GH85373) -- Fixed a bug in the substitution of empty pack indexing types. (#GH105903) -- Clang no longer tries to capture non-odr used default arguments of template parameters of generic lambdas (#GH107048) -- Fixed a bug where defaulted comparison operators would remove ``const`` from base classes. (#GH102588) -- Fix a crash when using ``source_location`` in the trailing return type of a lambda expression. (#GH67134) -- A follow-up fix was added for (#GH61460), as the previous fix was not entirely correct. (#GH86361), (#GH112352) -- Fixed a crash in the typo correction of an invalid CTAD guide. (#GH107887) -- Fixed a crash when clang tries to substitute parameter pack while retaining the parameter - pack. (#GH63819), (#GH107560) -- Fix a crash when a static assert declaration has an invalid close location. (#GH108687) -- Avoided a redundant friend declaration instantiation under a certain ``consteval`` context. (#GH107175) -- Fixed an assertion failure in debug mode, and potential crashes in release mode, when - diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter. -- Fixed an assertion failure by adjusting integral to boolean vector conversions (#GH108326) -- Fixed a crash when mixture of designated and non-designated initializers in union. (#GH113855) -- Fixed an issue deducing non-type template arguments of reference type. (#GH73460) -- Fixed an issue in constraint evaluation, where type constraints on the lambda expression - containing outer unexpanded parameters were not correctly expanded. (#GH101754) -- Fixes crashes with function template member specializations, and increases - conformance of explicit instantiation behaviour with MSVC. (#GH111266) -- Fixed a bug in constraint expression comparison where the ``sizeof...`` expression was not handled properly - in certain friend declarations. (#GH93099) -- Clang now instantiates the correct lambda call operator when a lambda's class type is - merged across modules. (#GH110401) -- Fix a crash when parsing a pseudo destructor involving an invalid type. (#GH111460) -- Fixed an assertion failure when invoking recovery call expressions with explicit attributes - and undeclared templates. (#GH107047), (#GH49093) -- Clang no longer crashes when a lambda contains an invalid block declaration that contains an unexpanded - parameter pack. (#GH109148) -- Fixed overload handling for object parameters with top-level cv-qualifiers in explicit member functions (#GH100394) -- Fixed a bug in lambda captures where ``constexpr`` class-type objects were not properly considered ODR-used in - certain situations. (#GH47400), (#GH90896) -- Fix erroneous templated array size calculation leading to crashes in generated code. (#GH41441) -- During the lookup for a base class name, non-type names are ignored. (#GH16855) -- Fix a crash when recovering an invalid expression involving an explicit object member conversion operator. (#GH112559) -- Clang incorrectly considered a class with an anonymous union member to not be - const-default-constructible even if a union member has a default member initializer. - (#GH95854). -- Fixed an assertion failure when evaluating an invalid expression in an array initializer. (#GH112140) -- Fixed an assertion failure in range calculations for conditional throw expressions. (#GH111854) -- Clang now correctly ignores previous partial specializations of member templates explicitly specialized for - an implicitly instantiated class template specialization. (#GH51051) -- Fixed an assertion failure caused by invalid enum forward declarations. (#GH112208) -- Name independent data members were not correctly initialized from default member initializers. (#GH114069) -- Fixed expression transformation for ``[[assume(...)]]``, allowing using pack indexing expressions within the - assumption if they also occur inside of a dependent lambda. (#GH114787) -- Lambdas now capture function types without considering top-level const qualifiers. (#GH84961) -- Clang now uses valid deduced type locations when diagnosing functions with trailing return type - missing placeholder return type. (#GH78694) -- Fixed a bug where bounds of partially expanded pack indexing expressions were checked too early. (#GH116105) -- Fixed an assertion failure caused by using ``consteval`` in condition in consumed analyses. (#GH117385) -- Fixed an assertion failure caused by invalid default argument substitutions in non-defining - friend declarations. (#GH113324) -- Fix a crash caused by incorrect argument position in merging deduced template arguments. (#GH113659) -- Fixed a parser crash when using pack indexing as a nested name specifier. (#GH119072) -- Fixed a null pointer dereference issue when heuristically computing ``sizeof...(pack)`` expressions. (#GH81436) -- Fixed an assertion failure caused by mangled names with invalid identifiers. (#GH112205) -- Fixed an incorrect lambda scope of generic lambdas that caused Clang to crash when computing potential lambda - captures at the end of a full expression. (#GH115931) -- Clang no longer rejects deleting a pointer of incomplete enumeration type. (#GH99278) -- Fixed recognition of ``std::initializer_list`` when it's surrounded with ``extern "C++"`` and exported - out of a module (which is the case e.g. in MSVC's implementation of ``std`` module). (#GH118218) -- Fixed a pack expansion issue in checking unexpanded parameter sizes. (#GH17042) -- Fixed a bug where captured structured bindings were modifiable inside non-mutable lambda (#GH95081) -- Passing incomplete types to ``__is_base_of`` and other builtin type traits for which the corresponding - standard type trait mandates a complete type is now a hard (non-sfinae-friendly) error - (`LWG3929 `__.) (#GH121278) -- Clang now identifies unexpanded parameter packs within the type constraint on a non-type template parameter. (#GH88866) -- Fixed an issue while resolving type of expression indexing into a pack of values of non-dependent type (#GH121242) -- Fixed a crash when __PRETTY_FUNCTION__ or __FUNCSIG__ (clang-cl) appears in the trailing return type of the lambda (#GH121274) -- Fixed a crash caused by the incorrect construction of template arguments for CTAD alias guides when type - constraints are applied. (#GH122134) -- Fixed canonicalization of pack indexing types - Clang did not always recognized identical pack indexing. (#GH123033) -- Fixed a nested lambda substitution issue for constraint evaluation. (#GH123441) -- Fixed various false diagnostics related to the use of immediate functions. (#GH123472) -- Fix immediate escalation not propagating through inherited constructors. (#GH112677) -- Fixed assertions or false compiler diagnostics in the case of C++ modules for - lambda functions or inline friend functions defined inside templates (#GH122493). +- Clang is now better at keeping track of friend function template instance contexts. (#GH55509) +- The initialization kind of elements of structured bindings + direct-list-initialized from an array is corrected to direct-initialization. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ -- Fixed a crash that occurred when dividing by zero in complex integer division. (#GH55390). -- Fixed a bug in ``ASTContext::getRawCommentForAnyRedecl()`` where the function could - sometimes incorrectly return null even if a comment was present. (#GH108145) -- Clang now correctly parses the argument of the ``relates``, ``related``, ``relatesalso``, - and ``relatedalso`` comment commands. -- Clang now uses the location of the begin of the member expression for ``CallExpr`` - involving deduced ``this``. (#GH116928) -- Fixed printout of AST that uses pack indexing expression. (#GH116486) - Miscellaneous Bug Fixes ^^^^^^^^^^^^^^^^^^^^^^^ +- HTML tags in comments that span multiple lines are now parsed correctly by Clang's comment parser. (#GH120843) + Miscellaneous Clang Crashes Fixed ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Fixed a crash in C due to incorrect lookup that members in nested anonymous struct/union - can be found as ordinary identifiers in struct/union definition. (#GH31295) - -- Fixed a crash caused by long chains of ``sizeof`` and other similar operators - that can be followed by a non-parenthesized expression. (#GH45061) - -- Fixed an crash when compiling ``#pragma STDC FP_CONTRACT DEFAULT`` with - ``-ffp-contract=fast-honor-pragmas``. (#GH104830) - -- Fixed a crash when function has more than 65536 parameters. - Now a diagnostic is emitted. (#GH35741) - -- Fixed ``-ast-dump`` crashes on codes involving ``concept`` with ``-ast-dump-decl-types``. (#GH94928) - -- Fixed internal assertion firing when a declaration in the implicit global - module is found through ADL. (GH#109879) - -- Fixed a crash when an unscoped enumeration declared by an opaque-enum-declaration within a class template - with a dependent underlying type is subject to integral promotion. (#GH117960) - OpenACC Specific Changes ------------------------ Target Specific Changes ----------------------- -- Clang now implements the Solaris-specific mangling of ``std::tm`` as - ``tm``, same for ``std::div_t``, ``std::ldiv_t``, and - ``std::lconv``, for Solaris ABI compatibility. (#GH33114) - AMDGPU Support ^^^^^^^^^^^^^^ -- Initial support for gfx950 - -- Added headers ``gpuintrin.h`` and ``amdgpuintrin.h`` that contains common - definitions for GPU builtin functions. This header can be included for OpenMP, - CUDA, HIP, OpenCL, and C/C++. - NVPTX Support ^^^^^^^^^^^^^^ -- Added headers ``gpuintrin.h`` and ``nvptxintrin.h`` that contains common - definitions for GPU builtin functions. This header can be included for OpenMP, - CUDA, HIP, OpenCL, and C/C++. +Hexagon Support +^^^^^^^^^^^^^^^ + +- The default compilation target has been changed from V60 to V68. X86 Support ^^^^^^^^^^^ -- The MMX vector intrinsic functions from ``*mmintrin.h`` which - operate on `__m64` vectors, such as ``_mm_add_pi8``, have been - reimplemented to use the SSE2 instruction-set and XMM registers - unconditionally. These intrinsics are therefore *no longer - supported* if MMX is enabled without SSE2 -- either from targeting - CPUs from the Pentium-MMX through the Pentium 3, or explicitly via - passing arguments such as ``-mmmx -mno-sse2``. MMX assembly code - remains supported without requiring SSE2, including inside - inline-assembly. - -- The compiler builtins such as ``__builtin_ia32_paddb`` which - formerly implemented the above MMX intrinsic functions have been - removed. Any uses of these removed functions should migrate to the - functions defined by the ``*mmintrin.h`` headers. A mapping can be - found in the file ``clang/www/builtins.py``. - -- Support ISA of ``AVX10.2``. - * Supported MINMAX intrinsics of ``*_(mask(z)))_minmax(ne)_p[s|d|h|bh]`` and - ``*_(mask(z)))_minmax_s[s|d|h]``. - -- Supported intrinsics for ``SM4 and AVX10.2``. - * Supported SM4 intrinsics of ``_mm512_sm4key4_epi32`` and - ``_mm512_sm4rnds4_epi32``. - -- All intrinsics in adcintrin.h can now be used in constant expressions. - -- All intrinsics in adxintrin.h can now be used in constant expressions. - -- All intrinsics in lzcntintrin.h can now be used in constant expressions. - -- All intrinsics in bmiintrin.h can now be used in constant expressions. - -- All intrinsics in bmi2intrin.h can now be used in constant expressions. - -- All intrinsics in tbmintrin.h can now be used in constant expressions. - -- Supported intrinsics for ``MOVRS AND AVX10.2``. - * Supported intrinsics of ``_mm(256|512)_(mask(z))_loadrs_epi(8|16|32|64)``. -- Support ISA of ``AMX-FP8``. -- Support ISA of ``AMX-TRANSPOSE``. -- Support ISA of ``AMX-MOVRS``. -- Support ISA of ``AMX-AVX512``. -- Support ISA of ``AMX-TF32``. -- Support ISA of ``MOVRS``. - -- Supported ``-march/tune=diamondrapids`` +- Disable ``-m[no-]avx10.1`` and switch ``-m[no-]avx10.2`` to alias of 512 bit + options. +- Change ``-mno-avx10.1-512`` to alias of ``-mno-avx10.1-256`` to disable both + 256 and 512 bit instructions. Arm and AArch64 Support ^^^^^^^^^^^^^^^^^^^^^^^ -- Implementation of SVE2.1 and SME2.1 in accordance with the Arm C Language - Extensions (ACLE) is now available. - -- In the ARM Target, the frame pointer (FP) of a leaf function can be retained - by using the ``-fno-omit-frame-pointer`` option. If you want to eliminate the FP - in leaf functions after enabling ``-fno-omit-frame-pointer``, you can do so by adding - the ``-momit-leaf-frame-pointer`` option. - -- SME keyword attributes which apply to function types are now represented in the - mangling of the type. This means that ``void foo(void (*f)() __arm_streaming);`` - now has a different mangling from ``void foo(void (*f)());``. - -- The ``__arm_agnostic`` keyword attribute was added to let users describe - a function that preserves SME state enabled by PSTATE.ZA without having to share - this state with its callers and without making the assumption that this state - exists. - -- Support has been added for the following processors (-mcpu identifiers in parenthesis): - - For AArch64: - - * FUJITSU-MONAKA (fujitsu-monaka) - Android Support ^^^^^^^^^^^^^^^ Windows Support ^^^^^^^^^^^^^^^ -- clang-cl now supports ``/std:c++23preview`` which enables C++23 features. - -- Clang no longer allows references inside a union when emulating MSVC 1900+ even if `fms-extensions` is enabled. - Starting with VS2015, MSVC 1900, this Microsoft extension is no longer allowed and always results in an error. - Clang now follows the MSVC behavior in this scenario. - When `-fms-compatibility-version=18.00` or prior is set on the command line this Microsoft extension is still - allowed as VS2013 and prior allow it. - -- Clang now supports the ``#pragma clang section`` directive for COFF targets. - LoongArch Support ^^^^^^^^^^^^^^^^^ -- Types of parameters and return value of ``__builtin_lsx_vorn_v`` and ``__builtin_lasx_xvorn_v`` - are changed from ``signed char`` to ``unsigned char``. (#GH114514) - -- ``-mrelax`` and ``-mno-relax`` are supported now on LoongArch that can be used - to enable / disable the linker relaxation optimization. (#GH123587) - -- Fine-grained la64v1.1 options are added including ``-m{no-,}frecipe``, ``-m{no-,}lam-bh``, - ``-m{no-,}ld-seq-sa``, ``-m{no-,}div32``, ``-m{no-,}lamcas`` and ``-m{no-,}scq``. - -- Two options ``-m{no-,}annotate-tablejump`` are added to enable / disable - annotating table jump instruction to correlate it with the jump table. (#GH102411) - -- FreeBSD support is added for LoongArch64 and has been tested by building kernel-toolchain. (#GH119191) - RISC-V Support ^^^^^^^^^^^^^^ -- The option ``-mcmodel=large`` for the large code model is supported. -- Bump RVV intrinsic to version 1.0, the spec: https://github.com/riscv-non-isa/rvv-intrinsic-doc/releases/tag/v1.0.0-rc4 - CUDA/HIP Language Changes ^^^^^^^^^^^^^^^^^^^^^^^^^ -- Fixed a bug about overriding a constexpr pure-virtual member function with a non-constexpr virtual member function which causes compilation failure when including standard C++ header `format`. -- Added initial support for version 3 of the compressed offload bundle format, which uses 64-bit fields for Total File Size and Uncompressed Binary Size. This enables support for files larger than 4GB. The support is currently experimental and can be enabled by setting the environment variable `COMPRESSED_BUNDLE_FORMAT_VERSION=3`. CUDA Support ^^^^^^^^^^^^ -- Clang now supports CUDA SDK up to 12.6 -- Added support for sm_100 -- Added support for `__grid_constant__` attribute. -- CUDA now uses the new offloading driver by default. The new driver supports - device-side LTO, interoperability with OpenMP and other languages, and native ``-fgpu-rdc`` - support with static libraries. The old behavior can be returned using the - ``--no-offload-new-driver`` flag. The binary format is no longer compatible - with the NVIDIA compiler's RDC-mode support. More information can be found at: - https://clang.llvm.org/docs/OffloadingDesign.html AIX Support ^^^^^^^^^^^ @@ -1196,276 +227,73 @@ NetBSD Support WebAssembly Support ^^^^^^^^^^^^^^^^^^^ -The default target CPU, "generic", now enables the `-mnontrapping-fptoint` -and `-mbulk-memory` flags, which correspond to the [Bulk Memory Operations] -and [Non-trapping float-to-int Conversions] language features, which are -[widely implemented in engines]. - -A new Lime1 target CPU is added, -mcpu=lime1. This CPU follows the definition of -the Lime1 CPU [here], and enables -mmultivalue, -mmutable-globals, --mcall-indirect-overlong, -msign-ext, -mbulk-memory-opt, -mnontrapping-fptoint, -and -mextended-const. - -[Bulk Memory Operations]: https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md -[Non-trapping float-to-int Conversions]: https://github.com/WebAssembly/spec/blob/master/proposals/nontrapping-float-to-int-conversion/Overview.md -[widely implemented in engines]: https://webassembly.org/features/ -[here]: https://github.com/WebAssembly/tool-conventions/blob/main/Lime.md#lime1 - AVR Support ^^^^^^^^^^^ -- Reject C/C++ compilation for avr1 devices which have no SRAM. - DWARF Support in Clang ---------------------- Floating Point Support in Clang ------------------------------- -- Add ``__builtin_elementwise_atan2`` builtin for floating point types only. - Fixed Point Support in Clang ---------------------------- AST Matchers ------------ -- Fixed an issue with the `hasName` and `hasAnyName` matcher when matching - inline namespaces with an enclosing namespace of the same name. - -- Fixed an ordering issue with the `hasOperands` matcher occurring when setting a - binding in the first matcher and using it in the second matcher. - -- Fixed a crash when traverse lambda expr with invalid captures. (#GH106444) - -- Fixed ``isInstantiated`` and ``isInTemplateInstantiation`` to also match for variable templates. (#GH110666) - -- Ensure ``hasName`` matches template specializations across inline namespaces, - making `matchesNodeFullSlow` and `matchesNodeFullFast` consistent. - -- Improved the performance of the ``getExpansionLocOfMacro`` by tracking already processed macros during recursion. - -- Add ``exportDecl`` matcher to match export declaration. - -- Ensure ``hasType`` and ``hasDeclaration`` match Objective-C interface declarations. - -- Ensure ``pointee`` matches Objective-C pointer types. - -- Add ``dependentScopeDeclRefExpr`` matcher to match expressions that refer to dependent scope declarations. - -- Add ``dependentNameType`` matcher to match a dependent name type. - -- Add ``dependentTemplateSpecializationType`` matcher to match a dependent template specialization type. - -- Add ``hasDependentName`` matcher to match the dependent name of a DependentScopeDeclRefExpr or DependentNameType. - clang-format ------------ -- Adds ``BreakBinaryOperations`` option. -- Adds ``TemplateNames`` option. -- Adds ``AlignFunctionDeclarations`` option to ``AlignConsecutiveDeclarations``. -- Adds ``IndentOnly`` suboption to ``ReflowComments`` to fix the indentation of - multi-line comments without touching their contents, renames ``false`` to - ``Never``, and ``true`` to ``Always``. -- Adds ``RemoveEmptyLinesInUnwrappedLines`` option. -- Adds ``KeepFormFeed`` option and set it to ``true`` for ``GNU`` style. -- Adds ``AllowShortNamespacesOnASingleLine`` option. -- Adds ``VariableTemplates`` option. -- Adds support for bash globstar in ``.clang-format-ignore``. -- Adds ``WrapNamespaceBodyWithEmptyLines`` option. -- Adds the ``IndentExportBlock`` option. +- Adds ``BreakBeforeTemplateCloser`` option. +- Adds ``BinPackLongBracedList`` option to override bin packing options in + long (20 item or more) braced list initializer lists. libclang -------- -- Add ``clang_isBeforeInTranslationUnit``. Given two source locations, it determines - whether the first one comes strictly before the second in the source code. -- Add ``clang_getTypePrettyPrinted``. It allows controlling the PrintingPolicy used - to pretty-print a type. -- Added ``clang_visitCXXBaseClasses``, which allows visiting the base classes - of a class. -- Added ``clang_getOffsetOfBase``, which allows computing the offset of a base - class in a class's layout. - Code Completion --------------- -- Use ``HeuristicResolver`` (upstreamed from clangd) to improve code completion results - in dependent code - Static Analyzer --------------- New features ^^^^^^^^^^^^ -- Now CSA models `__builtin_*_overflow` functions. (#GH102602) - -- MallocChecker now checks for ``ownership_returns(class, idx)`` and ``ownership_takes(class, idx)`` - attributes with class names different from "malloc". Clang static analyzer now reports an error - if class of allocation and deallocation function mismatches. - `Documentation `__. - -- Function effects, e.g. the ``nonblocking`` and ``nonallocating`` "performance constraint" - attributes, are now verified. For example, for functions declared with the ``nonblocking`` - attribute, the compiler can generate warnings about the use of any language features, or calls to - other functions, which may block. - -- Introduced ``-warning-suppression-mappings`` flag to control diagnostic - suppressions per file. See `documentation _` for details. +A new flag - `-static-libclosure` was introduced to support statically linking +the runtime for the Blocks extension on Windows. This flag currently only +changes the code generation, and even then, only on Windows. This does not +impact the linker behaviour like the other `-static-*` flags. Crash and bug fixes ^^^^^^^^^^^^^^^^^^^ -- In loops where the loop condition is opaque (i.e. the analyzer cannot - determine whether it's true or false), the analyzer will no longer assume - execution paths that perform more that two iterations. These unjustified - assumptions caused false positive reports (e.g. 100+ out-of-bounds reports in - the FFMPEG codebase) in loops where the programmer intended only two or three - steps but the analyzer wasn't able to understand that the loop is limited. - Improvements ^^^^^^^^^^^^ -- Improved the handling of the ``ownership_returns`` attribute. Now, Clang reports an - error if the attribute is attached to a function that returns a non-pointer value. - Fixes (#GH99501) - Moved checkers ^^^^^^^^^^^^^^ -- The checker ``alpha.core.IdenticalExpr`` was deleted because it was - duplicated in the clang-tidy checkers ``misc-redundant-expression`` and - ``bugprone-branch-clone``. - -- The checker ``alpha.security.MallocOverflow`` was deleted because it was - badly implemented and its aggressive logic produced too many false positives. - To detect too large arguments passed to malloc, consider using the checker - ``alpha.taint.TaintedAlloc``. - -- The checkers ``alpha.nondeterministic.PointerSorting`` and - ``alpha.nondeterministic.PointerIteration`` were moved to a new bugprone - checker named ``bugprone-nondeterministic-pointer-iteration-order``. The - original checkers were implemented only using AST matching and make more - sense as a single clang-tidy check. - -- The checker ``alpha.unix.Chroot`` was modernized, improved and moved to - ``unix.Chroot``. Testing was done on open source projects that use chroot(), - and false issues addressed in the improvements based on real use cases. Open - source projects used for testing include nsjail, lxroot, dive and ruri. - This checker conforms to SEI Cert C recommendation `POS05-C. Limit access to - files by creating a jail - `_. - Fixes (#GH34697). - (#GH117791) [Documentation](https://clang.llvm.org/docs/analyzer/checkers.html#unix-chroot-c). +- After lots of improvements, the checker ``alpha.security.ArrayBoundV2`` is + renamed to ``security.ArrayBound``. As this checker is stable now, the old + checker ``alpha.security.ArrayBound`` (which was searching for the same kind + of bugs with an different, simpler and less accurate algorithm) is removed. .. _release-notes-sanitizers: Sanitizers ---------- -- Introduced Realtime Sanitizer, activated by using the -fsanitize=realtime - flag. This sanitizer detects unsafe system library calls, such as memory - allocations and mutex locks. If any such function is called during invocation - of a function marked with the ``[[clang::nonblocking]]`` attribute, an error - is printed to the console and the process exits non-zero. - -- Added the ``-fsanitize-undefined-ignore-overflow-pattern`` flag which can be - used to disable specific overflow-dependent code patterns. The supported - patterns are: ``add-signed-overflow-test``, ``add-unsigned-overflow-test``, - ``negated-unsigned-const``, and ``unsigned-post-decr-while``. The sanitizer - instrumentation can be toggled off for all available patterns by specifying - ``all``. Conversely, you may disable all exclusions with ``none`` which is - the default. - - .. code-block:: c++ - - /// specified with ``-fsanitize-undefined-ignore-overflow-pattern=add-unsigned-overflow-test`` - int common_overflow_check_pattern(unsigned base, unsigned offset) { - if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, won't be instrumented - } - - /// specified with ``-fsanitize-undefined-ignore-overflow-pattern=add-signed-overflow-test`` - int common_overflow_check_pattern_signed(signed int base, signed int offset) { - if (base + offset < base) { /* ... */ } // The pattern of `a + b < a`, and other re-orderings, won't be instrumented - } - - /// specified with ``-fsanitize-undefined-ignore-overflow-pattern=negated-unsigned-const`` - void negation_overflow() { - unsigned long foo = -1UL; // No longer causes a negation overflow warning - unsigned long bar = -2UL; // and so on... - } - - /// specified with ``-fsanitize-undefined-ignore-overflow-pattern=unsigned-post-decr-while`` - void while_post_decrement() { - unsigned char count = 16; - while (count--) { /* ... */ } // No longer causes unsigned-integer-overflow sanitizer to trip - } - - Many existing projects have a large amount of these code patterns present. - This new flag should allow those projects to enable integer sanitizers with - less noise. - -- ``-fsanitize=signed-integer-overflow``, ``-fsanitize=unsigned-integer-overflow``, - ``-fsanitize=implicit-signed-integer-truncation``, ``-fsanitize=implicit-unsigned-integer-truncation``, - ``-fsanitize=enum`` now properly support the - "type" prefix within `Sanitizer Special Case Lists (SSCL) - `_. See that link - for examples. - -- Introduced an experimental Type Sanitizer, activated by using the - ``-fsanitize=type`` flag. This sanitizer detects violations of C/C++ type-based - aliasing rules. - -- Implemented ``-f[no-]sanitize-trap=local-bounds``, and ``-f[no-]sanitize-recover=local-bounds``. - -- ``-fsanitize-merge`` (default) and ``-fno-sanitize-merge`` have been added for - fine-grained, unified control of which UBSan checks can potentially be merged - by the compiler (for example, - ``-fno-sanitize-merge=bool,enum,array-bounds,local-bounds``). - -- Changed ``-fsanitize=pointer-overflow`` to no longer report ``NULL + 0`` as - undefined behavior in C, in line with - `N3322 `_, - and matching the previous behavior for C++. - ``NULL + non_zero`` continues to be reported as undefined behavior. Python Binding Changes ---------------------- -- Fixed an issue that led to crashes when calling ``Type.get_exception_specification_kind``. -- Added ``Cursor.pretty_printed``, a binding for ``clang_getCursorPrettyPrinted``, - and related functions, which allow changing the formatting of pretty-printed code. -- Added ``Cursor.is_anonymous_record_decl``, a binding for - ``clang_Cursor_isAnonymousRecordDecl``, which allows checking if a - declaration is an anonymous union or anonymous struct. -- Added ``Type.pretty_printed`, a binding for ``clang_getTypePrettyPrinted``, - which allows changing the formatting of pretty-printed types. -- Added ``Cursor.is_virtual_base``, a binding for ``clang_isVirtualBase``, - which checks whether a base class is virtual. -- Added ``Type.get_bases``, a binding for ``clang_visitCXXBaseClasses``, which - allows visiting the base classes of a class. -- Added ``Cursor.get_base_offsetof``, a binding for ``clang_getOffsetOfBase``, - which allows computing the offset of a base class in a class's layout. OpenMP Support -------------- -- Added support for 'omp assume' directive. -- Added support for 'omp scope' directive. -- Added support for allocator-modifier in 'allocate' clause. -- Changed the OpenMP DeviceRTL to use 'generic' IR. The - ``LIBOMPTARGET_DEVICE_ARCHITECTURES`` CMake argument is now unused and will - always build support for AMDGPU and NVPTX targets. -- Added support for combined masked constructs 'omp parallel masked taskloop', - 'omp parallel masked taskloop simd','omp masked taskloop' and 'omp masked taskloop simd' directive. -- Added support for align-modifier in 'allocate' clause. +- Added support 'no_openmp_constructs' assumption clause. Improvements ^^^^^^^^^^^^ -- Improve the handling of mapping array-section for struct containing nested structs with user defined mappers - -- `num_teams` and `thead_limit` now accept multiple expressions when it is used - along in ``target teams ompx_bare`` construct. This allows the target region - to be launched with multi-dim grid on GPUs. Additional Information ====================== diff --git a/clang/docs/SourceBasedCodeCoverage.rst b/clang/docs/SourceBasedCodeCoverage.rst index 73910e134a589..3e8642479a56d 100644 --- a/clang/docs/SourceBasedCodeCoverage.rst +++ b/clang/docs/SourceBasedCodeCoverage.rst @@ -94,6 +94,11 @@ directory structure will be created. Additionally, the following special not specified (i.e the pattern is "%m"), it's assumed that ``N = 1``. The merge pool specifier can only occur once per filename pattern. +* "%b" expands out to the binary ID (build ID). It can be used with "%Nm" to + avoid binary signature collisions. To use it, the program should be compiled + with the build ID linker option (``--build-id`` for GNU ld or LLD, + ``/build-id`` for lld-link on Windows). Linux, Windows and AIX are supported. + * "%c" expands out to nothing, but enables a mode in which profile counter updates are continuously synced to a file. This means that if the instrumented program crashes, or is killed by a signal, perfect coverage diff --git a/clang/docs/TypeSanitizer.rst b/clang/docs/TypeSanitizer.rst new file mode 100644 index 0000000000000..3c683a6c24bb4 --- /dev/null +++ b/clang/docs/TypeSanitizer.rst @@ -0,0 +1,205 @@ +============= +TypeSanitizer +============= + +.. contents:: + :local: + +Introduction +============ + +The TypeSanitizer is a detector for strict type aliasing violations. It consists of a compiler +instrumentation module and a run-time library. C/C++ has type-based aliasing rules, and LLVM +can exploit these for optimizations given the TBAA metadata Clang emits. In general, a pointer +of a given type cannot access an object of a different type, with only a few exceptions. + +These rules aren't always apparent to users, which leads to code that violates these rules +(e.g. for type punning). This can lead to optimization passes introducing bugs unless the +code is build with ``-fno-strict-aliasing``, sacrificing performance. + +TypeSanitizer is built to catch when these strict aliasing rules have been violated, helping +users find where such bugs originate in their code despite the code looking valid at first glance. + +As TypeSanitizer is still experimental, it can currently have a large impact on runtime speed, +memory use, and code size. It also has a large compile-time overhead. Work is being done to +reduce these impacts. + +The TypeSanitizer Algorithm +=========================== +For each TBAA type-access descriptor, encoded in LLVM IR using TBAA Metadata, the instrumentation +pass generates descriptor tables. Thus there is a unique pointer to each type (and access descriptor). +These tables are comdat (except for anonymous-namespace types), so the pointer values are unique +across the program. + +The descriptors refer to other descriptors to form a type aliasing tree, like how LLVM's TBAA data +does. + +The runtime uses 8 bytes of shadow memory, the size of the pointer to the type descriptor, for +every byte of accessed data in the program. The first byte of a type will have its shadow memory +be set to the pointer to its type descriptor. Aside from that, there are some other values it may be. + +* 0 is used to represent an unknown type +* Negative numbers represent an interior byte: A byte inside a type that is not the first one. As an + example, a value of -2 means you are in the third byte of a type. + +The Instrumentation first checks for an exact match between the type of the current access and the +type for that address in the shadow memory. This can quickly be done by checking pointer values. If +it matches, it checks the remaining shadow memory of the type to ensure they are the correct negative +numbers. If this fails, it calls the "slow path" check. If the exact match fails, we check to see if +the value, and the remainder of the shadow bytes, is 0. If they are, we can set the shadow memory to +the correct type descriptor pointer for the first byte, and the correct negative numbers for the rest +of the type's shadow. + +If the type in shadow memory is neither an exact match nor 0, we call the slower runtime check. It +uses the full TBAA algorithm, just as the compiler does, to determine when two types are permitted to +alias. + +The instrumentation pass inserts calls to the memset intrinsic to set the memory updated by memset, +memcpy, and memmove, as well as allocas/byval (and for lifetime.start/end) to reset the shadow memory +to reflect that the type is now unknown. The runtime intercepts memset, memcpy, etc. to perform the +same function for the library calls. + +How to build +============ + +Build LLVM/Clang with `CMake `_ and enable +the ``compiler-rt`` runtime. An example CMake configuration that will allow +for the use/testing of TypeSanitizer: + +.. code-block:: console + + $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="compiler-rt" /llvm + +Usage +===== + +Compile and link your program with ``-fsanitize=type`` flag. The +TypeSanitizer run-time library should be linked to the final executable, so +make sure to use ``clang`` (not ``ld``) for the final link step. To +get a reasonable performance add ``-O1`` or higher. +TypeSanitizer by default doesn't print the full stack trace in error messages. Use ``TYSAN_OPTIONS=print_stacktrace=1`` +to print the full trace. To get nicer stack traces in error messages add ``-fno-omit-frame-pointer`` and +``-g``. To get perfect stack traces you may need to disable inlining (just use ``-O1``) and tail call elimination +(``-fno-optimize-sibling-calls``). + +.. code-block:: console + + % cat example_AliasViolation.c + int main(int argc, char **argv) { + int x = 100; + float *y = (float*)&x; + *y += 2.0f; // Strict aliasing violation + return 0; + } + + # Compile and link + % clang++ -g -fsanitize=type example_AliasViolation.cc + +The program will print an error message to ``stderr`` each time a strict aliasing violation is detected. +The program won't terminate, which will allow you to detect many strict aliasing violations in one +run. + +.. code-block:: console + + % ./a.out + ==1375532==ERROR: TypeSanitizer: type-aliasing-violation on address 0x7ffeebf1a72c (pc 0x5b3b1145ff41 bp 0x7ffeebf1a660 sp 0x7ffeebf19e08 tid 1375532) + READ of size 4 at 0x7ffeebf1a72c with type float accesses an existing object of type int + #0 0x5b3b1145ff40 in main example_AliasViolation.c:4:10 + + ==1375532==ERROR: TypeSanitizer: type-aliasing-violation on address 0x7ffeebf1a72c (pc 0x5b3b1146008a bp 0x7ffeebf1a660 sp 0x7ffeebf19e08 tid 1375532) + WRITE of size 4 at 0x7ffeebf1a72c with type float accesses an existing object of type int + #0 0x5b3b11460089 in main example_AliasViolation.c:4:10 + +Error terminology +------------------ + +There are some terms that may appear in TypeSanitizer errors that are derived from +`TBAA Metadata `. This section hopes to provide a +brief dictionary of these terms. + +* ``omnipotent char``: This is a special type which can alias with anything. Its name comes from the C/C++ + type ``char``. +* ``type p[x]``: This signifies pointers to the type. ``x`` is the number of indirections to reach the final value. + As an example, a pointer to a pointer to an integer would be ``type p2 int``. + +TypeSanitizer is still experimental. User-facing error messages should be improved in the future to remove +references to LLVM IR specific terms. + +Sanitizer features +================== + +``__has_feature(type_sanitizer)`` +------------------------------------ + +In some cases one may need to execute different code depending on whether +TypeSanitizer is enabled. +:ref:`\_\_has\_feature ` can be used for +this purpose. + +.. code-block:: c + + #if defined(__has_feature) + # if __has_feature(type_sanitizer) + // code that builds only under TypeSanitizer + # endif + #endif + +``__attribute__((no_sanitize("type")))`` +----------------------------------------------- + +Some code you may not want to be instrumented by TypeSanitizer. One may use the +function attribute ``no_sanitize("type")`` to disable instrumenting type aliasing. +It is possible, depending on what happens in non-instrumented code, that instrumented code +emits false-positives/ false-negatives. This attribute may not be supported by other +compilers, so we suggest to use it together with ``__has_feature(type_sanitizer)``. + +``__attribute__((disable_sanitizer_instrumentation))`` +-------------------------------------------------------- + +The ``disable_sanitizer_instrumentation`` attribute can be applied to functions +to prevent all kinds of instrumentation. As a result, it may introduce false +positives and incorrect stack traces. Therefore, it should be used with care, +and only if absolutely required; for example for certain code that cannot +tolerate any instrumentation and resulting side-effects. This attribute +overrides ``no_sanitize("type")``. + +Ignorelist +---------- + +TypeSanitizer supports ``src`` and ``fun`` entity types in +:doc:`SanitizerSpecialCaseList`, that can be used to suppress aliasing +violation reports in the specified source files or functions. Like +with other methods of ignoring instrumentation, this can result in false +positives/ false-negatives. + +Limitations +----------- + +* TypeSanitizer uses more real memory than a native run. It uses 8 bytes of + shadow memory for each byte of user memory. +* There are transformation passes which run before TypeSanitizer. If these + passes optimize out an aliasing violation, TypeSanitizer cannot catch it. +* Currently, all instrumentation is inlined. This can result in a **15x** + (on average) increase in generated file size, and **3x** to **7x** increase + in compile time. In some documented cases this can cause the compiler to hang. + There are plans to improve this in the future. +* Codebases that use unions and struct-initialized variables can see incorrect + results, as TypeSanitizer doesn't yet instrument these reliably. +* Since Clang & LLVM's TBAA system is used to generate the checks used by the + instrumentation, TypeSanitizer follows Clang & LLVM's rules for type aliasing. + There may be situations where that disagrees with the standard. However this + does at least mean that TypeSanitizer will catch any aliasing violations that + would cause bugs when compiling with Clang & LLVM. +* TypeSanitizer cannot currently be run alongside other sanitizers such as + AddressSanitizer, ThreadSanitizer or UndefinedBehaviourSanitizer. + +Current Status +-------------- + +TypeSanitizer is brand new, and still in development. There are some known +issues, especially in areas where Clang's emitted TBAA data isn't extensive +enough for TypeSanitizer's runtime. + +We are actively working on enhancing the tool --- stay tuned. Any help, +issues, pull requests, ideas, is more than welcome. You can find the +`issue tracker here. `_ diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 260e84910c6f7..d977868b8a2c6 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -2103,7 +2103,10 @@ are listed below. ``-fsanitize=undefined``: :doc:`UndefinedBehaviorSanitizer`, a fast and compatible undefined behavior checker. + - .. _opt_fsanitize_type: + ``-fsanitize=type``: :doc:`TypeSanitizer`, a detector for strict + aliasing violations. - ``-fsanitize=dataflow``: :doc:`DataFlowSanitizer`, a general data flow analysis. - ``-fsanitize=cfi``: :doc:`control flow integrity ` @@ -2220,6 +2223,12 @@ are listed below. This option is currently experimental. +.. option:: -fsanitize-kcfi-arity + + Extends kernel indirect call forward-edge control flow integrity with + additional function arity information (for supported targets). See + :doc:`ControlFlowIntegrity` for more details. + .. option:: -fstrict-vtable-pointers Enable optimizations based on the strict rules for overwriting polymorphic @@ -2486,6 +2495,82 @@ are listed below. $ clang -fuse-ld=lld -Oz -Wl,--icf=safe -fcodegen-data-use code.cc +.. _strict_aliasing: + +Strict Aliasing +--------------- + +The C and C++ standards require accesses to objects in memory to use l-values of +an appropriate type for the object. This is called *strict aliasing* or +*type-based alias analysis*. Strict aliasing enhances a variety of powerful +memory optimizations, including reordering, combining, and eliminating memory +accesses. These optimizations can lead to unexpected behavior in code that +violates the strict aliasing rules. For example: + +.. code-block:: c++ + + void advance(size_t *index, double *data) { + double value = data[*index]; + /* Clang may assume that this store does not change the contents of `data`. */ + *index += 1; + /* Clang may assume that this store does not change the contents of `index`. */ + data[*index] = value; + /* Either of these facts may create significant optimization opportunities + if Clang is able to inline this function. */ + } + +Strict aliasing can be explicitly enabled with ``-fstrict-aliasing`` and +disabled with ``-fno-strict-aliasing``. ``clang-cl`` defaults to +``-fno-strict-aliasing``; see . Otherwise, Clang defaults to ``-fstrict-aliasing``. + +C and C++ specify slightly different rules for strict aliasing. To improve +language interoperability, Clang allows two types to alias if either language +would permit it. This includes applying the C++ similar types rule to C, +allowing ``int **`` to alias ``int const * const *``. Clang also relaxes the +standard aliasing rules in the following ways: + +* All integer types of the same size are permitted to alias each other, + including signed and unsigned types. +* ``void*`` is permitted to alias any pointer type, ``void**`` is permitted to + alias any pointer to pointer type, and so on. + +Code which violates strict aliasing has undefined behavior. A program that +works in one version of Clang may not work in another because of changes to the +optimizer. Clang provides a :doc:`TypeSanitizer` to help detect +violations of the strict aliasing rules, but it is currently still experimental. +Code that is known to violate strict aliasing should generally be built with +``-fno-strict-aliasing`` if the violation cannot be fixed. + +Clang supports several ways to fix a violation of strict aliasing: + +* L-values of the character types ``char`` and ``unsigned char`` (as well as + other types, depending on the standard) are permitted to access objects of + any type. + +* Library functions such as ``memcpy`` and ``memset`` are specified as treating + memory as characters and therefore are not limited by strict aliasing. If a + value of one type must be reinterpreted as another (e.g. to read the bits of a + floating-point number), use ``memcpy`` to copy the representation to an object + of the destination type. This has no overhead over a direct l-value access + because Clang should reliably optimize calls to these functions to use simple + loads and stores when they are used with small constant sizes. + +* The attribute ``may_alias`` can be added to a ``typedef`` to give l-values of + that type the same aliasing power as the character types. + +Clang makes a best effort to avoid obvious miscompilations from strict aliasing +by only considering type information when it cannot prove that two accesses must +refer to the same memory. However, it is not recommended that programmers +intentionally rely on this instead of using one of the solutions above because +it is too easy for the compiler's analysis to be blocked in surprising ways. + +In Clang 20, Clang strengthened its implementation of strict aliasing for +accesses of pointer type. Previously, all accesses of pointer type were +permitted to alias each other, but Clang now distinguishes different pointers +by their pointee type, except as limited by the relaxations around qualifiers +and ``void*`` described above. The previous behavior of treating all pointers as +aliasing can be restored using ``-fno-pointer-tbaa``. + Profile Guided Optimization --------------------------- @@ -2880,7 +2965,8 @@ instrumentation: environment variable to specify an alternate file. If non-default file name is specified by both the environment variable and the command line option, the environment variable takes precedence. The file name pattern specified - can include different modifiers: ``%p``, ``%h``, ``%m``, ``%t``, and ``%c``. + can include different modifiers: ``%p``, ``%h``, ``%m``, ``%b``, ``%t``, and + ``%c``. Any instance of ``%p`` in that file name will be replaced by the process ID, so that you can easily distinguish the profile output from multiple @@ -2902,11 +2988,11 @@ instrumentation: ``%p`` is that the storage requirement for raw profile data files is greatly increased. To avoid issues like this, the ``%m`` specifier can used in the profile name. When this specifier is used, the profiler runtime will substitute ``%m`` - with a unique integer identifier associated with the instrumented binary. Additionally, + with an integer identifier associated with the instrumented binary. Additionally, multiple raw profiles dumped from different processes that share a file system (can be on different hosts) will be automatically merged by the profiler runtime during the dumping. If the program links in multiple instrumented shared libraries, each library - will dump the profile data into its own profile data file (with its unique integer + will dump the profile data into its own profile data file (with its integer id embedded in the profile name). Note that the merging enabled by ``%m`` is for raw profile data generated by profiler runtime. The resulting merged "raw" profile data file still needs to be converted to a different format expected by the compiler ( @@ -2916,6 +3002,12 @@ instrumentation: $ LLVM_PROFILE_FILE="code-%m.profraw" ./code + Although rare, binary signatures used by the ``%m`` specifier can have + collisions. In this case, the ``%b`` specifier, which expands to the binary + ID (build ID in ELF and COFF), can be added. To use it, the program should be + compiled with the build ID linker option (``--build-id`` for GNU ld or LLD, + ``/build-id`` for lld-link on Windows). Linux, Windows and AIX are supported. + See `this `_ section about the ``%t``, and ``%c`` modifiers. @@ -3033,6 +3125,24 @@ indexed format, regardeless whether it is produced by frontend or the IR pass. overhead. ``prefer-atomic`` will be transformed to ``atomic`` when supported by the target, or ``single`` otherwise. +.. option:: -fprofile-continuous + + Enables the continuous instrumentation profiling where profile counter updates + are continuously synced to a file. This option sets any neccessary modifiers + (currently ``%c``) in the default profile filename and passes any necessary + flags to the middle-end to support this mode. Value profiling is not supported + in continuous mode. + + .. code-block:: console + + $ clang++ -O2 -fprofile-generate -fprofile-continuous code.cc -o code + + Running ``./code`` will collect the profile and write it to the + ``default_xxxx.profraw`` file. However, if ``./code`` abruptly terminates or + does not call ``exit()``, in continuous mode the profile collected up to the + point of termination will be available in ``default_xxxx.profraw`` while in + the non-continuous mode, no profile file is generated. + .. option:: -ftemporal-profile Enables the temporal profiling extension for IRPGO to improve startup time by @@ -5269,12 +5379,6 @@ The Visual C++ Toolset has a slightly more elaborate mechanism for detection. Restrictions and Limitations compared to Clang ---------------------------------------------- -Strict Aliasing -^^^^^^^^^^^^^^^ - -Strict aliasing (TBAA) is always off by default in clang-cl. Whereas in clang, -strict aliasing is turned on by default for all optimization levels. - -To enable LLVM optimizations based on strict aliasing rules (e.g., optimizations -based on type of expressions in C/C++), user will need to explicitly pass -`-fstrict-aliasing` to clang-cl. +Strict aliasing (TBAA) is always off by default in clang-cl whereas in clang, +strict aliasing is turned on by default for all optimization levels. For more +details, see :ref:`Strict aliasing `. diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index e093b2d672a74..707067358fdfe 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -1332,10 +1332,69 @@ security Security related checkers. +.. _security-ArrayBound: + +security.ArrayBound (C, C++) +"""""""""""""""""""""""""""" +Report out of bounds access to memory that is before the start or after the end +of the accessed region (array, heap-allocated region, string literal etc.). +This usually means incorrect indexing, but the checker also detects access via +the operators ``*`` and ``->``. + +.. code-block:: c + + void test_underflow(int x) { + int buf[100][100]; + if (x < 0) + buf[0][x] = 1; // warn + } + + void test_overflow() { + int buf[100]; + int *p = buf + 100; + *p = 1; // warn + } + +If checkers like :ref:`unix-Malloc` or :ref:`cplusplus-NewDelete` are enabled +to model the behavior of ``malloc()``, ``operator new`` and similar +allocators), then this checker can also reports out of bounds access to +dynamically allocated memory: + +.. code-block:: cpp + + int *test_dynamic() { + int *mem = new int[100]; + mem[-1] = 42; // warn + return mem; + } + +In uncertain situations (when the checker can neither prove nor disprove that +overflow occurs), the checker assumes that the the index (more precisely, the +memory offeset) is within bounds. + +However, if :ref:`optin-taint-GenericTaint` is enabled and the index/offset is +tainted (i.e. it is influenced by an untrusted souce), then this checker +reports the potential out of bounds access: + +.. code-block:: c + + void test_with_tainted_index() { + char s[] = "abc"; + int x = getchar(); + char c = s[x]; // warn: potential out of bounds access with tainted index + } + +.. note:: + + This checker is an improved and renamed version of the checker that was + previously known as ``alpha.security.ArrayBoundV2``. The old checker + ``alpha.security.ArrayBound`` was removed when the (previously + "experimental") V2 variant became stable enough for regular use. + .. _security-cert-env-InvalidPtr: security.cert.env.InvalidPtr -"""""""""""""""""""""""""""""""""" +"""""""""""""""""""""""""""" Corresponds to SEI CERT Rules `ENV31-C `_ and `ENV34-C `_. @@ -3216,78 +3275,6 @@ Warns against using one vs. many plural pattern in code when generating localize alpha.security ^^^^^^^^^^^^^^ -.. _alpha-security-ArrayBound: - -alpha.security.ArrayBound (C) -""""""""""""""""""""""""""""" -Warn about buffer overflows (older checker). - -.. code-block:: c - - void test() { - char *s = ""; - char c = s[1]; // warn - } - - struct seven_words { - int c[7]; - }; - - void test() { - struct seven_words a, *p; - p = &a; - p[0] = a; - p[1] = a; - p[2] = a; // warn - } - - // note: requires unix.Malloc or - // alpha.unix.MallocWithAnnotations checks enabled. - void test() { - int *p = malloc(12); - p[3] = 4; // warn - } - - void test() { - char a[2]; - int *b = (int*)a; - b[1] = 3; // warn - } - -.. _alpha-security-ArrayBoundV2: - -alpha.security.ArrayBoundV2 (C) -""""""""""""""""""""""""""""""" -Warn about buffer overflows (newer checker). - -.. code-block:: c - - void test() { - char *s = ""; - char c = s[1]; // warn - } - - void test() { - int buf[100]; - int *p = buf; - p = p + 99; - p[1] = 1; // warn - } - - // note: compiler has internal check for this. - // Use -Wno-array-bounds to suppress compiler warning. - void test() { - int buf[100][100]; - buf[0][-1] = 1; // warn - } - - // note: requires optin.taint check turned on. - void test() { - char s[] = "abc"; - int x = getchar(); - char c = s[x]; // warn: index is tainted - } - .. _alpha-security-ReturnPtrRange: alpha.security.ReturnPtrRange (C) diff --git a/clang/docs/analyzer/developer-docs.rst b/clang/docs/analyzer/developer-docs.rst index 1b8133ffa8920..60c0e71ad847c 100644 --- a/clang/docs/analyzer/developer-docs.rst +++ b/clang/docs/analyzer/developer-docs.rst @@ -11,3 +11,4 @@ Contents: developer-docs/InitializerLists developer-docs/nullability developer-docs/RegionStore + developer-docs/PerformanceInvestigation diff --git a/clang/docs/analyzer/developer-docs/PerformanceInvestigation.rst b/clang/docs/analyzer/developer-docs/PerformanceInvestigation.rst new file mode 100644 index 0000000000000..ca3a56828209b --- /dev/null +++ b/clang/docs/analyzer/developer-docs/PerformanceInvestigation.rst @@ -0,0 +1,137 @@ +========================= +Performance Investigation +========================= + +Multiple factors contribute to the time it takes to analyze a file with Clang Static Analyzer. +A translation unit contains multiple entry points, each of which take multiple steps to analyze. + +Performance analysis using ``-ftime-trace`` +=========================================== + +You can add the ``-ftime-trace=file.json`` option to break down the analysis time into individual entry points and steps within each entry point. +You can explore the generated JSON file in a Chromium browser using the ``chrome://tracing`` URL, +or using `speedscope `_. +Once you narrow down to specific analysis steps you are interested in, you can more effectively employ heavier profilers, +such as `Perf `_ and `Callgrind `_. + +Each analysis step has a time scope in the trace, corresponds to processing of an exploded node, and is designated with a ``ProgramPoint``. +If the ``ProgramPoint`` is associated with a location, you can see it on the scope metadata label. + +Here is an example of a time trace produced with + +.. code-block:: bash + :caption: Clang Static Analyzer invocation to generate a time trace of string.c analysis. + + clang -cc1 -analyze -verify clang/test/Analysis/string.c \ + -analyzer-checker=core,unix,alpha.unix.cstring,debug.ExprInspection \ + -ftime-trace=trace.json -ftime-trace-granularity=1 + +.. image:: ../images/speedscope.png + +On the speedscope screenshot above, under the first time ruler is the bird's-eye view of the entire trace that spans a little over 60 milliseconds. +Under the second ruler (focused on the 18.09-18.13ms time point) you can see a narrowed-down portion. +The second box ("HandleCode memset...") that spans entire screen (and actually extends beyond it) corresponds to the analysis of ``memset16_region_cast()`` entry point that is defined in the "string.c" test file on line 1627. +Below it, you can find multiple sub-scopes each corresponding to processing of a single exploded node. + +- First: a ``PostStmt`` for some statement on line 1634. This scope has a selected subscope "CheckerManager::runCheckersForCallEvent (Pre)" that takes 5 microseconds. +- Four other nodes, too small to be discernible at this zoom level +- Last on this screenshot: another ``PostStmt`` for a statement on line 1635. + +In addition to the ``-ftime-trace`` option, you can use ``-ftime-trace-granularity`` to fine-tune the time trace. + +- ``-ftime-trace-granularity=NN`` dumps only time scopes that are longer than NN microseconds. +- ``-ftime-trace-verbose`` enables some additional dumps in the frontend related to template instantiations. + At the moment, it has no effect on the traces from the static analyzer. + +Note: Both Chrome-tracing and speedscope tools might struggle with time traces above 100 MB in size. +Luckily, in most cases the default max-steps boundary of 225 000 produces the traces of approximately that size +for a single entry point. +You can use ``-analyze-function=get_global_options`` together with ``-ftime-trace`` to narrow down analysis to a specific entry point. + + +Performance analysis using ``perf`` +=================================== + +`Perf `_ is a tool for conducting sampling-based profiling. +It's easy to start profiling, you only have 2 prerequisites. +Build with ``-fno-omit-frame-pointer`` and debug info (``-g``). +You can use release builds, but probably the easiest is to set the ``CMAKE_BUILD_TYPE=RelWithDebInfo`` +along with ``CMAKE_CXX_FLAGS="-fno-omit-frame-pointer"`` when configuring ``llvm``. +Here is how to `get started `_ if you are in trouble. + +.. code-block:: bash + :caption: Running the Clang Static Analyzer through ``perf`` to gather samples of the execution. + + # -F: Sampling frequency, use `-F max` for maximal frequency + # -g: Enable call-graph recording for both kernel and user space + perf record -F 99 -g -- clang -cc1 -analyze -verify clang/test/Analysis/string.c \ + -analyzer-checker=core,unix,alpha.unix.cstring,debug.ExprInspection + +Once you have the profile data, you can use it to produce a Flame graph. +A Flame graph is a visual representation of the stack frames of the samples. +Common stack frame prefixes are squashed together, making up a wider bar. +The wider the bar, the more time was spent under that particular stack frame, +giving a sense of how the overall execution time was spent. + +Clone the `FlameGraph `_ git repository, +as we will use some scripts from there to convert the ``perf`` samples into a Flame graph. +It's also useful to check out Brendan Gregg's (the author of FlameGraph) +`homepage `_. + + +.. code-block:: bash + :caption: Converting the ``perf`` profile into a Flamegraph, then opening it in Firefox. + + perf script | /path/to/FlameGraph/stackcollapse-perf.pl > perf.folded + /path/to/FlameGraph/flamegraph.pl perf.folded > perf.svg + firefox perf.svg + +.. image:: ../images/flamegraph.png + + +Performance analysis using ``uftrace`` +====================================== + +`uftrace `_ is a great tool to generate rich profile data +that you can use to focus and drill down into the timeline of your application. +We will use it to generate Chromium trace JSON. +In contrast to ``perf``, this approach statically instruments every function, so it should be more precise and thorough than the sampling-based approaches like ``perf``. +In contrast to using ``-ftime-trace``, functions don't need to opt-in to be profiled using ``llvm::TimeTraceScope``. +All functions are profiled due to automatic static instrumentation. + +There is only one prerequisite to use this tool. +You need to build the binary you are about to instrument using ``-pg`` or ``-finstrument-functions``. +This will make it run substantially slower but allows rich instrumentation. +It will also consume many gigabites of storage for a single trace unless filter flags are used during recording. + +.. code-block:: bash + :caption: Recording with ``uftrace``, then dumping the result as a Chrome trace JSON. + + uftrace record clang -cc1 -analyze -verify clang/test/Analysis/string.c \ + -analyzer-checker=core,unix,alpha.unix.cstring,debug.ExprInspection + uftrace dump --filter=".*::AnalysisConsumer::HandleTranslationUnit" --time-filter=300 --chrome > trace.json + +.. image:: ../images/uftrace_detailed.png + +In this picture, you can see the functions below the Static Analyzer's entry point, which takes at least 300 nanoseconds to run, visualized by Chrome's ``about:tracing`` page +You can also see how deep function calls we may have due to AST visitors. + +Using different filters can reduce the number of functions to record. +For the common options, refer to the ``uftrace`` `documentation `_. + +Similar filters can be applied for dumping too. That way you can reuse the same (detailed) +recording to selectively focus on some special part using a refinement of the filter flags. +Remember, the trace JSON needs to fit into Chrome's ``about:tracing`` or `speedscope `_, +thus it needs to be of a limited size. +If you do not apply filters on recording, you will collect a large trace and every dump operation +would need to sieve through the much larger recording which may be annoying if done repeatedly. + +If the trace JSON is still too large to load, have a look at the dump as plain text and look for frequent entries that refer to non-interesting parts. +Once you have some of those, add them as ``--hide`` flags to the ``uftrace dump`` call. +To see what functions appear frequently in the trace, use this command: + +.. code-block:: bash + + cat trace.json | grep -Po '"name":"(.+)"' | sort | uniq -c | sort -nr | head -n 50 + +``uftrace`` can also dump the report as a Flame graph using ``uftrace dump --framegraph``. diff --git a/clang/docs/analyzer/images/flamegraph.png b/clang/docs/analyzer/images/flamegraph.png new file mode 100644 index 0000000000000..b16ec90b9e600 Binary files /dev/null and b/clang/docs/analyzer/images/flamegraph.png differ diff --git a/clang/docs/analyzer/images/speedscope.png b/clang/docs/analyzer/images/speedscope.png new file mode 100644 index 0000000000000..767725d68f740 Binary files /dev/null and b/clang/docs/analyzer/images/speedscope.png differ diff --git a/clang/docs/analyzer/images/uftrace_detailed.png b/clang/docs/analyzer/images/uftrace_detailed.png new file mode 100644 index 0000000000000..fcf681909d070 Binary files /dev/null and b/clang/docs/analyzer/images/uftrace_detailed.png differ diff --git a/clang/docs/analyzer/user-docs/Annotations.rst b/clang/docs/analyzer/user-docs/Annotations.rst index d87e8f4df99c3..11f15939ecfaf 100644 --- a/clang/docs/analyzer/user-docs/Annotations.rst +++ b/clang/docs/analyzer/user-docs/Annotations.rst @@ -23,8 +23,8 @@ recognized by GCC. Their use can be conditioned using preprocessor macros .. contents:: :local: -Annotations to Enhance Generic Checks -_____________________________________ +General Purpose Annotations +___________________________ Null Pointer Checking ##################### @@ -79,7 +79,7 @@ implemented with a macro, with the macro performing a check for the assertion condition and, when the check fails, calling an assertion handler. For example, consider the following code fragment: -.. code-block: c +.. code-block:: c void foo(int *p) { assert(p != NULL); @@ -87,7 +87,7 @@ example, consider the following code fragment: When this code is preprocessed on Mac OS X it expands to the following: -.. code-block: c +.. code-block:: c void foo(int *p) { (__builtin_expect(!(p != NULL), 0) ? __assert_rtn(__func__, "t.c", 4, "p != NULL") : (void)0); @@ -131,7 +131,7 @@ return. On Mac OS X, the function prototype for ``__assert_rtn`` (declared in ``assert.h``) is specifically annotated with the 'noreturn' attribute: -.. code-block: c +.. code-block:: c void __assert_rtn(const char *, const char *, int, const char *) __attribute__((__noreturn__)); @@ -151,7 +151,7 @@ the use of preprocessor macros. **Example** -.. code-block: c +.. code-block:: c #ifndef CLANG_ANALYZER_NORETURN #if __has_feature(attribute_analyzer_noreturn) @@ -163,6 +163,43 @@ the use of preprocessor macros. void my_assert_rtn(const char *, const char *, int, const char *) CLANG_ANALYZER_NORETURN; +Dynamic Memory Modeling Annotations +################################### + +If a project uses custom functions for dynamic memory management (that e.g. act as wrappers around ``malloc``/``free`` or ``new``/``delete`` in C++) and the analyzer cannot "see" the _definitions_ of these functions, it's possible to annotate their declarations to let the analyzer model their behavior. (Otherwise the analyzer cannot know that the opaque ``my_free()`` is basically equivalent to a standard ``free()`` call.) + +.. note:: + **This page only provides a brief list of these annotations.** For a full documentation, see the main `Attributes in Clang <../../AttributeReference.html#ownership-holds-ownership-returns-ownership-takes-clang-static-analyzer>`_ page. + +Attribute 'ownership_returns' (Clang-specific) +---------------------------------------------- + +Use this attribute to mark functions that return dynamically allocated memory. Takes a single argument, the type of the allocation (e.g. ``malloc`` or ``new``). + +.. code-block:: c + + void __attribute((ownership_returns(malloc))) *my_malloc(size_t); + +Attribute 'ownership_takes' (Clang-specific) +-------------------------------------------- + +Use this attribute to mark functions that deallocate memory. Takes two arguments: the type of the allocation (e.g. ``malloc`` or ``new``) and the index of the parameter that is being deallocated (counting from 1). + +.. code-block:: c + + void __attribute((ownership_takes(malloc, 1))) my_free(void *); + +Attribute 'ownership_holds' (Clang-specific) +-------------------------------------------- + +Use this attribute to mark functions that take ownership of memory and will deallocate it at some unspecified point in the future. Takes two arguments: the type of the allocation (e.g. ``malloc`` or ``new``) and the index of the parameter that is being held (counting from 1). + +.. code-block:: c + + void __attribute((ownership_holds(malloc, 2))) store_in_table(int key, record_t *val); + +The annotations ``ownership_takes`` and ``ownership_holds`` both prevent memory leak reports (concerning the specified argument); the difference between them is that using taken memory is a use-after-free error, while using held memory is assumed to be legitimate. + Mac OS X API Annotations ________________________ @@ -207,7 +244,7 @@ functions allows the analyzer to perform extra checking. **Example** -.. code-block: objc +.. code-block:: objc #import ; @@ -597,7 +634,6 @@ returned object. LIBKERN_RETURNS_NOT_RETAINED OSObject *myFieldGetter(); } - // Note that the annotation only has to be applied to the function declaration. OSObject * MyClass::myFieldGetter() { return f; diff --git a/clang/docs/index.rst b/clang/docs/index.rst index 349378b1efa21..6c792af66a62c 100644 --- a/clang/docs/index.rst +++ b/clang/docs/index.rst @@ -35,6 +35,7 @@ Using Clang as a Compiler UndefinedBehaviorSanitizer DataFlowSanitizer LeakSanitizer + TypeSanitizer RealtimeSanitizer SanitizerCoverage SanitizerStats diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index aac5d1fa8aa2e..61e361faabdaf 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2206,7 +2206,11 @@ enum CXCursorKind { */ CXCursor_OpenACCUpdateConstruct = 331, - CXCursor_LastStmt = CXCursor_OpenACCUpdateConstruct, + /** OpenACC atomic Construct. + */ + CXCursor_OpenACCAtomicConstruct = 332, + + CXCursor_LastStmt = CXCursor_OpenACCAtomicConstruct, /** * Cursor that represents the translation unit itself. @@ -5905,66 +5909,6 @@ CINDEX_LINKAGE const char *clang_EvalResult_getAsStr(CXEvalResult E); * Disposes the created Eval memory. */ CINDEX_LINKAGE void clang_EvalResult_dispose(CXEvalResult E); -/** - * @} - */ - -/** \defgroup CINDEX_REMAPPING Remapping functions - * - * @{ - */ - -/** - * A remapping of original source files and their translated files. - */ -typedef void *CXRemapping; - -/** - * Retrieve a remapping. - * - * \param path the path that contains metadata about remappings. - * - * \returns the requested remapping. This remapping must be freed - * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred. - */ -CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path); - -/** - * Retrieve a remapping. - * - * \param filePaths pointer to an array of file paths containing remapping info. - * - * \param numFiles number of file paths. - * - * \returns the requested remapping. This remapping must be freed - * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred. - */ -CINDEX_LINKAGE -CXRemapping clang_getRemappingsFromFileList(const char **filePaths, - unsigned numFiles); - -/** - * Determine the number of remappings. - */ -CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping); - -/** - * Get the original and the associated filename from the remapping. - * - * \param original If non-NULL, will be set to the original filename. - * - * \param transformed If non-NULL, will be set to the filename that the original - * is associated with. - */ -CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index, - CXString *original, - CXString *transformed); - -/** - * Dispose the remapping. - */ -CINDEX_LINKAGE void clang_remap_dispose(CXRemapping); - /** * @} */ diff --git a/clang/include/clang/ARCMigrate/ARCMT.h b/clang/include/clang/ARCMigrate/ARCMT.h deleted file mode 100644 index 2b950e3d2cc2b..0000000000000 --- a/clang/include/clang/ARCMigrate/ARCMT.h +++ /dev/null @@ -1,130 +0,0 @@ -//===-- ARCMT.h - ARC Migration Rewriter ------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ARCMIGRATE_ARCMT_H -#define LLVM_CLANG_ARCMIGRATE_ARCMT_H - -#include "clang/ARCMigrate/FileRemapper.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Frontend/CompilerInvocation.h" - -namespace clang { - class ASTContext; - class DiagnosticConsumer; - class PCHContainerOperations; - -namespace arcmt { - class MigrationPass; - -/// Creates an AST with the provided CompilerInvocation but with these -/// changes: -/// -if a PCH/PTH is set, the original header is used instead -/// -Automatic Reference Counting mode is enabled -/// -/// It then checks the AST and produces errors/warning for ARC migration issues -/// that the user needs to handle manually. -/// -/// \param emitPremigrationARCErrors if true all ARC errors will get emitted -/// even if the migrator can fix them, but the function will still return false -/// if all ARC errors can be fixed. -/// -/// \param plistOut if non-empty, it is the file path to store the plist with -/// the pre-migration ARC diagnostics. -/// -/// \returns false if no error is produced, true otherwise. -bool -checkForManualIssues(CompilerInvocation &CI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, - bool emitPremigrationARCErrors = false, - StringRef plistOut = StringRef()); - -/// Works similar to checkForManualIssues but instead of checking, it -/// applies automatic modifications to source files to conform to ARC. -/// -/// \returns false if no error is produced, true otherwise. -bool -applyTransformations(CompilerInvocation &origCI, - const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient); - -/// Applies automatic modifications and produces temporary files -/// and metadata into the \p outputDir path. -/// -/// \param emitPremigrationARCErrors if true all ARC errors will get emitted -/// even if the migrator can fix them, but the function will still return false -/// if all ARC errors can be fixed. -/// -/// \param plistOut if non-empty, it is the file path to store the plist with -/// the pre-migration ARC diagnostics. -/// -/// \returns false if no error is produced, true otherwise. -bool migrateWithTemporaryFiles( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, StringRef outputDir, - bool emitPremigrationARCErrors, StringRef plistOut); - -/// Get the set of file remappings from the \p outputDir path that -/// migrateWithTemporaryFiles produced. -/// -/// \returns false if no error is produced, true otherwise. -bool getFileRemappings(std::vector > &remap, - StringRef outputDir, - DiagnosticConsumer *DiagClient); - -/// Get the set of file remappings from a list of files with remapping -/// info. -/// -/// \returns false if no error is produced, true otherwise. -bool getFileRemappingsFromFileList( - std::vector > &remap, - ArrayRef remapFiles, - DiagnosticConsumer *DiagClient); - -typedef void (*TransformFn)(MigrationPass &pass); - -std::vector getAllTransformations(LangOptions::GCMode OrigGCMode, - bool NoFinalizeRemoval); - -class MigrationProcess { - CompilerInvocation OrigCI; - std::shared_ptr PCHContainerOps; - DiagnosticConsumer *DiagClient; - FileRemapper Remapper; - -public: - bool HadARCErrors; - - MigrationProcess(CompilerInvocation &CI, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *diagClient, - StringRef outputDir = StringRef()); - - class RewriteListener { - public: - virtual ~RewriteListener(); - - virtual void start(ASTContext &Ctx) { } - virtual void finish() { } - - virtual void insert(SourceLocation loc, StringRef text) { } - virtual void remove(CharSourceRange range) { } - }; - - bool applyTransform(TransformFn trans, RewriteListener *listener = nullptr); - - FileRemapper &getRemapper() { return Remapper; } -}; - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/include/clang/ARCMigrate/ARCMTActions.h b/clang/include/clang/ARCMigrate/ARCMTActions.h deleted file mode 100644 index 714f4b33db446..0000000000000 --- a/clang/include/clang/ARCMigrate/ARCMTActions.h +++ /dev/null @@ -1,76 +0,0 @@ -//===--- ARCMTActions.h - ARC Migrate Tool Frontend Actions -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H -#define LLVM_CLANG_ARCMIGRATE_ARCMTACTIONS_H - -#include "clang/ARCMigrate/FileRemapper.h" -#include "clang/Frontend/FrontendAction.h" -#include - -namespace clang { -namespace arcmt { - -class CheckAction : public WrapperFrontendAction { -protected: - bool BeginInvocation(CompilerInstance &CI) override; - -public: - CheckAction(std::unique_ptr WrappedAction); -}; - -class ModifyAction : public WrapperFrontendAction { -protected: - bool BeginInvocation(CompilerInstance &CI) override; - -public: - ModifyAction(std::unique_ptr WrappedAction); -}; - -class MigrateSourceAction : public ASTFrontendAction { - FileRemapper Remapper; -protected: - bool BeginInvocation(CompilerInstance &CI) override; - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; -}; - -class MigrateAction : public WrapperFrontendAction { - std::string MigrateDir; - std::string PlistOut; - bool EmitPremigrationARCErrors; -protected: - bool BeginInvocation(CompilerInstance &CI) override; - -public: - MigrateAction(std::unique_ptr WrappedAction, - StringRef migrateDir, - StringRef plistOut, - bool emitPremigrationARCErrors); -}; - -/// Migrates to modern ObjC syntax. -class ObjCMigrateAction : public WrapperFrontendAction { - std::string MigrateDir; - unsigned ObjCMigAction; - FileRemapper Remapper; - CompilerInstance *CompInst; -public: - ObjCMigrateAction(std::unique_ptr WrappedAction, - StringRef migrateDir, unsigned migrateAction); - -protected: - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override; - bool BeginInvocation(CompilerInstance &CI) override; -}; - -} -} - -#endif diff --git a/clang/include/clang/ARCMigrate/FileRemapper.h b/clang/include/clang/ARCMigrate/FileRemapper.h deleted file mode 100644 index afcee363516a2..0000000000000 --- a/clang/include/clang/ARCMigrate/FileRemapper.h +++ /dev/null @@ -1,84 +0,0 @@ -//===-- FileRemapper.h - File Remapping Helper ------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H -#define LLVM_CLANG_ARCMIGRATE_FILEREMAPPER_H - -#include "clang/Basic/FileEntry.h" -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.h" -#include -#include - -namespace llvm { - class MemoryBuffer; - class MemoryBufferRef; -} - -namespace clang { - class FileManager; - class DiagnosticsEngine; - class PreprocessorOptions; - -namespace arcmt { - -class FileRemapper { - // FIXME: Reuse the same FileManager for multiple ASTContexts. - std::unique_ptr FileMgr; - - using Target = std::variant; - using MappingsTy = llvm::DenseMap; - MappingsTy FromToMappings; - - llvm::DenseMap ToFromMappings; - -public: - FileRemapper(); - ~FileRemapper(); - - bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged); - bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged); - bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag); - bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag); - - bool overwriteOriginal(DiagnosticsEngine &Diag, - StringRef outputDir = StringRef()); - - void remap(StringRef filePath, std::unique_ptr memBuf); - - void applyMappings(PreprocessorOptions &PPOpts) const; - - /// Iterate through all the mappings. - void forEachMapping( - llvm::function_ref CaptureFile, - llvm::function_ref - CaptureBuffer) const; - - void clear(StringRef outputDir = StringRef()); - -private: - void remap(FileEntryRef file, std::unique_ptr memBuf); - void remap(FileEntryRef file, FileEntryRef newfile); - - OptionalFileEntryRef getOriginalFile(StringRef filePath); - void resetTarget(Target &targ); - - bool report(const Twine &err, DiagnosticsEngine &Diag); - - std::string getRemapInfoFile(StringRef outputDir); -}; - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 833a78c77871d..9999a30c51ade 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -161,8 +161,9 @@ class APValue { template T get() const { return cast(Ptr); } - template - T dyn_cast() const { return Ptr.dyn_cast(); } + template T dyn_cast() const { + return dyn_cast_if_present(Ptr); + } void *getOpaqueValue() const; diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 4e9b961688d55..a96b9c0a17045 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -769,7 +769,7 @@ class ASTContext : public RefCountedBase { /// pool. DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) { if (DeclListNode *Alloc = ListNodeFreeList) { - ListNodeFreeList = Alloc->Rest.dyn_cast(); + ListNodeFreeList = dyn_cast_if_present(Alloc->Rest); Alloc->D = ND; Alloc->Rest = nullptr; return Alloc; @@ -1733,6 +1733,47 @@ class ASTContext : public RefCountedBase { unsigned NumPositiveBits, QualType &BestType, QualType &BestPromotionType); + /// Determine whether the given integral value is representable within + /// the given type T. + bool isRepresentableIntegerValue(llvm::APSInt &Value, QualType T); + + /// Compute NumNegativeBits and NumPositiveBits for an enum based on + /// the constant values of its enumerators. + template + bool computeEnumBits(RangeT EnumConstants, unsigned &NumNegativeBits, + unsigned &NumPositiveBits) { + NumNegativeBits = 0; + NumPositiveBits = 0; + bool MembersRepresentableByInt = true; + for (auto *Elem : EnumConstants) { + EnumConstantDecl *ECD = cast_or_null(Elem); + if (!ECD) + continue; // Already issued a diagnostic. + + llvm::APSInt InitVal = ECD->getInitVal(); + if (InitVal.isUnsigned() || InitVal.isNonNegative()) { + // If the enumerator is zero that should still be counted as a positive + // bit since we need a bit to store the value zero. + unsigned ActiveBits = InitVal.getActiveBits(); + NumPositiveBits = std::max({NumPositiveBits, ActiveBits, 1u}); + } else { + NumNegativeBits = + std::max(NumNegativeBits, (unsigned)InitVal.getSignificantBits()); + } + + MembersRepresentableByInt &= isRepresentableIntegerValue(InitVal, IntTy); + } + + // If we have an empty set of enumerators we still need one bit. + // From [dcl.enum]p8 + // If the enumerator-list is empty, the values of the enumeration are as if + // the enumeration had a single enumerator with value 0 + if (!NumPositiveBits && !NumNegativeBits) + NumPositiveBits = 1; + + return MembersRepresentableByInt; + } + QualType getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const; diff --git a/clang/include/clang/AST/ASTLambda.h b/clang/include/clang/AST/ASTLambda.h index 646cb574847fe..a1854b6a1a949 100644 --- a/clang/include/clang/AST/ASTLambda.h +++ b/clang/include/clang/AST/ASTLambda.h @@ -17,6 +17,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" +#include "llvm/Support/Casting.h" namespace clang { inline StringRef getLambdaStaticInvokerName() { @@ -35,6 +36,12 @@ inline bool isLambdaCallOperator(const DeclContext *DC) { return isLambdaCallOperator(cast(DC)); } +inline bool isLambdaMethod(const DeclContext *DC) { + if (const auto *MD = dyn_cast_if_present(DC)) + return MD->getParent()->isLambda(); + return false; +} + inline bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC) { return isLambdaCallOperator(DC) && cast(DC)->isExplicitObjectMemberFunction(); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index d01681483a918..f305cbbce4c60 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -698,6 +698,10 @@ class ValueDecl : public NamedDecl { return const_cast(this)->getPotentiallyDecomposedVarDecl(); } + /// Determine whether this value is actually a function parameter pack, + /// init-capture pack, or structured binding pack + bool isParameterPack() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstValue && K <= lastValue; } @@ -1527,10 +1531,6 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { NonParmVarDeclBits.IsInitCapture = IC; } - /// Determine whether this variable is actually a function parameter pack or - /// init-capture pack. - bool isParameterPack() const; - /// Whether this local extern variable declaration's previous declaration /// was declared in the same block scope. Only correct in C++. bool isPreviousDeclInSameBlockScope() const { @@ -2298,6 +2298,13 @@ class FunctionDecl : public DeclaratorDecl, FunctionDeclBits.IsLateTemplateParsed = ILT; } + bool isInstantiatedFromMemberTemplate() const { + return FunctionDeclBits.IsInstantiatedFromMemberTemplate; + } + void setInstantiatedFromMemberTemplate(bool Val = true) { + FunctionDeclBits.IsInstantiatedFromMemberTemplate = Val; + } + /// Whether this function is "trivial" in some specialized C++ senses. /// Can only be true for default constructors, copy constructors, /// copy assignment operators, and destructors. Not meaningful until @@ -4035,7 +4042,7 @@ class EnumDecl : public TagDecl { /// Return the type source info for the underlying integer type, /// if no type source info exists, return 0. TypeSourceInfo *getIntegerTypeSourceInfo() const { - return IntegerType.dyn_cast(); + return dyn_cast_if_present(IntegerType); } /// Retrieve the source range that covers the underlying type if @@ -5139,6 +5146,12 @@ static constexpr StringRef getOpenMPVariantManglingSeparatorStr() { bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming); +/// Returns whether the given FunctionDecl has Arm ZA state. +bool hasArmZAState(const FunctionDecl *FD); + +/// Returns whether the given FunctionDecl has Arm ZT0 state. +bool hasArmZT0State(const FunctionDecl *FD); + } // namespace clang #endif // LLVM_CLANG_AST_DECL_H diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 573b46a2321c5..648dae2838e03 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -1257,8 +1257,11 @@ class alignas(8) Decl { int64_t getID() const; /// Looks through the Decl's underlying type to extract a FunctionType - /// when possible. Will return null if the type underlying the Decl does not - /// have a FunctionType. + /// when possible. This includes direct FunctionDecls, along with various + /// function types and typedefs. This includes function pointers/references, + /// member function pointers, and optionally if \p BlocksToo is set + /// Objective-C block pointers. Returns nullptr if the type underlying the + /// Decl does not have a FunctionType. const FunctionType *getFunctionType(bool BlocksToo = true) const; // Looks through the Decl's underlying type to determine if it's a @@ -1391,7 +1394,7 @@ class DeclContextLookupResult { const_iterator end() const { return iterator(); } bool empty() const { return Result.isNull(); } - bool isSingleResult() const { return Result.dyn_cast(); } + bool isSingleResult() const { return isa_and_present(Result); } reference front() const { return *begin(); } // Find the first declaration of the given type in the list. Note that this @@ -1777,6 +1780,8 @@ class DeclContext { uint64_t HasImplicitReturnZero : 1; LLVM_PREFERRED_TYPE(bool) uint64_t IsLateTemplateParsed : 1; + LLVM_PREFERRED_TYPE(bool) + uint64_t IsInstantiatedFromMemberTemplate : 1; /// Kind of contexpr specifier as defined by ConstexprSpecKind. LLVM_PREFERRED_TYPE(ConstexprSpecKind) @@ -1827,7 +1832,7 @@ class DeclContext { }; /// Number of inherited and non-inherited bits in FunctionDeclBitfields. - enum { NumFunctionDeclBits = NumDeclContextBits + 31 }; + enum { NumFunctionDeclBits = NumDeclContextBits + 32 }; /// Stores the bits used by CXXConstructorDecl. If modified /// NumCXXConstructorDeclBits and the accessor @@ -1838,12 +1843,12 @@ class DeclContext { LLVM_PREFERRED_TYPE(FunctionDeclBitfields) uint64_t : NumFunctionDeclBits; - /// 20 bits to fit in the remaining available space. + /// 19 bits to fit in the remaining available space. /// Note that this makes CXXConstructorDeclBitfields take /// exactly 64 bits and thus the width of NumCtorInitializers /// will need to be shrunk if some bit is added to NumDeclContextBitfields, /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. - uint64_t NumCtorInitializers : 17; + uint64_t NumCtorInitializers : 16; LLVM_PREFERRED_TYPE(bool) uint64_t IsInheritingConstructor : 1; @@ -1857,7 +1862,7 @@ class DeclContext { }; /// Number of inherited and non-inherited bits in CXXConstructorDeclBitfields. - enum { NumCXXConstructorDeclBits = NumFunctionDeclBits + 20 }; + enum { NumCXXConstructorDeclBits = NumFunctionDeclBits + 19 }; /// Stores the bits used by ObjCMethodDecl. /// If modified NumObjCMethodDeclBits and the accessor diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index fa3f4ec98eb36..766821b4fb25c 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1967,17 +1967,29 @@ class ExplicitSpecifier { class CXXDeductionGuideDecl : public FunctionDecl { void anchor() override; +public: + // Represents the relationship between this deduction guide and the + // deduction guide that it was generated from (or lack thereof). + // See the SourceDeductionGuide member for more details. + enum class SourceDeductionGuideKind : uint8_t { + None, + Alias, + }; + private: CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor, DeductionCandidate Kind, - Expr *TrailingRequiresClause) + Expr *TrailingRequiresClause, + const CXXDeductionGuideDecl *GeneratedFrom, + SourceDeductionGuideKind SourceKind) : FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo, SC_None, false, false, ConstexprSpecKind::Unspecified, TrailingRequiresClause), - Ctor(Ctor), ExplicitSpec(ES) { + Ctor(Ctor), ExplicitSpec(ES), + SourceDeductionGuide(GeneratedFrom, SourceKind) { if (EndLocation.isValid()) setRangeEnd(EndLocation); setDeductionCandidateKind(Kind); @@ -1985,6 +1997,12 @@ class CXXDeductionGuideDecl : public FunctionDecl { CXXConstructorDecl *Ctor; ExplicitSpecifier ExplicitSpec; + // The deduction guide, if any, that this deduction guide was generated from, + // in the case of alias template deduction. The SourceDeductionGuideKind + // member indicates which of these sources applies, or is None otherwise. + llvm::PointerIntPair + SourceDeductionGuide; void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } public: @@ -1997,7 +2015,9 @@ class CXXDeductionGuideDecl : public FunctionDecl { TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal, - Expr *TrailingRequiresClause = nullptr); + Expr *TrailingRequiresClause = nullptr, + const CXXDeductionGuideDecl *SourceDG = nullptr, + SourceDeductionGuideKind SK = SourceDeductionGuideKind::None); static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); @@ -2017,6 +2037,25 @@ class CXXDeductionGuideDecl : public FunctionDecl { /// this is an implicit deduction guide. CXXConstructorDecl *getCorrespondingConstructor() const { return Ctor; } + /// Get the deduction guide from which this deduction guide was generated, + /// if it was generated as part of alias template deduction or from an + /// inherited constructor. + const CXXDeductionGuideDecl *getSourceDeductionGuide() const { + return SourceDeductionGuide.getPointer(); + } + + void setSourceDeductionGuide(CXXDeductionGuideDecl *DG) { + SourceDeductionGuide.setPointer(DG); + } + + SourceDeductionGuideKind getSourceDeductionGuideKind() const { + return SourceDeductionGuide.getInt(); + } + + void setSourceDeductionGuideKind(SourceDeductionGuideKind SK) { + SourceDeductionGuide.setInt(SK); + } + void setDeductionCandidateKind(DeductionCandidate K) { FunctionDeclBits.DeductionCandidateKind = static_cast(K); } @@ -4136,8 +4175,9 @@ class BindingDecl : public ValueDecl { /// binding). Expr *Binding = nullptr; - BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id) - : ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()) {} + BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, + QualType T) + : ValueDecl(Decl::Binding, DC, IdLoc, Id, T) {} void anchor() override; @@ -4145,7 +4185,8 @@ class BindingDecl : public ValueDecl { friend class ASTDeclReader; static BindingDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation IdLoc, IdentifierInfo *Id); + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T); static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Get the expression to which this declaration is bound. This may be null @@ -4153,14 +4194,13 @@ class BindingDecl : public ValueDecl { /// decomposition declaration, and when the initializer is type-dependent. Expr *getBinding() const { return Binding; } + // Get the array of Exprs when the binding represents a pack. + llvm::ArrayRef getBindingPackExprs() const; + /// Get the decomposition declaration that this binding represents a /// decomposition of. ValueDecl *getDecomposedDecl() const { return Decomp; } - /// Get the variable (if any) that holds the value of evaluating the binding. - /// Only present for user-defined bindings for tuple-like types. - VarDecl *getHoldingVar() const; - /// Set the binding for this BindingDecl, along with its declared type (which /// should be a possibly-cv-qualified form of the type of the binding, or a /// reference to such a type). @@ -4172,6 +4212,10 @@ class BindingDecl : public ValueDecl { /// Set the decomposed variable for this BindingDecl. void setDecomposedDecl(ValueDecl *Decomposed) { Decomp = Decomposed; } + /// Get the variable (if any) that holds the value of evaluating the binding. + /// Only present for user-defined bindings for tuple-like types. + VarDecl *getHoldingVar() const; + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::Binding; } }; @@ -4199,8 +4243,16 @@ class DecompositionDecl final NumBindings(Bindings.size()) { std::uninitialized_copy(Bindings.begin(), Bindings.end(), getTrailingObjects()); - for (auto *B : Bindings) + for (auto *B : Bindings) { B->setDecomposedDecl(this); + if (B->isParameterPack() && B->getBinding()) { + for (Expr *E : B->getBindingPackExprs()) { + auto *DRE = cast(E); + auto *NestedB = cast(DRE->getDecl()); + NestedB->setDecomposedDecl(this); + } + } + } } void anchor() override; @@ -4218,8 +4270,33 @@ class DecompositionDecl final static DecompositionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumBindings); - ArrayRef bindings() const { - return llvm::ArrayRef(getTrailingObjects(), NumBindings); + // Provide the range of bindings which may have a nested pack. + llvm::ArrayRef bindings() const { + return {getTrailingObjects(), NumBindings}; + } + + // Provide a flattened range to visit each binding. + auto flat_bindings() const { + llvm::ArrayRef Bindings = bindings(); + llvm::ArrayRef PackExprs; + + // Split the bindings into subranges split by the pack. + auto S1 = Bindings.take_until( + [](BindingDecl *BD) { return BD->isParameterPack(); }); + + Bindings = Bindings.drop_front(S1.size()); + if (!Bindings.empty()) { + PackExprs = Bindings.front()->getBindingPackExprs(); + Bindings = Bindings.drop_front(); + } + + auto S2 = llvm::map_range(PackExprs, [](Expr *E) { + auto *DRE = cast(E); + return cast(DRE->getDecl()); + }); + + return llvm::concat(std::move(S1), std::move(S2), + std::move(Bindings)); } void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 8c2da97c07a3b..b82f75dd63fa5 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1011,6 +1011,26 @@ class FunctionTemplateDecl : public RedeclarableTemplateDecl { return getTemplatedDecl()->isThisDeclarationADefinition(); } + bool isCompatibleWithDefinition() const { + return getTemplatedDecl()->isInstantiatedFromMemberTemplate() || + isThisDeclarationADefinition(); + } + + // This bit closely tracks 'RedeclarableTemplateDecl::InstantiatedFromMember', + // except this is per declaration, while the redeclarable field is + // per chain. This indicates a template redeclaration which + // is compatible with the definition, in the non-trivial case + // where this is not already a definition. + // This is only really needed for instantiating the definition of friend + // function templates, which can have redeclarations in different template + // contexts. + // The bit is actually stored in the FunctionDecl for space efficiency + // reasons. + void setInstantiatedFromMemberTemplate(FunctionTemplateDecl *D) { + getTemplatedDecl()->setInstantiatedFromMemberTemplate(); + RedeclarableTemplateDecl::setInstantiatedFromMemberTemplate(D); + } + /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. FunctionDecl *findSpecialization(ArrayRef Args, @@ -1841,15 +1861,23 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, LLVM_PREFERRED_TYPE(TemplateSpecializationKind) unsigned SpecializationKind : 3; + /// Indicate that we have matched a parameter pack with a non pack + /// argument, when the opposite match is also allowed. + /// This needs to be cached as deduction is performed during declaration, + /// and we need the information to be preserved so that it is consistent + /// during instantiation. + bool StrictPackMatch : 1; + protected: ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, + bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl); - explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK); + ClassTemplateSpecializationDecl(ASTContext &C, Kind DK); public: friend class ASTDeclReader; @@ -1859,7 +1887,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, - ArrayRef Args, + ArrayRef Args, bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl); static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); @@ -1930,6 +1958,10 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, SpecializationKind = TSK; } + bool hasStrictPackMatch() const { return StrictPackMatch; } + + void setStrictPackMatch(bool Val) { StrictPackMatch = Val; } + /// Get the point of instantiation (if any), or null if none. SourceLocation getPointOfInstantiation() const { return PointOfInstantiation; @@ -2009,7 +2041,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// Retrieve the template argument list as written in the sources, /// if any. const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) return Info->TemplateArgsAsWritten; return cast(ExplicitInfo); } @@ -2017,7 +2050,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// Set the template argument list as written in the sources. void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) Info->TemplateArgsAsWritten = ArgsWritten; else ExplicitInfo = ArgsWritten; @@ -2031,7 +2065,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// Gets the location of the extern keyword, if present. SourceLocation getExternKeywordLoc() const { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) return Info->ExternKeywordLoc; return SourceLocation(); } @@ -2041,7 +2076,8 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// Gets the location of the template keyword, if present. SourceLocation getTemplateKeywordLoc() const { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) return Info->TemplateKeywordLoc; return SourceLocation(); } @@ -2778,7 +2814,8 @@ class VarTemplateSpecializationDecl : public VarDecl, /// Retrieve the template argument list as written in the sources, /// if any. const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) return Info->TemplateArgsAsWritten; return cast(ExplicitInfo); } @@ -2786,7 +2823,8 @@ class VarTemplateSpecializationDecl : public VarDecl, /// Set the template argument list as written in the sources. void setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) Info->TemplateArgsAsWritten = ArgsWritten; else ExplicitInfo = ArgsWritten; @@ -2800,7 +2838,8 @@ class VarTemplateSpecializationDecl : public VarDecl, /// Gets the location of the extern keyword, if present. SourceLocation getExternKeywordLoc() const { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) return Info->ExternKeywordLoc; return SourceLocation(); } @@ -2810,7 +2849,8 @@ class VarTemplateSpecializationDecl : public VarDecl, /// Gets the location of the template keyword, if present. SourceLocation getTemplateKeywordLoc() const { - if (auto *Info = ExplicitInfo.dyn_cast()) + if (auto *Info = + dyn_cast_if_present(ExplicitInfo)) return Info->TemplateKeywordLoc; return SourceLocation(); } diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h index 4382d20990829..703cca22777ad 100644 --- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h +++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h @@ -52,7 +52,11 @@ class ASTContext; /// WalkUpFromX or post-order traversal). /// /// \see RecursiveASTVisitor. -class DynamicRecursiveASTVisitor { +template class DynamicRecursiveASTVisitorBase { +protected: + template + using MaybeConst = std::conditional_t; + public: /// Whether this visitor should recurse into template instantiations. bool ShouldVisitTemplateInstantiations = false; @@ -68,28 +72,29 @@ class DynamicRecursiveASTVisitor { bool ShouldVisitLambdaBody = true; protected: - DynamicRecursiveASTVisitor() = default; - DynamicRecursiveASTVisitor(DynamicRecursiveASTVisitor &&) = default; - DynamicRecursiveASTVisitor(const DynamicRecursiveASTVisitor &) = default; - DynamicRecursiveASTVisitor & - operator=(DynamicRecursiveASTVisitor &&) = default; - DynamicRecursiveASTVisitor & - operator=(const DynamicRecursiveASTVisitor &) = default; + DynamicRecursiveASTVisitorBase() = default; + DynamicRecursiveASTVisitorBase(DynamicRecursiveASTVisitorBase &&) = default; + DynamicRecursiveASTVisitorBase(const DynamicRecursiveASTVisitorBase &) = + default; + DynamicRecursiveASTVisitorBase & + operator=(DynamicRecursiveASTVisitorBase &&) = default; + DynamicRecursiveASTVisitorBase & + operator=(const DynamicRecursiveASTVisitorBase &) = default; public: virtual void anchor(); - virtual ~DynamicRecursiveASTVisitor() = default; + virtual ~DynamicRecursiveASTVisitorBase() = default; /// Recursively visits an entire AST, starting from the TranslationUnitDecl. /// \returns false if visitation was terminated early. - virtual bool TraverseAST(ASTContext &AST); + virtual bool TraverseAST(MaybeConst &AST); /// Recursively visit an attribute, by dispatching to /// Traverse*Attr() based on the argument's dynamic type. /// /// \returns false if the visitation was terminated early, true /// otherwise (including when the argument is a Null type location). - virtual bool TraverseAttr(Attr *At); + virtual bool TraverseAttr(MaybeConst *At); /// Recursively visit a constructor initializer. This /// automatically dispatches to another visitor for the initializer @@ -97,7 +102,8 @@ class DynamicRecursiveASTVisitor { /// be overridden for clients that need access to the name. /// /// \returns false if the visitation was terminated early, true otherwise. - virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init); + virtual bool + TraverseConstructorInitializer(MaybeConst *Init); /// Recursively visit a base specifier. This can be overridden by a /// subclass. @@ -110,7 +116,7 @@ class DynamicRecursiveASTVisitor { /// /// \returns false if the visitation was terminated early, true /// otherwise (including when the argument is NULL). - virtual bool TraverseDecl(Decl *D); + virtual bool TraverseDecl(MaybeConst *D); /// Recursively visit a name with its location information. /// @@ -121,13 +127,15 @@ class DynamicRecursiveASTVisitor { /// will be used to initialize the capture. /// /// \returns false if the visitation was terminated early, true otherwise. - virtual bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, - Expr *Init); + virtual bool TraverseLambdaCapture(MaybeConst *LE, + const LambdaCapture *C, + MaybeConst *Init); /// Recursively visit a C++ nested-name-specifier. /// /// \returns false if the visitation was terminated early, true otherwise. - virtual bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); + virtual bool + TraverseNestedNameSpecifier(MaybeConst *NNS); /// Recursively visit a C++ nested-name-specifier with location /// information. @@ -140,7 +148,7 @@ class DynamicRecursiveASTVisitor { /// /// \returns false if the visitation was terminated early, true /// otherwise (including when the argument is nullptr). - virtual bool TraverseStmt(Stmt *S); + virtual bool TraverseStmt(MaybeConst *S); /// Recursively visit a template argument and dispatch to the /// appropriate method for the argument type. @@ -190,41 +198,51 @@ class DynamicRecursiveASTVisitor { /// Traverse a concept (requirement). virtual bool TraverseTypeConstraint(const TypeConstraint *C); - virtual bool TraverseConceptRequirement(concepts::Requirement *R); - virtual bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R); - virtual bool TraverseConceptExprRequirement(concepts::ExprRequirement *R); - virtual bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R); - virtual bool TraverseConceptReference(ConceptReference *CR); - virtual bool VisitConceptReference(ConceptReference *CR) { return true; } + virtual bool TraverseConceptRequirement(MaybeConst *R); + + virtual bool + TraverseConceptTypeRequirement(MaybeConst *R); + + virtual bool + TraverseConceptExprRequirement(MaybeConst *R); + + virtual bool + TraverseConceptNestedRequirement(MaybeConst *R); + + virtual bool TraverseConceptReference(MaybeConst *CR); + virtual bool VisitConceptReference(MaybeConst *CR) { + return true; + } /// Visit a node. - virtual bool VisitAttr(Attr *A) { return true; } - virtual bool VisitDecl(Decl *D) { return true; } - virtual bool VisitStmt(Stmt *S) { return true; } - virtual bool VisitType(Type *T) { return true; } + virtual bool VisitAttr(MaybeConst *A) { return true; } + virtual bool VisitDecl(MaybeConst *D) { return true; } + virtual bool VisitStmt(MaybeConst *S) { return true; } + virtual bool VisitType(MaybeConst *T) { return true; } virtual bool VisitTypeLoc(TypeLoc TL) { return true; } /// Walk up from a node. - bool WalkUpFromDecl(Decl *D) { return VisitDecl(D); } - bool WalkUpFromStmt(Stmt *S) { return VisitStmt(S); } - bool WalkUpFromType(Type *T) { return VisitType(T); } + bool WalkUpFromDecl(MaybeConst *D) { return VisitDecl(D); } + bool WalkUpFromStmt(MaybeConst *S) { return VisitStmt(S); } + bool WalkUpFromType(MaybeConst *T) { return VisitType(T); } bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); } /// Invoked before visiting a statement or expression via data recursion. /// /// \returns false to skip visiting the node, true otherwise. - virtual bool dataTraverseStmtPre(Stmt *S) { return true; } + virtual bool dataTraverseStmtPre(MaybeConst *S) { return true; } /// Invoked after visiting a statement or expression via data recursion. /// This is not invoked if the previously invoked \c dataTraverseStmtPre /// returned false. /// /// \returns false if the visitation was terminated early, true otherwise. - virtual bool dataTraverseStmtPost(Stmt *S) { return true; } - virtual bool dataTraverseNode(Stmt *S); + virtual bool dataTraverseStmtPost(MaybeConst *S) { return true; } + virtual bool dataTraverseNode(MaybeConst *S); #define DEF_TRAVERSE_TMPL_INST(kind) \ - virtual bool TraverseTemplateInstantiations(kind##TemplateDecl *D); + virtual bool TraverseTemplateInstantiations( \ + MaybeConst *D); DEF_TRAVERSE_TMPL_INST(Class) DEF_TRAVERSE_TMPL_INST(Var) DEF_TRAVERSE_TMPL_INST(Function) @@ -232,32 +250,34 @@ class DynamicRecursiveASTVisitor { // Decls. #define ABSTRACT_DECL(DECL) -#define DECL(CLASS, BASE) virtual bool Traverse##CLASS##Decl(CLASS##Decl *D); +#define DECL(CLASS, BASE) \ + bool WalkUpFrom##CLASS##Decl(MaybeConst *D); \ + virtual bool Traverse##CLASS##Decl(MaybeConst *D); #include "clang/AST/DeclNodes.inc" #define DECL(CLASS, BASE) \ - bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D); \ - virtual bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; } + virtual bool Visit##CLASS##Decl(MaybeConst *D) { return true; } #include "clang/AST/DeclNodes.inc" // Stmts. #define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) virtual bool Traverse##CLASS(CLASS *S); +#define STMT(CLASS, PARENT) virtual bool Traverse##CLASS(MaybeConst *S); #include "clang/AST/StmtNodes.inc" #define STMT(CLASS, PARENT) \ - bool WalkUpFrom##CLASS(CLASS *S); \ - virtual bool Visit##CLASS(CLASS *S) { return true; } + bool WalkUpFrom##CLASS(MaybeConst *S); \ + virtual bool Visit##CLASS(MaybeConst *S) { return true; } #include "clang/AST/StmtNodes.inc" // Types. #define ABSTRACT_TYPE(CLASS, BASE) -#define TYPE(CLASS, BASE) virtual bool Traverse##CLASS##Type(CLASS##Type *T); +#define TYPE(CLASS, BASE) \ + bool WalkUpFrom##CLASS##Type(MaybeConst *T); \ + virtual bool Traverse##CLASS##Type(MaybeConst *T); #include "clang/AST/TypeNodes.inc" #define TYPE(CLASS, BASE) \ - bool WalkUpFrom##CLASS##Type(CLASS##Type *T); \ - virtual bool Visit##CLASS##Type(CLASS##Type *T) { return true; } + virtual bool Visit##CLASS##Type(MaybeConst *T) { return true; } #include "clang/AST/TypeNodes.inc" // TypeLocs. @@ -271,6 +291,14 @@ class DynamicRecursiveASTVisitor { virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; } #include "clang/AST/TypeLocNodes.def" }; + +extern template class DynamicRecursiveASTVisitorBase; +extern template class DynamicRecursiveASTVisitorBase; + +using DynamicRecursiveASTVisitor = + DynamicRecursiveASTVisitorBase; +using ConstDynamicRecursiveASTVisitor = + DynamicRecursiveASTVisitorBase; } // namespace clang #endif // LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 708c8656decbe..cd584d9621a22 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -5180,7 +5180,7 @@ class InitListExpr : public Expr { /// than there are initializers in the list, specifies an expression to be /// used for value initialization of the rest of the elements. Expr *getArrayFiller() { - return ArrayFillerOrUnionFieldInit.dyn_cast(); + return dyn_cast_if_present(ArrayFillerOrUnionFieldInit); } const Expr *getArrayFiller() const { return const_cast(this)->getArrayFiller(); @@ -5205,7 +5205,7 @@ class InitListExpr : public Expr { /// union. However, a designated initializer can specify the /// initialization of a different field within the union. FieldDecl *getInitializedFieldInUnion() { - return ArrayFillerOrUnionFieldInit.dyn_cast(); + return dyn_cast_if_present(ArrayFillerOrUnionFieldInit); } const FieldDecl *getInitializedFieldInUnion() const { return const_cast(this)->getInitializedFieldInUnion(); @@ -6678,7 +6678,6 @@ class PseudoObjectExpr final class AtomicExpr : public Expr { public: enum AtomicOp { -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID, #include "clang/Basic/Builtins.inc" // Avoid trailing comma @@ -6742,7 +6741,6 @@ class AtomicExpr : public Expr { AtomicOp getOp() const { return Op; } StringRef getOpAsString() const { switch (Op) { -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case AO##ID: \ return #ID; diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 4cec89c979f77..98ba2bb41bb54 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -2847,8 +2847,8 @@ class TypeTraitExpr final /// /// Example: /// \code -/// __array_rank(int[10][20]) == 2 -/// __array_extent(int, 1) == 20 +/// __array_rank(int[10][20]) == 2 +/// __array_extent(int[10][20], 1) == 20 /// \endcode class ArrayTypeTraitExpr : public Expr { /// The trait. An ArrayTypeTrait enum in MSVC compat unsigned. @@ -4326,8 +4326,6 @@ class SizeOfPackExpr final /// Retrieve the parameter pack. NamedDecl *getPack() const { return Pack; } - void setPack(NamedDecl *NewPack) { Pack = NewPack; } - /// Retrieve the length of the parameter pack. /// /// This routine may only be invoked when the expression is not @@ -5026,11 +5024,11 @@ class CXXParenListInitExpr final void setArrayFiller(Expr *E) { ArrayFillerOrUnionFieldInit = E; } Expr *getArrayFiller() { - return ArrayFillerOrUnionFieldInit.dyn_cast(); + return dyn_cast_if_present(ArrayFillerOrUnionFieldInit); } const Expr *getArrayFiller() const { - return ArrayFillerOrUnionFieldInit.dyn_cast(); + return dyn_cast_if_present(ArrayFillerOrUnionFieldInit); } void setInitializedFieldInUnion(FieldDecl *FD) { @@ -5038,11 +5036,11 @@ class CXXParenListInitExpr final } FieldDecl *getInitializedFieldInUnion() { - return ArrayFillerOrUnionFieldInit.dyn_cast(); + return dyn_cast_if_present(ArrayFillerOrUnionFieldInit); } const FieldDecl *getInitializedFieldInUnion() const { - return ArrayFillerOrUnionFieldInit.dyn_cast(); + return dyn_cast_if_present(ArrayFillerOrUnionFieldInit); } child_range children() { @@ -5321,6 +5319,59 @@ class BuiltinBitCastExpr final } }; +// Represents an unexpanded pack where the list of expressions are +// known. These are used when structured bindings introduce a pack. +class ResolvedUnexpandedPackExpr final + : public Expr, + private llvm::TrailingObjects { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + + SourceLocation BeginLoc; + unsigned NumExprs; + + ResolvedUnexpandedPackExpr(SourceLocation BL, QualType QT, unsigned NumExprs); + +public: + static ResolvedUnexpandedPackExpr *CreateDeserialized(ASTContext &C, + unsigned NumExprs); + static ResolvedUnexpandedPackExpr * + Create(ASTContext &C, SourceLocation BeginLoc, QualType T, unsigned NumExprs); + static ResolvedUnexpandedPackExpr *Create(ASTContext &C, + SourceLocation BeginLoc, QualType T, + llvm::ArrayRef Exprs); + + unsigned getNumExprs() const { return NumExprs; } + + llvm::MutableArrayRef getExprs() { + return {getTrailingObjects(), NumExprs}; + } + + llvm::ArrayRef getExprs() const { + return {getTrailingObjects(), NumExprs}; + } + + Expr *getExpansion(unsigned Idx) { return getExprs()[Idx]; } + Expr *getExpansion(unsigned Idx) const { return getExprs()[Idx]; } + + // Iterators + child_range children() { + return child_range((Stmt **)getTrailingObjects(), + (Stmt **)getTrailingObjects() + getNumExprs()); + } + + SourceLocation getBeginLoc() const LLVM_READONLY { return BeginLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return BeginLoc; } + + // Returns the resolved pack of a decl or nullptr + static ResolvedUnexpandedPackExpr *getFromDecl(Decl *); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ResolvedUnexpandedPackExprClass; + } +}; + } // namespace clang #endif // LLVM_CLANG_AST_EXPRCXX_H diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index b9088eff3bb52..154ecfbaa4418 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -2423,6 +2423,28 @@ class OMPNoOpenMPRoutinesClause final OMPNoOpenMPRoutinesClause() : OMPNoChildClause() {} }; +/// This represents the 'no_openmp_constructs' clause in the +//// '#pragma omp assume' directive. +/// +/// \code +/// #pragma omp assume no_openmp_constructs +/// \endcode +/// In this example directive '#pragma omp assume' has a 'no_openmp_constructs' +/// clause. +class OMPNoOpenMPConstructsClause final + : public OMPNoChildClause { +public: + /// Build 'no_openmp_constructs' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPNoOpenMPConstructsClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPNoChildClause(StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPNoOpenMPConstructsClause() : OMPNoChildClause() {} +}; + /// This represents the 'no_parallelism' clause in the '#pragma omp assume' /// directive. /// @@ -9451,7 +9473,8 @@ struct TargetOMPContext final : public llvm::omp::OMPContext { TargetOMPContext(ASTContext &ASTCtx, std::function &&DiagUnknownTrait, const FunctionDecl *CurrentFunctionDecl, - ArrayRef ConstructTraits); + ArrayRef ConstructTraits, + int DeviceNum); virtual ~TargetOMPContext() = default; diff --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def index 8788b8ff0ef0a..b3dc7c3d8dc77 100644 --- a/clang/include/clang/AST/OperationKinds.def +++ b/clang/include/clang/AST/OperationKinds.def @@ -367,6 +367,9 @@ CAST_OPERATION(HLSLVectorTruncation) // Non-decaying array RValue cast (HLSL only). CAST_OPERATION(HLSLArrayRValue) +// Aggregate by Value cast (HLSL only). +CAST_OPERATION(HLSLElementwiseCast) + //===- Binary Operations -------------------------------------------------===// // Operators listed in order of precedence. // Note that additions to this should also update the StmtVisitor class, diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index c4a1d03f1b3d1..06c762c080de0 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2950,6 +2950,7 @@ DEF_TRAVERSE_STMT(FunctionParmPackExpr, {}) DEF_TRAVERSE_STMT(CXXFoldExpr, {}) DEF_TRAVERSE_STMT(AtomicExpr, {}) DEF_TRAVERSE_STMT(CXXParenListInitExpr, {}) +DEF_TRAVERSE_STMT(ResolvedUnexpandedPackExpr, {}) DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { if (S->getLifetimeExtendedTemporaryDecl()) { @@ -3543,6 +3544,12 @@ bool RecursiveASTVisitor::VisitOMPNoOpenMPRoutinesClause( return true; } +template +bool RecursiveASTVisitor::VisitOMPNoOpenMPConstructsClause( + OMPNoOpenMPConstructsClause *) { + return true; +} + template bool RecursiveASTVisitor::VisitOMPNoParallelismClause( OMPNoParallelismClause *) { @@ -4098,6 +4105,8 @@ DEF_TRAVERSE_STMT(OpenACCSetConstruct, { TRY_TO(VisitOpenACCClauseList(S->clauses())); }) DEF_TRAVERSE_STMT(OpenACCUpdateConstruct, { TRY_TO(VisitOpenACCClauseList(S->clauses())); }) +DEF_TRAVERSE_STMT(OpenACCAtomicConstruct, + { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) // Traverse HLSL: Out argument expression DEF_TRAVERSE_STMT(HLSLOutArgExpr, {}) diff --git a/clang/include/clang/AST/StmtOpenACC.h b/clang/include/clang/AST/StmtOpenACC.h index ebbee152f918f..bd6c95d342ce2 100644 --- a/clang/include/clang/AST/StmtOpenACC.h +++ b/clang/include/clang/AST/StmtOpenACC.h @@ -751,5 +751,50 @@ class OpenACCUpdateConstruct final Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef Clauses); }; + +// This class represents the 'atomic' construct, which has an associated +// statement, but no clauses. +class OpenACCAtomicConstruct final : public OpenACCAssociatedStmtConstruct { + + friend class ASTStmtReader; + OpenACCAtomicKind AtomicKind = OpenACCAtomicKind::None; + + OpenACCAtomicConstruct(EmptyShell) + : OpenACCAssociatedStmtConstruct( + OpenACCAtomicConstructClass, OpenACCDirectiveKind::Atomic, + SourceLocation{}, SourceLocation{}, SourceLocation{}, + /*AssociatedStmt=*/nullptr) {} + + OpenACCAtomicConstruct(SourceLocation Start, SourceLocation DirectiveLoc, + OpenACCAtomicKind AtKind, SourceLocation End, + Stmt *AssociatedStmt) + : OpenACCAssociatedStmtConstruct(OpenACCAtomicConstructClass, + OpenACCDirectiveKind::Atomic, Start, + DirectiveLoc, End, AssociatedStmt), + AtomicKind(AtKind) {} + + void setAssociatedStmt(Stmt *S) { + OpenACCAssociatedStmtConstruct::setAssociatedStmt(S); + } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCAtomicConstructClass; + } + + static OpenACCAtomicConstruct *CreateEmpty(const ASTContext &C); + static OpenACCAtomicConstruct * + Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + OpenACCAtomicKind AtKind, SourceLocation End, Stmt *AssociatedStmt); + + OpenACCAtomicKind getAtomicKind() const { return AtomicKind; } + const Stmt *getAssociatedStmt() const { + return OpenACCAssociatedStmtConstruct::getAssociatedStmt(); + } + Stmt *getAssociatedStmt() { + return OpenACCAssociatedStmtConstruct::getAssociatedStmt(); + } +}; + } // namespace clang #endif // LLVM_CLANG_AST_STMTOPENACC_H diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 4aaae48ba8b42..bfd205ffb0d99 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -420,6 +420,7 @@ class TextNodeDumper void VisitOpenACCSetConstruct(const OpenACCSetConstruct *S); void VisitOpenACCShutdownConstruct(const OpenACCShutdownConstruct *S); void VisitOpenACCUpdateConstruct(const OpenACCUpdateConstruct *S); + void VisitOpenACCAtomicConstruct(const OpenACCAtomicConstruct *S); void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S); void VisitEmbedExpr(const EmbedExpr *S); void VisitAtomicExpr(const AtomicExpr *AE); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 3457d524c63aa..1d9743520654e 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2518,6 +2518,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isFloat32Type() const; bool isDoubleType() const; bool isBFloat16Type() const; + bool isMFloat8Type() const; bool isFloat128Type() const; bool isIbm128Type() const; bool isRealType() const; // C99 6.2.5p17 (real floating + integer) @@ -8537,6 +8538,10 @@ inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } +inline bool Type::isMFloat8Type() const { + return isSpecificBuiltinType(BuiltinType::MFloat8); +} + inline bool Type::isFloat128Type() const { return isSpecificBuiltinType(BuiltinType::Float128); } diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 239fcba4e5e05..0f7e3a8a01762 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2489,7 +2489,28 @@ extern const internal::VariadicDynCastAllOfMatcher extern const internal::VariadicDynCastAllOfMatcher imaginaryLiteral; -/// Matches fixed point literals +/// Matches fixed-point literals eg. +/// 0.5r, 0.5hr, 0.5lr, 0.5uhr, 0.5ur, 0.5ulr +/// 1.0k, 1.0hk, 1.0lk, 1.0uhk, 1.0uk, 1.0ulk +/// Exponents 1.0e10k +/// Hexadecimal numbers 0x0.2p2r +/// +/// Does not match implicit conversions such as first two lines: +/// \code +/// short _Accum sa = 2; +/// _Accum a = 12.5; +/// _Accum b = 1.25hk; +/// _Fract c = 0.25hr; +/// _Fract v = 0.35uhr; +/// _Accum g = 1.45uhk; +/// _Accum decexp1 = 1.575e1k; +/// \endcode +/// \compile_args{-ffixed-point;-std=c99} +/// +/// The matcher \matcher{fixedPointLiteral()} matches +/// \match{1.25hk}, \match{0.25hr}, \match{0.35uhr}, +/// \match{1.45uhk}, \match{1.575e1k}, but does not +/// match \nomatch{12.5} and \nomatch{2} from the code block. extern const internal::VariadicDynCastAllOfMatcher fixedPointLiteral; diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h index b9339570e1ae7..1df1f1cb892e4 100644 --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -85,6 +85,9 @@ class ProgramPoint { LoopExitKind, EpsilonKind}; + static StringRef getProgramPointKindName(Kind K); + std::optional getSourceLocation() const; + private: const void *Data1; llvm::PointerIntPair Data2; diff --git a/clang/include/clang/Basic/AArch64SVEACLETypes.def b/clang/include/clang/Basic/AArch64SVEACLETypes.def index 063cac1f4a58e..6a6f51c95ebd0 100644 --- a/clang/include/clang/Basic/AArch64SVEACLETypes.def +++ b/clang/include/clang/Basic/AArch64SVEACLETypes.def @@ -57,6 +57,11 @@ // - IsBF true for vector of brain float elements. //===----------------------------------------------------------------------===// +#ifndef SVE_SCALAR_TYPE +#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits) \ + SVE_TYPE(Name, Id, SingletonId) +#endif + #ifndef SVE_VECTOR_TYPE #define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ SVE_TYPE(Name, Id, SingletonId) @@ -72,6 +77,11 @@ SVE_VECTOR_TYPE_DETAILS(Name, MangledName, Id, SingletonId, NumEls, ElBits, NF, false, false, true) #endif +#ifndef SVE_VECTOR_TYPE_MFLOAT +#define SVE_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, ElBits, NF) \ + SVE_VECTOR_TYPE_DETAILS(Name, MangledName, Id, SingletonId, NumEls, ElBits, NF, false, false, false) +#endif + #ifndef SVE_VECTOR_TYPE_FLOAT #define SVE_VECTOR_TYPE_FLOAT(Name, MangledName, Id, SingletonId, NumEls, ElBits, NF) \ SVE_VECTOR_TYPE_DETAILS(Name, MangledName, Id, SingletonId, NumEls, ElBits, NF, false, true, false) @@ -97,120 +107,107 @@ SVE_TYPE(Name, Id, SingletonId) #endif -#ifndef AARCH64_VECTOR_TYPE -#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ - SVE_TYPE(Name, Id, SingletonId) -#endif - -#ifndef AARCH64_VECTOR_TYPE_MFLOAT -#define AARCH64_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, ElBits, NF) \ - AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) -#endif - //===- Vector point types -----------------------------------------------===// -SVE_VECTOR_TYPE_INT("__SVInt8_t", "__SVInt8_t", SveInt8, SveInt8Ty, 16, 8, 1, true) -SVE_VECTOR_TYPE_INT("__SVInt16_t", "__SVInt16_t", SveInt16, SveInt16Ty, 8, 16, 1, true) -SVE_VECTOR_TYPE_INT("__SVInt32_t", "__SVInt32_t", SveInt32, SveInt32Ty, 4, 32, 1, true) -SVE_VECTOR_TYPE_INT("__SVInt64_t", "__SVInt64_t", SveInt64, SveInt64Ty, 2, 64, 1, true) +SVE_VECTOR_TYPE_INT(__SVInt8_t, __SVInt8_t, SveInt8, SveInt8Ty, 16, 8, 1, true) +SVE_VECTOR_TYPE_INT(__SVInt16_t, __SVInt16_t, SveInt16, SveInt16Ty, 8, 16, 1, true) +SVE_VECTOR_TYPE_INT(__SVInt32_t, __SVInt32_t, SveInt32, SveInt32Ty, 4, 32, 1, true) +SVE_VECTOR_TYPE_INT(__SVInt64_t, __SVInt64_t, SveInt64, SveInt64Ty, 2, 64, 1, true) -SVE_VECTOR_TYPE_INT("__SVUint8_t", "__SVUint8_t", SveUint8, SveUint8Ty, 16, 8, 1, false) -SVE_VECTOR_TYPE_INT("__SVUint16_t", "__SVUint16_t", SveUint16, SveUint16Ty, 8, 16, 1, false) -SVE_VECTOR_TYPE_INT("__SVUint32_t", "__SVUint32_t", SveUint32, SveUint32Ty, 4, 32, 1, false) -SVE_VECTOR_TYPE_INT("__SVUint64_t", "__SVUint64_t", SveUint64, SveUint64Ty, 2, 64, 1, false) +SVE_VECTOR_TYPE_INT(__SVUint8_t, __SVUint8_t, SveUint8, SveUint8Ty, 16, 8, 1, false) +SVE_VECTOR_TYPE_INT(__SVUint16_t, __SVUint16_t, SveUint16, SveUint16Ty, 8, 16, 1, false) +SVE_VECTOR_TYPE_INT(__SVUint32_t, __SVUint32_t, SveUint32, SveUint32Ty, 4, 32, 1, false) +SVE_VECTOR_TYPE_INT(__SVUint64_t, __SVUint64_t, SveUint64, SveUint64Ty, 2, 64, 1, false) -SVE_VECTOR_TYPE_FLOAT("__SVFloat16_t", "__SVFloat16_t", SveFloat16, SveFloat16Ty, 8, 16, 1) -SVE_VECTOR_TYPE_FLOAT("__SVFloat32_t", "__SVFloat32_t", SveFloat32, SveFloat32Ty, 4, 32, 1) -SVE_VECTOR_TYPE_FLOAT("__SVFloat64_t", "__SVFloat64_t", SveFloat64, SveFloat64Ty, 2, 64, 1) +SVE_VECTOR_TYPE_FLOAT(__SVFloat16_t, __SVFloat16_t, SveFloat16, SveFloat16Ty, 8, 16, 1) +SVE_VECTOR_TYPE_FLOAT(__SVFloat32_t, __SVFloat32_t, SveFloat32, SveFloat32Ty, 4, 32, 1) +SVE_VECTOR_TYPE_FLOAT(__SVFloat64_t, __SVFloat64_t, SveFloat64, SveFloat64Ty, 2, 64, 1) -SVE_VECTOR_TYPE_BFLOAT("__SVBfloat16_t", "__SVBfloat16_t", SveBFloat16, SveBFloat16Ty, 8, 16, 1) +SVE_VECTOR_TYPE_BFLOAT(__SVBfloat16_t, __SVBfloat16_t, SveBFloat16, SveBFloat16Ty, 8, 16, 1) -// This is a 8 bits opaque type. -SVE_VECTOR_TYPE_INT("__SVMfloat8_t", "__SVMfloat8_t", SveMFloat8, SveMFloat8Ty, 16, 8, 1, false) +SVE_VECTOR_TYPE_MFLOAT(__SVMfloat8_t, __SVMfloat8_t, SveMFloat8, SveMFloat8Ty, 16, 8, 1) // // x2 // -SVE_VECTOR_TYPE_INT("__clang_svint8x2_t", "svint8x2_t", SveInt8x2, SveInt8x2Ty, 16, 8, 2, true) -SVE_VECTOR_TYPE_INT("__clang_svint16x2_t", "svint16x2_t", SveInt16x2, SveInt16x2Ty, 8, 16, 2, true) -SVE_VECTOR_TYPE_INT("__clang_svint32x2_t", "svint32x2_t", SveInt32x2, SveInt32x2Ty, 4, 32, 2, true) -SVE_VECTOR_TYPE_INT("__clang_svint64x2_t", "svint64x2_t", SveInt64x2, SveInt64x2Ty, 2, 64, 2, true) +SVE_VECTOR_TYPE_INT(__clang_svint8x2_t, svint8x2_t, SveInt8x2, SveInt8x2Ty, 16, 8, 2, true) +SVE_VECTOR_TYPE_INT(__clang_svint16x2_t, svint16x2_t, SveInt16x2, SveInt16x2Ty, 8, 16, 2, true) +SVE_VECTOR_TYPE_INT(__clang_svint32x2_t, svint32x2_t, SveInt32x2, SveInt32x2Ty, 4, 32, 2, true) +SVE_VECTOR_TYPE_INT(__clang_svint64x2_t, svint64x2_t, SveInt64x2, SveInt64x2Ty, 2, 64, 2, true) -SVE_VECTOR_TYPE_INT("__clang_svuint8x2_t", "svuint8x2_t", SveUint8x2, SveUint8x2Ty, 16 , 8, 2, false) -SVE_VECTOR_TYPE_INT("__clang_svuint16x2_t", "svuint16x2_t", SveUint16x2, SveUint16x2Ty, 8, 16, 2, false) -SVE_VECTOR_TYPE_INT("__clang_svuint32x2_t", "svuint32x2_t", SveUint32x2, SveUint32x2Ty, 4, 32, 2, false) -SVE_VECTOR_TYPE_INT("__clang_svuint64x2_t", "svuint64x2_t", SveUint64x2, SveUint64x2Ty, 2, 64, 2, false) +SVE_VECTOR_TYPE_INT(__clang_svuint8x2_t, svuint8x2_t, SveUint8x2, SveUint8x2Ty, 16 , 8, 2, false) +SVE_VECTOR_TYPE_INT(__clang_svuint16x2_t, svuint16x2_t, SveUint16x2, SveUint16x2Ty, 8, 16, 2, false) +SVE_VECTOR_TYPE_INT(__clang_svuint32x2_t, svuint32x2_t, SveUint32x2, SveUint32x2Ty, 4, 32, 2, false) +SVE_VECTOR_TYPE_INT(__clang_svuint64x2_t, svuint64x2_t, SveUint64x2, SveUint64x2Ty, 2, 64, 2, false) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat16x2_t", "svfloat16x2_t", SveFloat16x2, SveFloat16x2Ty, 8, 16, 2) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat32x2_t", "svfloat32x2_t", SveFloat32x2, SveFloat32x2Ty, 4, 32, 2) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat64x2_t", "svfloat64x2_t", SveFloat64x2, SveFloat64x2Ty, 2, 64, 2) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat16x2_t, svfloat16x2_t, SveFloat16x2, SveFloat16x2Ty, 8, 16, 2) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat32x2_t, svfloat32x2_t, SveFloat32x2, SveFloat32x2Ty, 4, 32, 2) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat64x2_t, svfloat64x2_t, SveFloat64x2, SveFloat64x2Ty, 2, 64, 2) -SVE_VECTOR_TYPE_BFLOAT("__clang_svbfloat16x2_t", "svbfloat16x2_t", SveBFloat16x2, SveBFloat16x2Ty, 8, 16, 2) +SVE_VECTOR_TYPE_BFLOAT(__clang_svbfloat16x2_t, svbfloat16x2_t, SveBFloat16x2, SveBFloat16x2Ty, 8, 16, 2) -SVE_VECTOR_TYPE_INT("__clang_svmfloat8x2_t", "svmfloat8x2_t", SveMFloat8x2, SveMFloat8x2Ty, 16, 8, 2, false) +SVE_VECTOR_TYPE_MFLOAT(__clang_svmfloat8x2_t, svmfloat8x2_t, SveMFloat8x2, SveMFloat8x2Ty, 16, 8, 2) // // x3 // -SVE_VECTOR_TYPE_INT("__clang_svint8x3_t", "svint8x3_t", SveInt8x3, SveInt8x3Ty, 16, 8, 3, true) -SVE_VECTOR_TYPE_INT("__clang_svint16x3_t", "svint16x3_t", SveInt16x3, SveInt16x3Ty, 8, 16, 3, true) -SVE_VECTOR_TYPE_INT("__clang_svint32x3_t", "svint32x3_t", SveInt32x3, SveInt32x3Ty, 4, 32, 3, true) -SVE_VECTOR_TYPE_INT("__clang_svint64x3_t", "svint64x3_t", SveInt64x3, SveInt64x3Ty, 2, 64, 3, true) +SVE_VECTOR_TYPE_INT(__clang_svint8x3_t, svint8x3_t, SveInt8x3, SveInt8x3Ty, 16, 8, 3, true) +SVE_VECTOR_TYPE_INT(__clang_svint16x3_t, svint16x3_t, SveInt16x3, SveInt16x3Ty, 8, 16, 3, true) +SVE_VECTOR_TYPE_INT(__clang_svint32x3_t, svint32x3_t, SveInt32x3, SveInt32x3Ty, 4, 32, 3, true) +SVE_VECTOR_TYPE_INT(__clang_svint64x3_t, svint64x3_t, SveInt64x3, SveInt64x3Ty, 2, 64, 3, true) -SVE_VECTOR_TYPE_INT("__clang_svuint8x3_t", "svuint8x3_t", SveUint8x3, SveUint8x3Ty, 16, 8, 3, false) -SVE_VECTOR_TYPE_INT("__clang_svuint16x3_t", "svuint16x3_t", SveUint16x3, SveUint16x3Ty, 8, 16, 3, false) -SVE_VECTOR_TYPE_INT("__clang_svuint32x3_t", "svuint32x3_t", SveUint32x3, SveUint32x3Ty, 4, 32, 3, false) -SVE_VECTOR_TYPE_INT("__clang_svuint64x3_t", "svuint64x3_t", SveUint64x3, SveUint64x3Ty, 2, 64, 3, false) +SVE_VECTOR_TYPE_INT(__clang_svuint8x3_t, svuint8x3_t, SveUint8x3, SveUint8x3Ty, 16, 8, 3, false) +SVE_VECTOR_TYPE_INT(__clang_svuint16x3_t, svuint16x3_t, SveUint16x3, SveUint16x3Ty, 8, 16, 3, false) +SVE_VECTOR_TYPE_INT(__clang_svuint32x3_t, svuint32x3_t, SveUint32x3, SveUint32x3Ty, 4, 32, 3, false) +SVE_VECTOR_TYPE_INT(__clang_svuint64x3_t, svuint64x3_t, SveUint64x3, SveUint64x3Ty, 2, 64, 3, false) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat16x3_t", "svfloat16x3_t", SveFloat16x3, SveFloat16x3Ty, 8, 16, 3) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat32x3_t", "svfloat32x3_t", SveFloat32x3, SveFloat32x3Ty, 4, 32, 3) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat64x3_t", "svfloat64x3_t", SveFloat64x3, SveFloat64x3Ty, 2, 64, 3) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat16x3_t, svfloat16x3_t, SveFloat16x3, SveFloat16x3Ty, 8, 16, 3) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat32x3_t, svfloat32x3_t, SveFloat32x3, SveFloat32x3Ty, 4, 32, 3) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat64x3_t, svfloat64x3_t, SveFloat64x3, SveFloat64x3Ty, 2, 64, 3) -SVE_VECTOR_TYPE_BFLOAT("__clang_svbfloat16x3_t", "svbfloat16x3_t", SveBFloat16x3, SveBFloat16x3Ty, 8, 16, 3) +SVE_VECTOR_TYPE_BFLOAT(__clang_svbfloat16x3_t, svbfloat16x3_t, SveBFloat16x3, SveBFloat16x3Ty, 8, 16, 3) -SVE_VECTOR_TYPE_INT("__clang_svmfloat8x3_t", "svmfloat8x3_t", SveMFloat8x3, SveMFloat8x3Ty, 16, 8, 3, false) +SVE_VECTOR_TYPE_MFLOAT(__clang_svmfloat8x3_t, svmfloat8x3_t, SveMFloat8x3, SveMFloat8x3Ty, 16, 8, 3) // // x4 // -SVE_VECTOR_TYPE_INT("__clang_svint8x4_t", "svint8x4_t", SveInt8x4, SveInt8x4Ty, 16, 8, 4, true) -SVE_VECTOR_TYPE_INT("__clang_svint16x4_t", "svint16x4_t", SveInt16x4, SveInt16x4Ty, 8, 16, 4, true) -SVE_VECTOR_TYPE_INT("__clang_svint32x4_t", "svint32x4_t", SveInt32x4, SveInt32x4Ty, 4, 32, 4, true) -SVE_VECTOR_TYPE_INT("__clang_svint64x4_t", "svint64x4_t", SveInt64x4, SveInt64x4Ty, 2, 64, 4, true) +SVE_VECTOR_TYPE_INT(__clang_svint8x4_t, svint8x4_t, SveInt8x4, SveInt8x4Ty, 16, 8, 4, true) +SVE_VECTOR_TYPE_INT(__clang_svint16x4_t, svint16x4_t, SveInt16x4, SveInt16x4Ty, 8, 16, 4, true) +SVE_VECTOR_TYPE_INT(__clang_svint32x4_t, svint32x4_t, SveInt32x4, SveInt32x4Ty, 4, 32, 4, true) +SVE_VECTOR_TYPE_INT(__clang_svint64x4_t, svint64x4_t, SveInt64x4, SveInt64x4Ty, 2, 64, 4, true) -SVE_VECTOR_TYPE_INT("__clang_svuint8x4_t", "svuint8x4_t", SveUint8x4, SveUint8x4Ty, 16, 8, 4, false) -SVE_VECTOR_TYPE_INT("__clang_svuint16x4_t", "svuint16x4_t", SveUint16x4, SveUint16x4Ty, 8, 16, 4, false) -SVE_VECTOR_TYPE_INT("__clang_svuint32x4_t", "svuint32x4_t", SveUint32x4, SveUint32x4Ty, 4, 32, 4, false) -SVE_VECTOR_TYPE_INT("__clang_svuint64x4_t", "svuint64x4_t", SveUint64x4, SveUint64x4Ty, 2, 64, 4, false) +SVE_VECTOR_TYPE_INT(__clang_svuint8x4_t, svuint8x4_t, SveUint8x4, SveUint8x4Ty, 16, 8, 4, false) +SVE_VECTOR_TYPE_INT(__clang_svuint16x4_t, svuint16x4_t, SveUint16x4, SveUint16x4Ty, 8, 16, 4, false) +SVE_VECTOR_TYPE_INT(__clang_svuint32x4_t, svuint32x4_t, SveUint32x4, SveUint32x4Ty, 4, 32, 4, false) +SVE_VECTOR_TYPE_INT(__clang_svuint64x4_t, svuint64x4_t, SveUint64x4, SveUint64x4Ty, 2, 64, 4, false) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat16x4_t", "svfloat16x4_t", SveFloat16x4, SveFloat16x4Ty, 8, 16, 4) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat32x4_t", "svfloat32x4_t", SveFloat32x4, SveFloat32x4Ty, 4, 32, 4) -SVE_VECTOR_TYPE_FLOAT("__clang_svfloat64x4_t", "svfloat64x4_t", SveFloat64x4, SveFloat64x4Ty, 2, 64, 4) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat16x4_t, svfloat16x4_t, SveFloat16x4, SveFloat16x4Ty, 8, 16, 4) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat32x4_t, svfloat32x4_t, SveFloat32x4, SveFloat32x4Ty, 4, 32, 4) +SVE_VECTOR_TYPE_FLOAT(__clang_svfloat64x4_t, svfloat64x4_t, SveFloat64x4, SveFloat64x4Ty, 2, 64, 4) -SVE_VECTOR_TYPE_BFLOAT("__clang_svbfloat16x4_t", "svbfloat16x4_t", SveBFloat16x4, SveBFloat16x4Ty, 8, 16, 4) +SVE_VECTOR_TYPE_BFLOAT(__clang_svbfloat16x4_t, svbfloat16x4_t, SveBFloat16x4, SveBFloat16x4Ty, 8, 16, 4) -SVE_VECTOR_TYPE_INT("__clang_svmfloat8x4_t", "svmfloat8x4_t", SveMFloat8x4, SveMFloat8x4Ty, 16, 8, 4, false) +SVE_VECTOR_TYPE_MFLOAT(__clang_svmfloat8x4_t, svmfloat8x4_t, SveMFloat8x4, SveMFloat8x4Ty, 16, 8, 4) -SVE_PREDICATE_TYPE_ALL("__SVBool_t", "__SVBool_t", SveBool, SveBoolTy, 16, 1) -SVE_PREDICATE_TYPE_ALL("__clang_svboolx2_t", "svboolx2_t", SveBoolx2, SveBoolx2Ty, 16, 2) -SVE_PREDICATE_TYPE_ALL("__clang_svboolx4_t", "svboolx4_t", SveBoolx4, SveBoolx4Ty, 16, 4) +SVE_PREDICATE_TYPE_ALL(__SVBool_t, __SVBool_t, SveBool, SveBoolTy, 16, 1) +SVE_PREDICATE_TYPE_ALL(__clang_svboolx2_t, svboolx2_t, SveBoolx2, SveBoolx2Ty, 16, 2) +SVE_PREDICATE_TYPE_ALL(__clang_svboolx4_t, svboolx4_t, SveBoolx4, SveBoolx4Ty, 16, 4) -SVE_OPAQUE_TYPE("__SVCount_t", "__SVCount_t", SveCount, SveCountTy) +SVE_OPAQUE_TYPE(__SVCount_t, __SVCount_t, SveCount, SveCountTy) -AARCH64_VECTOR_TYPE_MFLOAT("__mfp8", "__mfp8", MFloat8, MFloat8Ty, 1, 8, 1) -AARCH64_VECTOR_TYPE_MFLOAT("__MFloat8x8_t", "__MFloat8x8_t", MFloat8x8, MFloat8x8Ty, 8, 8, 1) -AARCH64_VECTOR_TYPE_MFLOAT("__MFloat8x16_t", "__MFloat8x16_t", MFloat8x16, MFloat8x16Ty, 16, 8, 1) +SVE_SCALAR_TYPE(__mfp8, __mfp8, MFloat8, MFloat8Ty, 8) #undef SVE_VECTOR_TYPE +#undef SVE_VECTOR_TYPE_MFLOAT #undef SVE_VECTOR_TYPE_BFLOAT #undef SVE_VECTOR_TYPE_FLOAT #undef SVE_VECTOR_TYPE_INT #undef SVE_PREDICATE_TYPE #undef SVE_PREDICATE_TYPE_ALL #undef SVE_OPAQUE_TYPE -#undef AARCH64_VECTOR_TYPE_MFLOAT -#undef AARCH64_VECTOR_TYPE +#undef SVE_SCALAR_TYPE #undef SVE_TYPE diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h index 7b723d508fff1..d18bfe54931f9 100644 --- a/clang/include/clang/Basic/AddressSpaces.h +++ b/clang/include/clang/Basic/AddressSpaces.h @@ -58,6 +58,7 @@ enum class LangAS : unsigned { // HLSL specific address spaces. hlsl_groupshared, + hlsl_constant, // Wasm specific address spaces. wasm_funcref, diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 408d3adf370c8..4384a98d63eb3 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -198,7 +198,7 @@ def OpenCLKernelFunction // inclusive nature of subject testing). def HasFunctionProto : SubsetSubjectgetFunctionType(true) != nullptr && - isa(S->getFunctionType())) || + isa(S->getFunctionType())) || isa(S) || isa(S)}], "non-K&R-style functions">; @@ -380,6 +380,13 @@ class Clang bit AllowInC = allowInC; } +// This spelling combines the spellings of GCC and Clang for cases where the +// spellings are equivalent for compile compatibility. +class ClangGCC + : Spelling { + bit AllowInC = allowInC; +} + // HLSL Annotation spellings class HLSLAnnotation : Spelling; @@ -3458,18 +3465,16 @@ def DiagnoseIf : InheritableAttr { let Spellings = [GNU<"diagnose_if">]; let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>; let Args = [ExprArgument<"Cond">, StringArgument<"Message">, - EnumArgument<"DiagnosticType", "DiagnosticType", + EnumArgument<"DefaultSeverity", + "DefaultSeverity", /*is_string=*/true, - ["error", "warning"], - ["DT_Error", "DT_Warning"]>, + ["error", "warning"], + ["DS_error", "DS_warning"]>, + StringArgument<"WarningGroup", /*optional*/ 1>, BoolArgument<"ArgDependent", 0, /*fake*/ 1>, DeclArgument]; let InheritEvenIfAlreadyPresent = 1; let LateParsed = LateAttrParseStandard; - let AdditionalMembers = [{ - bool isError() const { return diagnosticType == DT_Error; } - bool isWarning() const { return diagnosticType == DT_Warning; } - }]; let TemplateDependent = 1; let Documentation = [DiagnoseIfDocs]; } @@ -3679,7 +3684,7 @@ def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr } def NoSanitize : InheritableAttr { - let Spellings = [Clang<"no_sanitize">]; + let Spellings = [ClangGCC<"no_sanitize">]; let Args = [VariadicStringArgument<"Sanitizers">]; let Subjects = SubjectList<[Function, ObjCMethod, GlobalVar], ErrorDiag>; let Documentation = [NoSanitizeDocs]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index a8b588169725a..0ad4c958d0983 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5274,6 +5274,7 @@ optimization passes are aware of the following assumptions: "omp_no_openmp" "omp_no_openmp_routines" "omp_no_parallelism" + "omp_no_openmp_constructs" The OpenMP standard defines the meaning of OpenMP assumptions ("omp_XYZ" is spelled "XYZ" in the `OpenMP 5.1 Standard`_). diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 63559d977ce6b..6d29b4315e5a7 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringTable.h" #include // VC++ defines 'alloca' as an object-like macro, which interferes with our @@ -55,6 +56,7 @@ struct HeaderDesc { #undef HEADER } ID; + constexpr HeaderDesc() : ID() {} constexpr HeaderDesc(HeaderID ID) : ID(ID) {} const char *getName() const; @@ -62,20 +64,160 @@ struct HeaderDesc { namespace Builtin { enum ID { - NotBuiltin = 0, // This is not a builtin function. -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, + NotBuiltin = 0, // This is not a builtin function. +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_ENUMERATORS FirstTSBuiltin }; +struct InfosShard; + +/// The info used to represent each builtin. struct Info { - llvm::StringLiteral Name; - const char *Type, *Attributes; - const char *Features; - HeaderDesc Header; - LanguageID Langs; + // Rather than store pointers to the string literals describing these four + // aspects of builtins, we store offsets into a common string table. + struct StrOffsets { + llvm::StringTable::Offset Name = {}; + llvm::StringTable::Offset Type = {}; + llvm::StringTable::Offset Attributes = {}; + + // Defaults to the empty string offset. + llvm::StringTable::Offset Features = {}; + } Offsets; + + HeaderDesc Header = HeaderDesc::NO_HEADER; + LanguageID Langs = ALL_LANGUAGES; + + /// Get the name for the builtin represented by this `Info` object. + /// + /// Must be provided the `Shard` for this `Info` object. + std::string getName(const InfosShard &Shard) const; }; +/// A constexpr function to construct an infos array from X-macros. +/// +/// The input array uses the same data structure, but the offsets are actually +/// _lengths_ when input. This is all we can compute from the X-macro approach +/// to builtins. This function will convert these lengths into actual offsets to +/// a string table built up through sequentially appending strings with the +/// given lengths. +template +static constexpr std::array MakeInfos(std::array Infos) { + // Translate lengths to offsets. We start past the initial empty string at + // offset zero. + unsigned Offset = 1; + for (Info &I : Infos) { + Info::StrOffsets NewOffsets = {}; + NewOffsets.Name = Offset; + Offset += I.Offsets.Name.value(); + NewOffsets.Type = Offset; + Offset += I.Offsets.Type.value(); + NewOffsets.Attributes = Offset; + Offset += I.Offsets.Attributes.value(); + NewOffsets.Features = Offset; + Offset += I.Offsets.Features.value(); + I.Offsets = NewOffsets; + } + return Infos; +} + +/// A shard of a target's builtins string table and info. +/// +/// Target builtins are sharded across multiple tables due to different +/// structures, origins, and also to improve the overall scaling by avoiding a +/// single table across all builtins. +struct InfosShard { + const llvm::StringTable *Strings; + llvm::ArrayRef Infos; + + llvm::StringLiteral NamePrefix = ""; +}; + +// A detail macro used below to emit a string literal that, after string literal +// concatenation, ends up triggering the `-Woverlength-strings` warning. While +// the warning is useful in general to catch accidentally excessive strings, +// here we are creating them intentionally. +// +// This relies on a subtle aspect of `_Pragma`: that the *diagnostic* ones don't +// turn into actual tokens that would disrupt string literal concatenation. +#ifdef __clang__ +#define CLANG_BUILTIN_DETAIL_STR_TABLE(S) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Woverlength-strings\"") \ + S _Pragma("clang diagnostic pop") +#else +#define CLANG_BUILTIN_DETAIL_STR_TABLE(S) S +#endif + +// We require string tables to start with an empty string so that a `0` offset +// can always be used to refer to an empty string. To satisfy that when building +// string tables with X-macros, we use this start macro prior to expanding the +// X-macros. +#define CLANG_BUILTIN_STR_TABLE_START CLANG_BUILTIN_DETAIL_STR_TABLE("\0") + +// A macro that can be used with `Builtins.def` and similar files as an X-macro +// to add the string arguments to a builtin string table. This is typically the +// target for the `BUILTIN`, `LANGBUILTIN`, or `LIBBUILTIN` macros in those +// files. +#define CLANG_BUILTIN_STR_TABLE(ID, TYPE, ATTRS) \ + CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" /*FEATURE*/ "\0") + +// A macro that can be used with target builtin `.def` and `.inc` files as an +// X-macro to add the string arguments to a builtin string table. this is +// typically the target for the `TARGET_BUILTIN` macro. +#define CLANG_TARGET_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, FEATURE) \ + CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0") + +// A macro that can be used with target builtin `.def` and `.inc` files as an +// X-macro to add the string arguments to a builtin string table. this is +// typically the target for the `TARGET_HEADER_BUILTIN` macro. We can't delegate +// to `TARGET_BUILTIN` because the `FEATURE` string changes position. +#define CLANG_TARGET_HEADER_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, HEADER, LANGS, \ + FEATURE) \ + CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0") + +// A detail macro used internally to compute the desired string table +// `StrOffsets` struct for arguments to `MakeInfos`. +#define CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS) \ + Builtin::Info::StrOffsets { \ + sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("") \ + } + +// A detail macro used internally to compute the desired string table +// `StrOffsets` struct for arguments to `Storage::Make`. +#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE) \ + Builtin::Info::StrOffsets { \ + sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE) \ + } + +// A set of macros that can be used with builtin `.def' files as an X-macro to +// create an `Info` struct for a particular builtin. It both computes the +// `StrOffsets` value for the string table (the lengths here, translated to +// offsets by the `MakeInfos` function), and the other metadata for each +// builtin. +// +// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`, +// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`. +#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS) \ + Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \ + HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG) \ + Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \ + HeaderDesc::NO_HEADER, LANG}, +#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG) \ + Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS), \ + HeaderDesc::HEADER, LANG}, +#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE) \ + Builtin::Info{ \ + CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE), \ + HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG, \ + FEATURE) \ + Builtin::Info{ \ + CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE), \ + HeaderDesc::HEADER, LANG}, + /// Holds information about both target-independent and /// target-specific builtins, allowing easy queries by clients. /// @@ -83,11 +225,16 @@ struct Info { /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to /// be translated back with getAuxBuiltinID() before use. class Context { - llvm::ArrayRef TSRecords; - llvm::ArrayRef AuxTSRecords; + llvm::SmallVector BuiltinShards; + + llvm::SmallVector TargetShards; + llvm::SmallVector AuxTargetShards; + + unsigned NumTargetBuiltins = 0; + unsigned NumAuxTargetBuiltins = 0; public: - Context() = default; + Context(); /// Perform target-specific initialization /// \param AuxTarget Target info to incorporate builtins from. May be nullptr. @@ -100,13 +247,17 @@ class Context { /// Return the identifier name for the specified builtin, /// e.g. "__builtin_abs". - llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; } + std::string getName(unsigned ID) const; - /// Return a quoted name for the specified builtin for use in diagnostics. + /// Return the identifier name for the specified builtin inside single quotes + /// for a diagnostic, e.g. "'__builtin_abs'". std::string getQuotedName(unsigned ID) const; /// Get the type descriptor string for the specified builtin. - const char *getTypeString(unsigned ID) const { return getRecord(ID).Type; } + const char *getTypeString(unsigned ID) const; + + /// Get the attributes descriptor string for the specified builtin. + const char *getAttributesString(unsigned ID) const; /// Return true if this function is a target-specific builtin. bool isTSBuiltin(unsigned ID) const { @@ -115,40 +266,40 @@ class Context { /// Return true if this function has no side effects. bool isPure(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'U') != nullptr; + return strchr(getAttributesString(ID), 'U') != nullptr; } /// Return true if this function has no side effects and doesn't /// read memory. bool isConst(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'c') != nullptr; + return strchr(getAttributesString(ID), 'c') != nullptr; } /// Return true if we know this builtin never throws an exception. bool isNoThrow(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'n') != nullptr; + return strchr(getAttributesString(ID), 'n') != nullptr; } /// Return true if we know this builtin never returns. bool isNoReturn(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'r') != nullptr; + return strchr(getAttributesString(ID), 'r') != nullptr; } /// Return true if we know this builtin can return twice. bool isReturnsTwice(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'j') != nullptr; + return strchr(getAttributesString(ID), 'j') != nullptr; } /// Returns true if this builtin does not perform the side-effects /// of its arguments. bool isUnevaluated(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'u') != nullptr; + return strchr(getAttributesString(ID), 'u') != nullptr; } /// Return true if this is a builtin for a libc/libm function, /// with a "__builtin_" prefix (e.g. __builtin_abs). bool isLibFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'F') != nullptr; + return strchr(getAttributesString(ID), 'F') != nullptr; } /// Determines whether this builtin is a predefined libc/libm @@ -159,21 +310,21 @@ class Context { /// they do not, but they are recognized as builtins once we see /// a declaration. bool isPredefinedLibFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'f') != nullptr; + return strchr(getAttributesString(ID), 'f') != nullptr; } /// Returns true if this builtin requires appropriate header in other /// compilers. In Clang it will work even without including it, but we can emit /// a warning about missing header. bool isHeaderDependentFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'h') != nullptr; + return strchr(getAttributesString(ID), 'h') != nullptr; } /// Determines whether this builtin is a predefined compiler-rt/libgcc /// function, such as "__clear_cache", where we know the signature a /// priori. bool isPredefinedRuntimeFunction(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'i') != nullptr; + return strchr(getAttributesString(ID), 'i') != nullptr; } /// Determines whether this builtin is a C++ standard library function @@ -181,7 +332,7 @@ class Context { /// specialization, where the signature is determined by the standard library /// declaration. bool isInStdNamespace(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'z') != nullptr; + return strchr(getAttributesString(ID), 'z') != nullptr; } /// Determines whether this builtin can have its address taken with no @@ -195,33 +346,33 @@ class Context { /// Determines whether this builtin has custom typechecking. bool hasCustomTypechecking(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 't') != nullptr; + return strchr(getAttributesString(ID), 't') != nullptr; } /// Determines whether a declaration of this builtin should be recognized /// even if the type doesn't match the specified signature. bool allowTypeMismatch(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'T') != nullptr || + return strchr(getAttributesString(ID), 'T') != nullptr || hasCustomTypechecking(ID); } /// Determines whether this builtin has a result or any arguments which /// are pointer types. bool hasPtrArgsOrResult(unsigned ID) const { - return strchr(getRecord(ID).Type, '*') != nullptr; + return strchr(getTypeString(ID), '*') != nullptr; } /// Return true if this builtin has a result or any arguments which are /// reference types. bool hasReferenceArgsOrResult(unsigned ID) const { - return strchr(getRecord(ID).Type, '&') != nullptr || - strchr(getRecord(ID).Type, 'A') != nullptr; + return strchr(getTypeString(ID), '&') != nullptr || + strchr(getTypeString(ID), 'A') != nullptr; } /// If this is a library function that comes from a specific /// header, retrieve that header name. const char *getHeaderName(unsigned ID) const { - return getRecord(ID).Header.getName(); + return getInfo(ID).Header.getName(); } /// Determine whether this builtin is like printf in its @@ -246,27 +397,25 @@ class Context { /// Such functions can be const when the MathErrno lang option and FP /// exceptions are disabled. bool isConstWithoutErrnoAndExceptions(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'e') != nullptr; + return strchr(getAttributesString(ID), 'e') != nullptr; } bool isConstWithoutExceptions(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'g') != nullptr; + return strchr(getAttributesString(ID), 'g') != nullptr; } - const char *getRequiredFeatures(unsigned ID) const { - return getRecord(ID).Features; - } + const char *getRequiredFeatures(unsigned ID) const; unsigned getRequiredVectorWidth(unsigned ID) const; /// Return true if builtin ID belongs to AuxTarget. bool isAuxBuiltinID(unsigned ID) const { - return ID >= (Builtin::FirstTSBuiltin + TSRecords.size()); + return ID >= (Builtin::FirstTSBuiltin + NumTargetBuiltins); } /// Return real builtin ID (i.e. ID it would have during compilation /// for AuxTarget). - unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); } + unsigned getAuxBuiltinID(unsigned ID) const { return ID - NumTargetBuiltins; } /// Returns true if this is a libc/libm function without the '__builtin_' /// prefix. @@ -278,16 +427,19 @@ class Context { /// Return true if this function can be constant evaluated by Clang frontend. bool isConstantEvaluated(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'E') != nullptr; + return strchr(getAttributesString(ID), 'E') != nullptr; } /// Returns true if this is an immediate (consteval) function bool isImmediate(unsigned ID) const { - return strchr(getRecord(ID).Attributes, 'G') != nullptr; + return strchr(getAttributesString(ID), 'G') != nullptr; } private: - const Info &getRecord(unsigned ID) const; + std::pair + getShardAndInfo(unsigned ID) const; + + const Info &getInfo(unsigned ID) const { return getShardAndInfo(ID).second; } /// Helper function for isPrintfLike and isScanfLike. bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg, diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 60c360d4a9e07..2433427a89429 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4753,6 +4753,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> { } // HLSL +def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_adduint64"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_resource_getpointer"]; let Attributes = [NoThrow]; @@ -4795,6 +4801,12 @@ def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { let Prototype = "unsigned int(bool)"; } +def HLSLWaveActiveMax : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_active_max"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void (...)"; +} + def HLSLWaveActiveSum : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_wave_active_sum"]; let Attributes = [NoThrow, Const]; diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index 1b29a8e359c20..39e295aced96b 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -504,6 +504,8 @@ TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4i16, "V4sV4s*1", "nc", "gf TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64") TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4bf16, "V4yV4y*1", "nc", "gfx12-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_ds_bpermute_fi_b32, "iii", "nc", "gfx12-insts") + //===----------------------------------------------------------------------===// // WMMA builtins. // Postfix w32 indicates the builtin requires wavefront size of 32. diff --git a/clang/include/clang/Basic/BuiltinsARM.def b/clang/include/clang/Basic/BuiltinsARM.def index 5a7064a98045e..cbab87cecbc7d 100644 --- a/clang/include/clang/Basic/BuiltinsARM.def +++ b/clang/include/clang/Basic/BuiltinsARM.def @@ -206,13 +206,6 @@ BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // Misc BUILTIN(__builtin_sponentry, "v*", "c") -// Builtins for implementing ACLE MVE intrinsics. (Unlike NEON, these -// don't need to live in a separate BuiltinsMVE.def, because they -// aren't included from both here and BuiltinsAArch64.def.) -#include "clang/Basic/arm_mve_builtins.inc" - -#include "clang/Basic/arm_cde_builtins.inc" - // MSVC LANGBUILTIN(__emit, "vIUiC", "", ALL_MS_LANGUAGES) diff --git a/clang/include/clang/Basic/BuiltinsBase.td b/clang/include/clang/Basic/BuiltinsBase.td index 6180a94aa4b5c..cf15a31235e7e 100644 --- a/clang/include/clang/Basic/BuiltinsBase.td +++ b/clang/include/clang/Basic/BuiltinsBase.td @@ -86,6 +86,13 @@ def Consteval : Attribute<"EG">; // indicated by the remaining indices. class Callback ArgIndices> : MultiIndexAttribute<"C", ArgIndices>; +// Prefixes +// ======== + +class NamePrefix { + string Spelling = spelling; +} + // Builtin kinds // ============= @@ -99,6 +106,9 @@ class Builtin { bit RequiresUndef = 0; // Enables builtins to generate `long long` outside of OpenCL and `long` inside. bit EnableOpenCLLong = 0; + // Requires a common prefix to be prepended. Each generated set of builtins + // can optionally extract one common prefix that is handled separately. + NamePrefix RequiredNamePrefix; } class AtomicBuiltin : Builtin; diff --git a/clang/include/clang/Basic/BuiltinsHexagon.def b/clang/include/clang/Basic/BuiltinsHexagon.def deleted file mode 100644 index adff9f884c049..0000000000000 --- a/clang/include/clang/Basic/BuiltinsHexagon.def +++ /dev/null @@ -1,173 +0,0 @@ -//===-- BuiltinsHexagon.def - Hexagon Builtin function database --*- C++ -*-==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the Hexagon-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -// The format of this database matches clang/Basic/Builtins.def. - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -#pragma push_macro("V79") -#define V79 "v79" -#pragma push_macro("V75") -#define V75 "v75|" V79 -#pragma push_macro("V73") -#define V73 "v73|" V75 -#pragma push_macro("V71") -#define V71 "v71|" V73 -#pragma push_macro("V69") -#define V69 "v69|" V71 -#pragma push_macro("V68") -#define V68 "v68|" V69 -#pragma push_macro("V67") -#define V67 "v67|" V68 -#pragma push_macro("V66") -#define V66 "v66|" V67 -#pragma push_macro("V65") -#define V65 "v65|" V66 -#pragma push_macro("V62") -#define V62 "v62|" V65 -#pragma push_macro("V60") -#define V60 "v60|" V62 -#pragma push_macro("V55") -#define V55 "v55|" V60 -#pragma push_macro("V5") -#define V5 "v5|" V55 - -#pragma push_macro("HVXV79") -#define HVXV79 "hvxv79" -#pragma push_macro("HVXV75") -#define HVXV75 "hvxv75|" HVXV79 -#pragma push_macro("HVXV73") -#define HVXV73 "hvxv73|" HVXV75 -#pragma push_macro("HVXV71") -#define HVXV71 "hvxv71|" HVXV73 -#pragma push_macro("HVXV69") -#define HVXV69 "hvxv69|" HVXV71 -#pragma push_macro("HVXV68") -#define HVXV68 "hvxv68|" HVXV69 -#pragma push_macro("HVXV67") -#define HVXV67 "hvxv67|" HVXV68 -#pragma push_macro("HVXV66") -#define HVXV66 "hvxv66|" HVXV67 -#pragma push_macro("HVXV65") -#define HVXV65 "hvxv65|" HVXV66 -#pragma push_macro("HVXV62") -#define HVXV62 "hvxv62|" HVXV65 -#pragma push_macro("HVXV60") -#define HVXV60 "hvxv60|" HVXV62 - - -// The builtins below are not autogenerated from iset.py. -// Make sure you do not overwrite these. -TARGET_BUILTIN(__builtin_SI_to_SXTHI_asrh, "ii", "", V5) -TARGET_BUILTIN(__builtin_brev_ldd, "v*LLi*CLLi*iC", "", V5) -TARGET_BUILTIN(__builtin_brev_ldw, "v*i*Ci*iC", "", V5) -TARGET_BUILTIN(__builtin_brev_ldh, "v*s*Cs*iC", "", V5) -TARGET_BUILTIN(__builtin_brev_lduh, "v*Us*CUs*iC", "", V5) -TARGET_BUILTIN(__builtin_brev_ldb, "v*Sc*CSc*iC", "", V5) -TARGET_BUILTIN(__builtin_brev_ldub, "v*Uc*CUc*iC", "", V5) -TARGET_BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*iIi", "", V5) -TARGET_BUILTIN(__builtin_circ_ldw, "i*i*i*iIi", "", V5) -TARGET_BUILTIN(__builtin_circ_ldh, "s*s*s*iIi", "", V5) -TARGET_BUILTIN(__builtin_circ_lduh, "Us*Us*Us*iIi", "", V5) -TARGET_BUILTIN(__builtin_circ_ldb, "c*c*c*iIi", "", V5) -TARGET_BUILTIN(__builtin_circ_ldub, "Uc*Uc*Uc*iIi", "", V5) -TARGET_BUILTIN(__builtin_brev_std, "LLi*CLLi*LLiiC", "", V5) -TARGET_BUILTIN(__builtin_brev_stw, "i*Ci*iiC", "", V5) -TARGET_BUILTIN(__builtin_brev_sth, "s*Cs*iiC", "", V5) -TARGET_BUILTIN(__builtin_brev_sthhi, "s*Cs*iiC", "", V5) -TARGET_BUILTIN(__builtin_brev_stb, "c*Cc*iiC", "", V5) -TARGET_BUILTIN(__builtin_circ_std, "LLi*LLi*LLiiIi", "", V5) -TARGET_BUILTIN(__builtin_circ_stw, "i*i*iiIi", "", V5) -TARGET_BUILTIN(__builtin_circ_sth, "s*s*iiIi", "", V5) -TARGET_BUILTIN(__builtin_circ_sthhi, "s*s*iiIi", "", V5) -TARGET_BUILTIN(__builtin_circ_stb, "c*c*iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrub_pci, "iv*IiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrb_pci, "iv*IiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadruh_pci, "iv*IiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrh_pci, "iv*IiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadri_pci, "iv*IiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrd_pci, "LLiv*IiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrub_pcr, "iv*ivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrb_pcr, "iv*ivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadruh_pcr, "iv*ivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrh_pcr, "iv*ivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadri_pcr, "iv*ivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrd_pcr, "LLiv*ivC*", "", V5) - -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerb_pci, "vv*IiiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerh_pci, "vv*IiiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerf_pci, "vv*IiiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storeri_pci, "vv*IiiivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerd_pci, "vv*IiiLLivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerb_pcr, "vv*iivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerh_pcr, "vv*iivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerf_pcr, "vv*iivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storeri_pcr, "vv*iivC*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_storerd_pcr, "vv*iLLivC*", "", V5) - -TARGET_BUILTIN(__builtin_HEXAGON_prefetch,"vv*","", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A6_vminub_RdP,"LLiLLiLLi","", V62) - -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq,"vV64bv*V16i","", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq,"vV64bv*V16i","", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq,"vV64bv*V16i","", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq,"vV64bv*V16i","", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq_128B,"vV128bv*V32i","", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq_128B,"vV128bv*V32i","", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq_128B,"vV128bv*V32i","", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq_128B,"vV128bv*V32i","", HVXV60) - - -// These are only valid on v65 -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt,"V32iV16iLLi","", "hvxv65") -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_128B,"V64iV32iLLi","", "hvxv65") -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc,"V32iV32iV16iLLi","", "hvxv65") -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B,"V64iV64iV32iLLi","", "hvxv65") -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt,"V32iV16iLLi","", "hvxv65") -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_128B,"V64iV32iLLi","", "hvxv65") -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc,"V32iV32iV16iLLi","", "hvxv65") -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "hvxv65") - -#include "clang/Basic/BuiltinsHexagonDep.def" - -#pragma pop_macro("HVXV60") -#pragma pop_macro("HVXV62") -#pragma pop_macro("HVXV65") -#pragma pop_macro("HVXV66") -#pragma pop_macro("HVXV67") -#pragma pop_macro("HVXV68") -#pragma pop_macro("HVXV69") -#pragma pop_macro("HVXV71") -#pragma pop_macro("HVXV73") -#pragma pop_macro("HVXV75") -#pragma pop_macro("HVXV79") - -#pragma pop_macro("V5") -#pragma pop_macro("V55") -#pragma pop_macro("V60") -#pragma pop_macro("V62") -#pragma pop_macro("V65") -#pragma pop_macro("V66") -#pragma pop_macro("V67") -#pragma pop_macro("V68") -#pragma pop_macro("V69") -#pragma pop_macro("V71") -#pragma pop_macro("V73") -#pragma pop_macro("V75") -#pragma pop_macro("V79") - -#undef BUILTIN -#undef TARGET_BUILTIN - diff --git a/clang/include/clang/Basic/BuiltinsHexagon.td b/clang/include/clang/Basic/BuiltinsHexagon.td new file mode 100644 index 0000000000000..0727c67346697 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHexagon.td @@ -0,0 +1,2146 @@ +//===--- BuiltinsHexagon.td - Hexagon Builtin function defs -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the Hexagon-specific builtin function database. +// +//===----------------------------------------------------------------------===// + +include "clang/Basic/BuiltinsBase.td" + +class VFeatures { + string Features; +} + +class V : VFeatures { + let Features = !strconcat("v", version, "|", newer.Features); +} + +let Features = "v79" in def V79 : VFeatures; + +def V75 : V<"75", V79>; +def V73 : V<"73", V75>; +def V71 : V<"71", V73>; +def V69 : V<"69", V71>; +def V68 : V<"68", V69>; +def V67 : V<"67", V68>; +def V66 : V<"66", V67>; +def V65 : V<"65", V66>; +def V62 : V<"62", V65>; +def V60 : V<"60", V62>; +def V55 : V<"55", V60>; +def V5 : V<"5", V55>; + +class HVXVFeatures { + string Features; +} + +class HVXV : HVXVFeatures { + let Features = !strconcat("hvxv", version, "|", newer.Features); +} + +let Features = "hvxv79" in def HVXV79 : HVXVFeatures; + +def HVXV75 : HVXV<"75", HVXV79>; +def HVXV73 : HVXV<"73", HVXV75>; +def HVXV71 : HVXV<"71", HVXV73>; +def HVXV69 : HVXV<"69", HVXV71>; +def HVXV68 : HVXV<"68", HVXV69>; +def HVXV67 : HVXV<"67", HVXV68>; +def HVXV66 : HVXV<"66", HVXV67>; +def HVXV65 : HVXV<"65", HVXV66>; +def HVXV62 : HVXV<"62", HVXV65>; +def HVXV60 : HVXV<"60", HVXV62>; + +def HexagonPrefix : NamePrefix<"__builtin_HEXAGON_">; + +class HexagonBuiltin : TargetBuiltin { + let Spellings = [NAME]; + let Prototype = prototype; + let Features = V5.Features; + let RequiredNamePrefix = HexagonPrefix; // Adds a prefix to the name. +} + +class HexagonBuiltinNoPrefix : TargetBuiltin { + let Spellings = [NAME]; + let Prototype = prototype; + let Features = V5.Features; +} + +// The builtins below are not autogenerated from iset.py. +// Make sure you do not overwrite these. +def __builtin_SI_to_SXTHI_asrh : HexagonBuiltinNoPrefix<"int(int)">; +def __builtin_brev_ldd : HexagonBuiltinNoPrefix<"void *(long long int * const, long long int *, int const)">; +def __builtin_brev_ldw : HexagonBuiltinNoPrefix<"void *(int * const, int *, int const)">; +def __builtin_brev_ldh : HexagonBuiltinNoPrefix<"void *(short * const, short *, int const)">; +def __builtin_brev_lduh : HexagonBuiltinNoPrefix<"void *(unsigned short * const, unsigned short *, int const)">; +def __builtin_brev_ldb : HexagonBuiltinNoPrefix<"void *(signed char * const, signed char *, int const)">; +def __builtin_brev_ldub : HexagonBuiltinNoPrefix<"void *(unsigned char * const, unsigned char *, int const)">; +def __builtin_circ_ldd : HexagonBuiltinNoPrefix<"long long int *(long long int *, long long int *, int, _Constant int)">; +def __builtin_circ_ldw : HexagonBuiltinNoPrefix<"int *(int *, int *, int, _Constant int)">; +def __builtin_circ_ldh : HexagonBuiltinNoPrefix<"short *(short *, short *, int, _Constant int)">; +def __builtin_circ_lduh : HexagonBuiltinNoPrefix<"unsigned short *(unsigned short *, unsigned short *, int, _Constant int)">; +def __builtin_circ_ldb : HexagonBuiltinNoPrefix<"char *(char *, char *, int, _Constant int)">; +def __builtin_circ_ldub : HexagonBuiltinNoPrefix<"unsigned char *(unsigned char *, unsigned char *, int, _Constant int)">; +def __builtin_brev_std : HexagonBuiltinNoPrefix<"long long int * const(long long int *, long long int, int const)">; +def __builtin_brev_stw : HexagonBuiltinNoPrefix<"int * const(int *, int, int const)">; +def __builtin_brev_sth : HexagonBuiltinNoPrefix<"short * const(short *, int, int const)">; +def __builtin_brev_sthhi : HexagonBuiltinNoPrefix<"short * const(short *, int, int const)">; +def __builtin_brev_stb : HexagonBuiltinNoPrefix<"char * const(char *, int, int const)">; +def __builtin_circ_std : HexagonBuiltinNoPrefix<"long long int *(long long int *, long long int, int, _Constant int)">; +def __builtin_circ_stw : HexagonBuiltinNoPrefix<"int *(int *, int, int, _Constant int)">; +def __builtin_circ_sth : HexagonBuiltinNoPrefix<"short *(short *, int, int, _Constant int)">; +def __builtin_circ_sthhi : HexagonBuiltinNoPrefix<"short *(short *, int, int, _Constant int)">; +def __builtin_circ_stb : HexagonBuiltinNoPrefix<"char *(char *, int, int, _Constant int)">; +def L2_loadrub_pci : HexagonBuiltin<"int(void *, _Constant int, int, void const *)">; +def L2_loadrb_pci : HexagonBuiltin<"int(void *, _Constant int, int, void const *)">; +def L2_loadruh_pci : HexagonBuiltin<"int(void *, _Constant int, int, void const *)">; +def L2_loadrh_pci : HexagonBuiltin<"int(void *, _Constant int, int, void const *)">; +def L2_loadri_pci : HexagonBuiltin<"int(void *, _Constant int, int, void const *)">; +def L2_loadrd_pci : HexagonBuiltin<"long long int(void *, _Constant int, int, void const *)">; +def L2_loadrub_pcr : HexagonBuiltin<"int(void *, int, void const *)">; +def L2_loadrb_pcr : HexagonBuiltin<"int(void *, int, void const *)">; +def L2_loadruh_pcr : HexagonBuiltin<"int(void *, int, void const *)">; +def L2_loadrh_pcr : HexagonBuiltin<"int(void *, int, void const *)">; +def L2_loadri_pcr : HexagonBuiltin<"int(void *, int, void const *)">; +def L2_loadrd_pcr : HexagonBuiltin<"long long int(void *, int, void const *)">; + +def S2_storerb_pci : HexagonBuiltin<"void(void *, _Constant int, int, int, void const *)">; +def S2_storerh_pci : HexagonBuiltin<"void(void *, _Constant int, int, int, void const *)">; +def S2_storerf_pci : HexagonBuiltin<"void(void *, _Constant int, int, int, void const *)">; +def S2_storeri_pci : HexagonBuiltin<"void(void *, _Constant int, int, int, void const *)">; +def S2_storerd_pci : HexagonBuiltin<"void(void *, _Constant int, int, long long int, void const *)">; +def S2_storerb_pcr : HexagonBuiltin<"void(void *, int, int, void const *)">; +def S2_storerh_pcr : HexagonBuiltin<"void(void *, int, int, void const *)">; +def S2_storerf_pcr : HexagonBuiltin<"void(void *, int, int, void const *)">; +def S2_storeri_pcr : HexagonBuiltin<"void(void *, int, int, void const *)">; +def S2_storerd_pcr : HexagonBuiltin<"void(void *, int, long long int, void const *)">; + +def prefetch : HexagonBuiltin<"void(void *)">; +let Features = V62.Features in { + def A6_vminub_RdP : HexagonBuiltin<"long long int(long long int, long long int)">; +} + +let Features = HVXV60.Features in { + def V6_vmaskedstoreq : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vmaskedstorenq : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vmaskedstorentq : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vmaskedstorentnq : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vmaskedstoreq_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; + def V6_vmaskedstorenq_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; + def V6_vmaskedstorentq_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; + def V6_vmaskedstorentnq_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; +} + + +// These are only valid on v65 +let Features = "hvxv65" in { + def V6_vrmpybub_rtt : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, long long int)">; + def V6_vrmpybub_rtt_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, long long int)">; + def V6_vrmpybub_rtt_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, long long int)">; + def V6_vrmpybub_rtt_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, long long int)">; + def V6_vrmpyub_rtt : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, long long int)">; + def V6_vrmpyub_rtt_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, long long int)">; + def V6_vrmpyub_rtt_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, long long int)">; + def V6_vrmpyub_rtt_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, long long int)">; +} + +// V5 Scalar Instructions. + +def A2_abs : HexagonBuiltin<"int(int)">; +def A2_absp : HexagonBuiltin<"long long int(long long int)">; +def A2_abssat : HexagonBuiltin<"int(int)">; +def A2_add : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_hh : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_hl : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_lh : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_ll : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_sat_hh : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_sat_hl : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_sat_lh : HexagonBuiltin<"int(int, int)">; +def A2_addh_h16_sat_ll : HexagonBuiltin<"int(int, int)">; +def A2_addh_l16_hl : HexagonBuiltin<"int(int, int)">; +def A2_addh_l16_ll : HexagonBuiltin<"int(int, int)">; +def A2_addh_l16_sat_hl : HexagonBuiltin<"int(int, int)">; +def A2_addh_l16_sat_ll : HexagonBuiltin<"int(int, int)">; +def A2_addi : HexagonBuiltin<"int(int, _Constant int)">; +def A2_addp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_addpsat : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_addsat : HexagonBuiltin<"int(int, int)">; +def A2_addsp : HexagonBuiltin<"long long int(int, long long int)">; +def A2_and : HexagonBuiltin<"int(int, int)">; +def A2_andir : HexagonBuiltin<"int(int, _Constant int)">; +def A2_andp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_aslh : HexagonBuiltin<"int(int)">; +def A2_asrh : HexagonBuiltin<"int(int)">; +def A2_combine_hh : HexagonBuiltin<"int(int, int)">; +def A2_combine_hl : HexagonBuiltin<"int(int, int)">; +def A2_combine_lh : HexagonBuiltin<"int(int, int)">; +def A2_combine_ll : HexagonBuiltin<"int(int, int)">; +def A2_combineii : HexagonBuiltin<"long long int(_Constant int, _Constant int)">; +def A2_combinew : HexagonBuiltin<"long long int(int, int)">; +def A2_max : HexagonBuiltin<"int(int, int)">; +def A2_maxp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_maxu : HexagonBuiltin<"unsigned int(int, int)">; +def A2_maxup : HexagonBuiltin<"unsigned long long int(long long int, long long int)">; +def A2_min : HexagonBuiltin<"int(int, int)">; +def A2_minp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_minu : HexagonBuiltin<"unsigned int(int, int)">; +def A2_minup : HexagonBuiltin<"unsigned long long int(long long int, long long int)">; +def A2_neg : HexagonBuiltin<"int(int)">; +def A2_negp : HexagonBuiltin<"long long int(long long int)">; +def A2_negsat : HexagonBuiltin<"int(int)">; +def A2_not : HexagonBuiltin<"int(int)">; +def A2_notp : HexagonBuiltin<"long long int(long long int)">; +def A2_or : HexagonBuiltin<"int(int, int)">; +def A2_orir : HexagonBuiltin<"int(int, _Constant int)">; +def A2_orp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_roundsat : HexagonBuiltin<"int(long long int)">; +def A2_sat : HexagonBuiltin<"int(long long int)">; +def A2_satb : HexagonBuiltin<"int(int)">; +def A2_sath : HexagonBuiltin<"int(int)">; +def A2_satub : HexagonBuiltin<"int(int)">; +def A2_satuh : HexagonBuiltin<"int(int)">; +def A2_sub : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_hh : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_hl : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_lh : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_ll : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_sat_hh : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_sat_hl : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_sat_lh : HexagonBuiltin<"int(int, int)">; +def A2_subh_h16_sat_ll : HexagonBuiltin<"int(int, int)">; +def A2_subh_l16_hl : HexagonBuiltin<"int(int, int)">; +def A2_subh_l16_ll : HexagonBuiltin<"int(int, int)">; +def A2_subh_l16_sat_hl : HexagonBuiltin<"int(int, int)">; +def A2_subh_l16_sat_ll : HexagonBuiltin<"int(int, int)">; +def A2_subp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_subri : HexagonBuiltin<"int(_Constant int, int)">; +def A2_subsat : HexagonBuiltin<"int(int, int)">; +def A2_svaddh : HexagonBuiltin<"int(int, int)">; +def A2_svaddhs : HexagonBuiltin<"int(int, int)">; +def A2_svadduhs : HexagonBuiltin<"int(int, int)">; +def A2_svavgh : HexagonBuiltin<"int(int, int)">; +def A2_svavghs : HexagonBuiltin<"int(int, int)">; +def A2_svnavgh : HexagonBuiltin<"int(int, int)">; +def A2_svsubh : HexagonBuiltin<"int(int, int)">; +def A2_svsubhs : HexagonBuiltin<"int(int, int)">; +def A2_svsubuhs : HexagonBuiltin<"int(int, int)">; +def A2_swiz : HexagonBuiltin<"int(int)">; +def A2_sxtb : HexagonBuiltin<"int(int)">; +def A2_sxth : HexagonBuiltin<"int(int)">; +def A2_sxtw : HexagonBuiltin<"long long int(int)">; +def A2_tfr : HexagonBuiltin<"int(int)">; +def A2_tfrih : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A2_tfril : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A2_tfrp : HexagonBuiltin<"long long int(long long int)">; +def A2_tfrpi : HexagonBuiltin<"long long int(_Constant int)">; +def A2_tfrsi : HexagonBuiltin<"int(_Constant int)">; +def A2_vabsh : HexagonBuiltin<"long long int(long long int)">; +def A2_vabshsat : HexagonBuiltin<"long long int(long long int)">; +def A2_vabsw : HexagonBuiltin<"long long int(long long int)">; +def A2_vabswsat : HexagonBuiltin<"long long int(long long int)">; +def A2_vaddb_map : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vaddh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vaddhs : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vaddub : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vaddubs : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vadduhs : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vaddw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vaddws : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavgh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavghcr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavghr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavgub : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavgubr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavguh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavguhr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavguw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavguwr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavgw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavgwcr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vavgwr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vcmpbeq : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vcmpbgtu : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vcmpheq : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vcmphgt : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vcmphgtu : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vcmpweq : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vcmpwgt : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vcmpwgtu : HexagonBuiltin<"int(long long int, long long int)">; +def A2_vconj : HexagonBuiltin<"long long int(long long int)">; +def A2_vmaxb : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vmaxh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vmaxub : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vmaxuh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vmaxuw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vmaxw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vminb : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vminh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vminub : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vminuh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vminuw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vminw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vnavgh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vnavghcr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vnavghr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vnavgw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vnavgwcr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vnavgwr : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vraddub : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vraddub_acc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def A2_vrsadub : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vrsadub_acc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def A2_vsubb_map : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vsubh : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vsubhs : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vsubub : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vsububs : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vsubuhs : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vsubw : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_vsubws : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_xor : HexagonBuiltin<"int(int, int)">; +def A2_xorp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A2_zxtb : HexagonBuiltin<"int(int)">; +def A2_zxth : HexagonBuiltin<"int(int)">; +def A4_andn : HexagonBuiltin<"int(int, int)">; +def A4_andnp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A4_bitsplit : HexagonBuiltin<"long long int(int, int)">; +def A4_bitspliti : HexagonBuiltin<"long long int(int, unsigned _Constant int)">; +def A4_boundscheck : HexagonBuiltin<"int(int, long long int)">; +def A4_cmpbeq : HexagonBuiltin<"int(int, int)">; +def A4_cmpbeqi : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A4_cmpbgt : HexagonBuiltin<"int(int, int)">; +def A4_cmpbgti : HexagonBuiltin<"int(int, _Constant int)">; +def A4_cmpbgtu : HexagonBuiltin<"int(int, int)">; +def A4_cmpbgtui : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A4_cmpheq : HexagonBuiltin<"int(int, int)">; +def A4_cmpheqi : HexagonBuiltin<"int(int, _Constant int)">; +def A4_cmphgt : HexagonBuiltin<"int(int, int)">; +def A4_cmphgti : HexagonBuiltin<"int(int, _Constant int)">; +def A4_cmphgtu : HexagonBuiltin<"int(int, int)">; +def A4_cmphgtui : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A4_combineir : HexagonBuiltin<"long long int(_Constant int, int)">; +def A4_combineri : HexagonBuiltin<"long long int(int, _Constant int)">; +def A4_cround_ri : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A4_cround_rr : HexagonBuiltin<"int(int, int)">; +def A4_modwrapu : HexagonBuiltin<"int(int, int)">; +def A4_orn : HexagonBuiltin<"int(int, int)">; +def A4_ornp : HexagonBuiltin<"long long int(long long int, long long int)">; +def A4_rcmpeq : HexagonBuiltin<"int(int, int)">; +def A4_rcmpeqi : HexagonBuiltin<"int(int, _Constant int)">; +def A4_rcmpneq : HexagonBuiltin<"int(int, int)">; +def A4_rcmpneqi : HexagonBuiltin<"int(int, _Constant int)">; +def A4_round_ri : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A4_round_ri_sat : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def A4_round_rr : HexagonBuiltin<"int(int, int)">; +def A4_round_rr_sat : HexagonBuiltin<"int(int, int)">; +def A4_tlbmatch : HexagonBuiltin<"int(long long int, int)">; +def A4_vcmpbeq_any : HexagonBuiltin<"int(long long int, long long int)">; +def A4_vcmpbeqi : HexagonBuiltin<"int(long long int, unsigned _Constant int)">; +def A4_vcmpbgt : HexagonBuiltin<"int(long long int, long long int)">; +def A4_vcmpbgti : HexagonBuiltin<"int(long long int, _Constant int)">; +def A4_vcmpbgtui : HexagonBuiltin<"int(long long int, unsigned _Constant int)">; +def A4_vcmpheqi : HexagonBuiltin<"int(long long int, _Constant int)">; +def A4_vcmphgti : HexagonBuiltin<"int(long long int, _Constant int)">; +def A4_vcmphgtui : HexagonBuiltin<"int(long long int, unsigned _Constant int)">; +def A4_vcmpweqi : HexagonBuiltin<"int(long long int, _Constant int)">; +def A4_vcmpwgti : HexagonBuiltin<"int(long long int, _Constant int)">; +def A4_vcmpwgtui : HexagonBuiltin<"int(long long int, unsigned _Constant int)">; +def A4_vrmaxh : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A4_vrmaxuh : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A4_vrmaxuw : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A4_vrmaxw : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A4_vrminh : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A4_vrminuh : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A4_vrminuw : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A4_vrminw : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def A5_vaddhubs : HexagonBuiltin<"int(long long int, long long int)">; +def C2_all8 : HexagonBuiltin<"int(int)">; +def C2_and : HexagonBuiltin<"int(int, int)">; +def C2_andn : HexagonBuiltin<"int(int, int)">; +def C2_any8 : HexagonBuiltin<"int(int)">; +def C2_bitsclr : HexagonBuiltin<"int(int, int)">; +def C2_bitsclri : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def C2_bitsset : HexagonBuiltin<"int(int, int)">; +def C2_cmpeq : HexagonBuiltin<"int(int, int)">; +def C2_cmpeqi : HexagonBuiltin<"int(int, _Constant int)">; +def C2_cmpeqp : HexagonBuiltin<"int(long long int, long long int)">; +def C2_cmpgei : HexagonBuiltin<"int(int, _Constant int)">; +def C2_cmpgeui : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def C2_cmpgt : HexagonBuiltin<"int(int, int)">; +def C2_cmpgti : HexagonBuiltin<"int(int, _Constant int)">; +def C2_cmpgtp : HexagonBuiltin<"int(long long int, long long int)">; +def C2_cmpgtu : HexagonBuiltin<"int(int, int)">; +def C2_cmpgtui : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def C2_cmpgtup : HexagonBuiltin<"int(long long int, long long int)">; +def C2_cmplt : HexagonBuiltin<"int(int, int)">; +def C2_cmpltu : HexagonBuiltin<"int(int, int)">; +def C2_mask : HexagonBuiltin<"long long int(int)">; +def C2_mux : HexagonBuiltin<"int(int, int, int)">; +def C2_muxii : HexagonBuiltin<"int(int, _Constant int, _Constant int)">; +def C2_muxir : HexagonBuiltin<"int(int, int, _Constant int)">; +def C2_muxri : HexagonBuiltin<"int(int, _Constant int, int)">; +def C2_not : HexagonBuiltin<"int(int)">; +def C2_or : HexagonBuiltin<"int(int, int)">; +def C2_orn : HexagonBuiltin<"int(int, int)">; +def C2_pxfer_map : HexagonBuiltin<"int(int)">; +def C2_tfrpr : HexagonBuiltin<"int(int)">; +def C2_tfrrp : HexagonBuiltin<"int(int)">; +def C2_vitpack : HexagonBuiltin<"int(int, int)">; +def C2_vmux : HexagonBuiltin<"long long int(int, long long int, long long int)">; +def C2_xor : HexagonBuiltin<"int(int, int)">; +def C4_and_and : HexagonBuiltin<"int(int, int, int)">; +def C4_and_andn : HexagonBuiltin<"int(int, int, int)">; +def C4_and_or : HexagonBuiltin<"int(int, int, int)">; +def C4_and_orn : HexagonBuiltin<"int(int, int, int)">; +def C4_cmplte : HexagonBuiltin<"int(int, int)">; +def C4_cmpltei : HexagonBuiltin<"int(int, _Constant int)">; +def C4_cmplteu : HexagonBuiltin<"int(int, int)">; +def C4_cmplteui : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def C4_cmpneq : HexagonBuiltin<"int(int, int)">; +def C4_cmpneqi : HexagonBuiltin<"int(int, _Constant int)">; +def C4_fastcorner9 : HexagonBuiltin<"int(int, int)">; +def C4_fastcorner9_not : HexagonBuiltin<"int(int, int)">; +def C4_nbitsclr : HexagonBuiltin<"int(int, int)">; +def C4_nbitsclri : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def C4_nbitsset : HexagonBuiltin<"int(int, int)">; +def C4_or_and : HexagonBuiltin<"int(int, int, int)">; +def C4_or_andn : HexagonBuiltin<"int(int, int, int)">; +def C4_or_or : HexagonBuiltin<"int(int, int, int)">; +def C4_or_orn : HexagonBuiltin<"int(int, int, int)">; +def F2_conv_d2df : HexagonBuiltin<"double(long long int)">; +def F2_conv_d2sf : HexagonBuiltin<"float(long long int)">; +def F2_conv_df2d : HexagonBuiltin<"long long int(double)">; +def F2_conv_df2d_chop : HexagonBuiltin<"long long int(double)">; +def F2_conv_df2sf : HexagonBuiltin<"float(double)">; +def F2_conv_df2ud : HexagonBuiltin<"long long int(double)">; +def F2_conv_df2ud_chop : HexagonBuiltin<"long long int(double)">; +def F2_conv_df2uw : HexagonBuiltin<"int(double)">; +def F2_conv_df2uw_chop : HexagonBuiltin<"int(double)">; +def F2_conv_df2w : HexagonBuiltin<"int(double)">; +def F2_conv_df2w_chop : HexagonBuiltin<"int(double)">; +def F2_conv_sf2d : HexagonBuiltin<"long long int(float)">; +def F2_conv_sf2d_chop : HexagonBuiltin<"long long int(float)">; +def F2_conv_sf2df : HexagonBuiltin<"double(float)">; +def F2_conv_sf2ud : HexagonBuiltin<"long long int(float)">; +def F2_conv_sf2ud_chop : HexagonBuiltin<"long long int(float)">; +def F2_conv_sf2uw : HexagonBuiltin<"int(float)">; +def F2_conv_sf2uw_chop : HexagonBuiltin<"int(float)">; +def F2_conv_sf2w : HexagonBuiltin<"int(float)">; +def F2_conv_sf2w_chop : HexagonBuiltin<"int(float)">; +def F2_conv_ud2df : HexagonBuiltin<"double(long long int)">; +def F2_conv_ud2sf : HexagonBuiltin<"float(long long int)">; +def F2_conv_uw2df : HexagonBuiltin<"double(int)">; +def F2_conv_uw2sf : HexagonBuiltin<"float(int)">; +def F2_conv_w2df : HexagonBuiltin<"double(int)">; +def F2_conv_w2sf : HexagonBuiltin<"float(int)">; +def F2_dfclass : HexagonBuiltin<"int(double, unsigned _Constant int)">; +def F2_dfcmpeq : HexagonBuiltin<"int(double, double)">; +def F2_dfcmpge : HexagonBuiltin<"int(double, double)">; +def F2_dfcmpgt : HexagonBuiltin<"int(double, double)">; +def F2_dfcmpuo : HexagonBuiltin<"int(double, double)">; +def F2_dfimm_n : HexagonBuiltin<"double(unsigned _Constant int)">; +def F2_dfimm_p : HexagonBuiltin<"double(unsigned _Constant int)">; +def F2_sfadd : HexagonBuiltin<"float(float, float)">; +def F2_sfclass : HexagonBuiltin<"int(float, unsigned _Constant int)">; +def F2_sfcmpeq : HexagonBuiltin<"int(float, float)">; +def F2_sfcmpge : HexagonBuiltin<"int(float, float)">; +def F2_sfcmpgt : HexagonBuiltin<"int(float, float)">; +def F2_sfcmpuo : HexagonBuiltin<"int(float, float)">; +def F2_sffixupd : HexagonBuiltin<"float(float, float)">; +def F2_sffixupn : HexagonBuiltin<"float(float, float)">; +def F2_sffixupr : HexagonBuiltin<"float(float)">; +def F2_sffma : HexagonBuiltin<"float(float, float, float)">; +def F2_sffma_lib : HexagonBuiltin<"float(float, float, float)">; +def F2_sffma_sc : HexagonBuiltin<"float(float, float, float, int)">; +def F2_sffms : HexagonBuiltin<"float(float, float, float)">; +def F2_sffms_lib : HexagonBuiltin<"float(float, float, float)">; +def F2_sfimm_n : HexagonBuiltin<"float(unsigned _Constant int)">; +def F2_sfimm_p : HexagonBuiltin<"float(unsigned _Constant int)">; +def F2_sfmax : HexagonBuiltin<"float(float, float)">; +def F2_sfmin : HexagonBuiltin<"float(float, float)">; +def F2_sfmpy : HexagonBuiltin<"float(float, float)">; +def F2_sfsub : HexagonBuiltin<"float(float, float)">; +def M2_acci : HexagonBuiltin<"int(int, int, int)">; +def M2_accii : HexagonBuiltin<"int(int, int, _Constant int)">; +def M2_cmaci_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cmacr_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cmacs_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cmacs_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cmacsc_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cmacsc_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cmpyi_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_cmpyr_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_cmpyrs_s0 : HexagonBuiltin<"int(int, int)">; +def M2_cmpyrs_s1 : HexagonBuiltin<"int(int, int)">; +def M2_cmpyrsc_s0 : HexagonBuiltin<"int(int, int)">; +def M2_cmpyrsc_s1 : HexagonBuiltin<"int(int, int)">; +def M2_cmpys_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_cmpys_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_cmpysc_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_cmpysc_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_cnacs_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cnacs_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cnacsc_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_cnacsc_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_dpmpyss_acc_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_dpmpyss_nac_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_dpmpyss_rnd_s0 : HexagonBuiltin<"int(int, int)">; +def M2_dpmpyss_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_dpmpyuu_acc_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_dpmpyuu_nac_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_dpmpyuu_s0 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_hmmpyh_rs1 : HexagonBuiltin<"int(int, int)">; +def M2_hmmpyh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_hmmpyl_rs1 : HexagonBuiltin<"int(int, int)">; +def M2_hmmpyl_s1 : HexagonBuiltin<"int(int, int)">; +def M2_maci : HexagonBuiltin<"int(int, int, int)">; +def M2_macsin : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def M2_macsip : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def M2_mmachs_rs0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmachs_rs1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmachs_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmachs_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacls_rs0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacls_rs1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacls_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacls_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacuhs_rs0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacuhs_rs1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacuhs_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmacuhs_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmaculs_rs0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmaculs_rs1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmaculs_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmaculs_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_mmpyh_rs0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyh_rs1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyh_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyh_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyl_rs0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyl_rs1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyl_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyl_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyuh_rs0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyuh_rs1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyuh_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyuh_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyul_rs0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyul_rs1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyul_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mmpyul_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_mpy_acc_hh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_hh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_hl_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_hl_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_lh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_lh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_ll_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_ll_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_hh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_hh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_hl_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_hl_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_lh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_lh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_ll_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_acc_sat_ll_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_hh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_hh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_hl_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_hl_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_lh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_lh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_ll_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_ll_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_nac_hh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_hh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_hl_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_hl_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_lh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_lh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_ll_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_ll_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_hh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_hh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_hl_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_hl_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_lh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_lh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_ll_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_nac_sat_ll_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpy_rnd_hh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_rnd_hh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_rnd_hl_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_rnd_hl_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_rnd_lh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_rnd_lh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_rnd_ll_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_rnd_ll_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_hh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_hh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_hl_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_hl_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_lh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_lh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_ll_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_ll_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_hh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_hh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_hl_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_hl_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_lh_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_lh_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_ll_s0 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_sat_rnd_ll_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_up : HexagonBuiltin<"int(int, int)">; +def M2_mpy_up_s1 : HexagonBuiltin<"int(int, int)">; +def M2_mpy_up_s1_sat : HexagonBuiltin<"int(int, int)">; +def M2_mpyd_acc_hh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_acc_hh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_acc_hl_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_acc_hl_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_acc_lh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_acc_lh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_acc_ll_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_acc_ll_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_hh_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_hh_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_hl_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_hl_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_lh_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_lh_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_ll_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_ll_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_nac_hh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_nac_hh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_nac_hl_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_nac_hl_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_nac_lh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_nac_lh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_nac_ll_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_nac_ll_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyd_rnd_hh_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_rnd_hh_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_rnd_hl_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_rnd_hl_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_rnd_lh_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_rnd_lh_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_rnd_ll_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyd_rnd_ll_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_mpyi : HexagonBuiltin<"int(int, int)">; +def M2_mpysmi : HexagonBuiltin<"int(int, _Constant int)">; +def M2_mpysu_up : HexagonBuiltin<"int(int, int)">; +def M2_mpyu_acc_hh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_acc_hh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_acc_hl_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_acc_hl_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_acc_lh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_acc_lh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_acc_ll_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_acc_ll_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_hh_s0 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_hh_s1 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_hl_s0 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_hl_s1 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_lh_s0 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_lh_s1 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_ll_s0 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_ll_s1 : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyu_nac_hh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_nac_hh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_nac_hl_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_nac_hl_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_nac_lh_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_nac_lh_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_nac_ll_s0 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_nac_ll_s1 : HexagonBuiltin<"int(int, int, int)">; +def M2_mpyu_up : HexagonBuiltin<"unsigned int(int, int)">; +def M2_mpyud_acc_hh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_acc_hh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_acc_hl_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_acc_hl_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_acc_lh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_acc_lh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_acc_ll_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_acc_ll_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_hh_s0 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_hh_s1 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_hl_s0 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_hl_s1 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_lh_s0 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_lh_s1 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_ll_s0 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_ll_s1 : HexagonBuiltin<"unsigned long long int(int, int)">; +def M2_mpyud_nac_hh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_nac_hh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_nac_hl_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_nac_hl_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_nac_lh_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_nac_lh_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_nac_ll_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyud_nac_ll_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_mpyui : HexagonBuiltin<"int(int, int)">; +def M2_nacci : HexagonBuiltin<"int(int, int, int)">; +def M2_naccii : HexagonBuiltin<"int(int, int, _Constant int)">; +def M2_subacc : HexagonBuiltin<"int(int, int, int)">; +def M2_vabsdiffh : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vabsdiffw : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vcmac_s0_sat_i : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vcmac_s0_sat_r : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vcmpy_s0_sat_i : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vcmpy_s0_sat_r : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vcmpy_s1_sat_i : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vcmpy_s1_sat_r : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vdmacs_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vdmacs_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vdmpyrs_s0 : HexagonBuiltin<"int(long long int, long long int)">; +def M2_vdmpyrs_s1 : HexagonBuiltin<"int(long long int, long long int)">; +def M2_vdmpys_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vdmpys_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vmac2 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_vmac2es : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vmac2es_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vmac2es_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vmac2s_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_vmac2s_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_vmac2su_s0 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_vmac2su_s1 : HexagonBuiltin<"long long int(long long int, int, int)">; +def M2_vmpy2es_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vmpy2es_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vmpy2s_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_vmpy2s_s0pack : HexagonBuiltin<"int(int, int)">; +def M2_vmpy2s_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_vmpy2s_s1pack : HexagonBuiltin<"int(int, int)">; +def M2_vmpy2su_s0 : HexagonBuiltin<"long long int(int, int)">; +def M2_vmpy2su_s1 : HexagonBuiltin<"long long int(int, int)">; +def M2_vraddh : HexagonBuiltin<"int(long long int, long long int)">; +def M2_vradduh : HexagonBuiltin<"int(long long int, long long int)">; +def M2_vrcmaci_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vrcmaci_s0c : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vrcmacr_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vrcmacr_s0c : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vrcmpyi_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vrcmpyi_s0c : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vrcmpyr_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vrcmpyr_s0c : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_vrcmpys_acc_s1 : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def M2_vrcmpys_s1 : HexagonBuiltin<"long long int(long long int, int)">; +def M2_vrcmpys_s1rp : HexagonBuiltin<"int(long long int, int)">; +def M2_vrmac_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M2_vrmpy_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M2_xor_xacc : HexagonBuiltin<"int(int, int, int)">; +def M4_and_and : HexagonBuiltin<"int(int, int, int)">; +def M4_and_andn : HexagonBuiltin<"int(int, int, int)">; +def M4_and_or : HexagonBuiltin<"int(int, int, int)">; +def M4_and_xor : HexagonBuiltin<"int(int, int, int)">; +def M4_cmpyi_wh : HexagonBuiltin<"int(long long int, int)">; +def M4_cmpyi_whc : HexagonBuiltin<"int(long long int, int)">; +def M4_cmpyr_wh : HexagonBuiltin<"int(long long int, int)">; +def M4_cmpyr_whc : HexagonBuiltin<"int(long long int, int)">; +def M4_mac_up_s1_sat : HexagonBuiltin<"int(int, int, int)">; +def M4_mpyri_addi : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def M4_mpyri_addr : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def M4_mpyri_addr_u2 : HexagonBuiltin<"int(int, unsigned _Constant int, int)">; +def M4_mpyrr_addi : HexagonBuiltin<"int(unsigned _Constant int, int, int)">; +def M4_mpyrr_addr : HexagonBuiltin<"int(int, int, int)">; +def M4_nac_up_s1_sat : HexagonBuiltin<"int(int, int, int)">; +def M4_or_and : HexagonBuiltin<"int(int, int, int)">; +def M4_or_andn : HexagonBuiltin<"int(int, int, int)">; +def M4_or_or : HexagonBuiltin<"int(int, int, int)">; +def M4_or_xor : HexagonBuiltin<"int(int, int, int)">; +def M4_pmpyw : HexagonBuiltin<"long long int(int, int)">; +def M4_pmpyw_acc : HexagonBuiltin<"long long int(long long int, int, int)">; +def M4_vpmpyh : HexagonBuiltin<"long long int(int, int)">; +def M4_vpmpyh_acc : HexagonBuiltin<"long long int(long long int, int, int)">; +def M4_vrmpyeh_acc_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M4_vrmpyeh_acc_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M4_vrmpyeh_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M4_vrmpyeh_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M4_vrmpyoh_acc_s0 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M4_vrmpyoh_acc_s1 : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M4_vrmpyoh_s0 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M4_vrmpyoh_s1 : HexagonBuiltin<"long long int(long long int, long long int)">; +def M4_xor_and : HexagonBuiltin<"int(int, int, int)">; +def M4_xor_andn : HexagonBuiltin<"int(int, int, int)">; +def M4_xor_or : HexagonBuiltin<"int(int, int, int)">; +def M4_xor_xacc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M5_vdmacbsu : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M5_vdmpybsu : HexagonBuiltin<"long long int(long long int, long long int)">; +def M5_vmacbsu : HexagonBuiltin<"long long int(long long int, int, int)">; +def M5_vmacbuu : HexagonBuiltin<"long long int(long long int, int, int)">; +def M5_vmpybsu : HexagonBuiltin<"long long int(int, int)">; +def M5_vmpybuu : HexagonBuiltin<"long long int(int, int)">; +def M5_vrmacbsu : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M5_vrmacbuu : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def M5_vrmpybsu : HexagonBuiltin<"long long int(long long int, long long int)">; +def M5_vrmpybuu : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_addasl_rrri : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asl_i_p : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asl_i_p_acc : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asl_i_p_and : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asl_i_p_nac : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asl_i_p_or : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asl_i_p_xacc : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asl_i_r : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_asl_i_r_acc : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asl_i_r_and : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asl_i_r_nac : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asl_i_r_or : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asl_i_r_sat : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_asl_i_r_xacc : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asl_i_vh : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asl_i_vw : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asl_r_p : HexagonBuiltin<"long long int(long long int, int)">; +def S2_asl_r_p_acc : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asl_r_p_and : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asl_r_p_nac : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asl_r_p_or : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asl_r_p_xor : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asl_r_r : HexagonBuiltin<"int(int, int)">; +def S2_asl_r_r_acc : HexagonBuiltin<"int(int, int, int)">; +def S2_asl_r_r_and : HexagonBuiltin<"int(int, int, int)">; +def S2_asl_r_r_nac : HexagonBuiltin<"int(int, int, int)">; +def S2_asl_r_r_or : HexagonBuiltin<"int(int, int, int)">; +def S2_asl_r_r_sat : HexagonBuiltin<"int(int, int)">; +def S2_asl_r_vh : HexagonBuiltin<"long long int(long long int, int)">; +def S2_asl_r_vw : HexagonBuiltin<"long long int(long long int, int)">; +def S2_asr_i_p : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asr_i_p_acc : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asr_i_p_and : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asr_i_p_nac : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asr_i_p_or : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_asr_i_p_rnd : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asr_i_p_rnd_goodsyntax : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asr_i_r : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_asr_i_r_acc : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asr_i_r_and : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asr_i_r_nac : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asr_i_r_or : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_asr_i_r_rnd : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_asr_i_r_rnd_goodsyntax : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_asr_i_svw_trun : HexagonBuiltin<"int(long long int, unsigned _Constant int)">; +def S2_asr_i_vh : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asr_i_vw : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_asr_r_p : HexagonBuiltin<"long long int(long long int, int)">; +def S2_asr_r_p_acc : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asr_r_p_and : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asr_r_p_nac : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asr_r_p_or : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asr_r_p_xor : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_asr_r_r : HexagonBuiltin<"int(int, int)">; +def S2_asr_r_r_acc : HexagonBuiltin<"int(int, int, int)">; +def S2_asr_r_r_and : HexagonBuiltin<"int(int, int, int)">; +def S2_asr_r_r_nac : HexagonBuiltin<"int(int, int, int)">; +def S2_asr_r_r_or : HexagonBuiltin<"int(int, int, int)">; +def S2_asr_r_r_sat : HexagonBuiltin<"int(int, int)">; +def S2_asr_r_svw_trun : HexagonBuiltin<"int(long long int, int)">; +def S2_asr_r_vh : HexagonBuiltin<"long long int(long long int, int)">; +def S2_asr_r_vw : HexagonBuiltin<"long long int(long long int, int)">; +def S2_brev : HexagonBuiltin<"int(int)">; +def S2_brevp : HexagonBuiltin<"long long int(long long int)">; +def S2_cl0 : HexagonBuiltin<"int(int)">; +def S2_cl0p : HexagonBuiltin<"int(long long int)">; +def S2_cl1 : HexagonBuiltin<"int(int)">; +def S2_cl1p : HexagonBuiltin<"int(long long int)">; +def S2_clb : HexagonBuiltin<"int(int)">; +def S2_clbnorm : HexagonBuiltin<"int(int)">; +def S2_clbp : HexagonBuiltin<"int(long long int)">; +def S2_clrbit_i : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_clrbit_r : HexagonBuiltin<"int(int, int)">; +def S2_ct0 : HexagonBuiltin<"int(int)">; +def S2_ct0p : HexagonBuiltin<"int(long long int)">; +def S2_ct1 : HexagonBuiltin<"int(int)">; +def S2_ct1p : HexagonBuiltin<"int(long long int)">; +def S2_deinterleave : HexagonBuiltin<"long long int(long long int)">; +def S2_extractu : HexagonBuiltin<"int(int, unsigned _Constant int, unsigned _Constant int)">; +def S2_extractu_rp : HexagonBuiltin<"int(int, long long int)">; +def S2_extractup : HexagonBuiltin<"long long int(long long int, unsigned _Constant int, unsigned _Constant int)">; +def S2_extractup_rp : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_insert : HexagonBuiltin<"int(int, int, unsigned _Constant int, unsigned _Constant int)">; +def S2_insert_rp : HexagonBuiltin<"int(int, int, long long int)">; +def S2_insertp : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int, unsigned _Constant int)">; +def S2_insertp_rp : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +def S2_interleave : HexagonBuiltin<"long long int(long long int)">; +def S2_lfsp : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_lsl_r_p : HexagonBuiltin<"long long int(long long int, int)">; +def S2_lsl_r_p_acc : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsl_r_p_and : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsl_r_p_nac : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsl_r_p_or : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsl_r_p_xor : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsl_r_r : HexagonBuiltin<"int(int, int)">; +def S2_lsl_r_r_acc : HexagonBuiltin<"int(int, int, int)">; +def S2_lsl_r_r_and : HexagonBuiltin<"int(int, int, int)">; +def S2_lsl_r_r_nac : HexagonBuiltin<"int(int, int, int)">; +def S2_lsl_r_r_or : HexagonBuiltin<"int(int, int, int)">; +def S2_lsl_r_vh : HexagonBuiltin<"long long int(long long int, int)">; +def S2_lsl_r_vw : HexagonBuiltin<"long long int(long long int, int)">; +def S2_lsr_i_p : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_lsr_i_p_acc : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_lsr_i_p_and : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_lsr_i_p_nac : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_lsr_i_p_or : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_lsr_i_p_xacc : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_lsr_i_r : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_lsr_i_r_acc : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_lsr_i_r_and : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_lsr_i_r_nac : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_lsr_i_r_or : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_lsr_i_r_xacc : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +def S2_lsr_i_vh : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_lsr_i_vw : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def S2_lsr_r_p : HexagonBuiltin<"long long int(long long int, int)">; +def S2_lsr_r_p_acc : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsr_r_p_and : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsr_r_p_nac : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsr_r_p_or : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsr_r_p_xor : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_lsr_r_r : HexagonBuiltin<"int(int, int)">; +def S2_lsr_r_r_acc : HexagonBuiltin<"int(int, int, int)">; +def S2_lsr_r_r_and : HexagonBuiltin<"int(int, int, int)">; +def S2_lsr_r_r_nac : HexagonBuiltin<"int(int, int, int)">; +def S2_lsr_r_r_or : HexagonBuiltin<"int(int, int, int)">; +def S2_lsr_r_vh : HexagonBuiltin<"long long int(long long int, int)">; +def S2_lsr_r_vw : HexagonBuiltin<"long long int(long long int, int)">; +def S2_packhl : HexagonBuiltin<"long long int(int, int)">; +def S2_parityp : HexagonBuiltin<"int(long long int, long long int)">; +def S2_setbit_i : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_setbit_r : HexagonBuiltin<"int(int, int)">; +def S2_shuffeb : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_shuffeh : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_shuffob : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_shuffoh : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_svsathb : HexagonBuiltin<"int(int)">; +def S2_svsathub : HexagonBuiltin<"int(int)">; +def S2_tableidxb_goodsyntax : HexagonBuiltin<"int(int, int, unsigned _Constant int, unsigned _Constant int)">; +def S2_tableidxd_goodsyntax : HexagonBuiltin<"int(int, int, unsigned _Constant int, unsigned _Constant int)">; +def S2_tableidxh_goodsyntax : HexagonBuiltin<"int(int, int, unsigned _Constant int, unsigned _Constant int)">; +def S2_tableidxw_goodsyntax : HexagonBuiltin<"int(int, int, unsigned _Constant int, unsigned _Constant int)">; +def S2_togglebit_i : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_togglebit_r : HexagonBuiltin<"int(int, int)">; +def S2_tstbit_i : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S2_tstbit_r : HexagonBuiltin<"int(int, int)">; +def S2_valignib : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_valignrb : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_vcnegh : HexagonBuiltin<"long long int(long long int, int)">; +def S2_vcrotate : HexagonBuiltin<"long long int(long long int, int)">; +def S2_vrcnegh : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_vrndpackwh : HexagonBuiltin<"int(long long int)">; +def S2_vrndpackwhs : HexagonBuiltin<"int(long long int)">; +def S2_vsathb : HexagonBuiltin<"int(long long int)">; +def S2_vsathb_nopack : HexagonBuiltin<"long long int(long long int)">; +def S2_vsathub : HexagonBuiltin<"int(long long int)">; +def S2_vsathub_nopack : HexagonBuiltin<"long long int(long long int)">; +def S2_vsatwh : HexagonBuiltin<"int(long long int)">; +def S2_vsatwh_nopack : HexagonBuiltin<"long long int(long long int)">; +def S2_vsatwuh : HexagonBuiltin<"int(long long int)">; +def S2_vsatwuh_nopack : HexagonBuiltin<"long long int(long long int)">; +def S2_vsplatrb : HexagonBuiltin<"int(int)">; +def S2_vsplatrh : HexagonBuiltin<"long long int(int)">; +def S2_vspliceib : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; +def S2_vsplicerb : HexagonBuiltin<"long long int(long long int, long long int, int)">; +def S2_vsxtbh : HexagonBuiltin<"long long int(int)">; +def S2_vsxthw : HexagonBuiltin<"long long int(int)">; +def S2_vtrunehb : HexagonBuiltin<"int(long long int)">; +def S2_vtrunewh : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_vtrunohb : HexagonBuiltin<"int(long long int)">; +def S2_vtrunowh : HexagonBuiltin<"long long int(long long int, long long int)">; +def S2_vzxtbh : HexagonBuiltin<"long long int(int)">; +def S2_vzxthw : HexagonBuiltin<"long long int(int)">; +def S4_addaddi : HexagonBuiltin<"int(int, int, _Constant int)">; +def S4_addi_asl_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_addi_lsr_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_andi_asl_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_andi_lsr_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_clbaddi : HexagonBuiltin<"int(int, _Constant int)">; +def S4_clbpaddi : HexagonBuiltin<"int(long long int, _Constant int)">; +def S4_clbpnorm : HexagonBuiltin<"int(long long int)">; +def S4_extract : HexagonBuiltin<"int(int, unsigned _Constant int, unsigned _Constant int)">; +def S4_extract_rp : HexagonBuiltin<"int(int, long long int)">; +def S4_extractp : HexagonBuiltin<"long long int(long long int, unsigned _Constant int, unsigned _Constant int)">; +def S4_extractp_rp : HexagonBuiltin<"long long int(long long int, long long int)">; +def S4_lsli : HexagonBuiltin<"int(_Constant int, int)">; +def S4_ntstbit_i : HexagonBuiltin<"int(int, unsigned _Constant int)">; +def S4_ntstbit_r : HexagonBuiltin<"int(int, int)">; +def S4_or_andi : HexagonBuiltin<"int(int, int, _Constant int)">; +def S4_or_andix : HexagonBuiltin<"int(int, int, _Constant int)">; +def S4_or_ori : HexagonBuiltin<"int(int, int, _Constant int)">; +def S4_ori_asl_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_ori_lsr_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_parity : HexagonBuiltin<"int(int, int)">; +def S4_subaddi : HexagonBuiltin<"int(int, _Constant int, int)">; +def S4_subi_asl_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_subi_lsr_ri : HexagonBuiltin<"int(unsigned _Constant int, int, unsigned _Constant int)">; +def S4_vrcrotate : HexagonBuiltin<"long long int(long long int, int, unsigned _Constant int)">; +def S4_vrcrotate_acc : HexagonBuiltin<"long long int(long long int, long long int, int, unsigned _Constant int)">; +def S4_vxaddsubh : HexagonBuiltin<"long long int(long long int, long long int)">; +def S4_vxaddsubhr : HexagonBuiltin<"long long int(long long int, long long int)">; +def S4_vxaddsubw : HexagonBuiltin<"long long int(long long int, long long int)">; +def S4_vxsubaddh : HexagonBuiltin<"long long int(long long int, long long int)">; +def S4_vxsubaddhr : HexagonBuiltin<"long long int(long long int, long long int)">; +def S4_vxsubaddw : HexagonBuiltin<"long long int(long long int, long long int)">; +def S5_asrhub_rnd_sat_goodsyntax : HexagonBuiltin<"int(long long int, unsigned _Constant int)">; +def S5_asrhub_sat : HexagonBuiltin<"int(long long int, unsigned _Constant int)">; +def S5_popcountp : HexagonBuiltin<"int(long long int)">; +def S5_vasrhrnd_goodsyntax : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +def Y2_dccleana : HexagonBuiltin<"void(void *)">; +def Y2_dccleaninva : HexagonBuiltin<"void(void *)">; +def Y2_dcfetch : HexagonBuiltin<"void(void *)">; +def Y2_dcinva : HexagonBuiltin<"void(void *)">; +def Y2_dczeroa : HexagonBuiltin<"void(void *)">; +def Y4_l2fetch : HexagonBuiltin<"void(void *, int)">; +def Y5_l2fetch : HexagonBuiltin<"void(void *, long long int)">; + +// V60 Scalar Instructions. + +let Features = V60.Features in { + def S6_rol_i_p : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; + def S6_rol_i_p_acc : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; + def S6_rol_i_p_and : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; + def S6_rol_i_p_nac : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; + def S6_rol_i_p_or : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; + def S6_rol_i_p_xacc : HexagonBuiltin<"long long int(long long int, long long int, unsigned _Constant int)">; + def S6_rol_i_r : HexagonBuiltin<"int(int, unsigned _Constant int)">; + def S6_rol_i_r_acc : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; + def S6_rol_i_r_and : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; + def S6_rol_i_r_nac : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; + def S6_rol_i_r_or : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; + def S6_rol_i_r_xacc : HexagonBuiltin<"int(int, int, unsigned _Constant int)">; +} + +// V62 Scalar Instructions. + +let Features = V62.Features in { + def M6_vabsdiffb : HexagonBuiltin<"long long int(long long int, long long int)">; + def M6_vabsdiffub : HexagonBuiltin<"long long int(long long int, long long int)">; + def S6_vsplatrbp : HexagonBuiltin<"long long int(int)">; + def S6_vtrunehb_ppp : HexagonBuiltin<"long long int(long long int, long long int)">; + def S6_vtrunohb_ppp : HexagonBuiltin<"long long int(long long int, long long int)">; +} + +// V65 Scalar Instructions. + +let Features = V65.Features in { + def A6_vcmpbeq_notany : HexagonBuiltin<"int(long long int, long long int)">; +} + +// V66 Scalar Instructions. + +let Features = V66.Features in { + def F2_dfadd : HexagonBuiltin<"double(double, double)">; + def F2_dfsub : HexagonBuiltin<"double(double, double)">; + def M2_mnaci : HexagonBuiltin<"int(int, int, int)">; + def S2_mask : HexagonBuiltin<"int(unsigned _Constant int, unsigned _Constant int)">; +} + +// V67 Scalar Instructions. + +let Features = "audio" in { + def A7_clip : HexagonBuiltin<"int(int, unsigned _Constant int)">; + def A7_croundd_ri : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; + def A7_croundd_rr : HexagonBuiltin<"long long int(long long int, int)">; + def A7_vclip : HexagonBuiltin<"long long int(long long int, unsigned _Constant int)">; +} +let Features = V67.Features in { + def F2_dfmax : HexagonBuiltin<"double(double, double)">; + def F2_dfmin : HexagonBuiltin<"double(double, double)">; + def F2_dfmpyfix : HexagonBuiltin<"double(double, double)">; + def F2_dfmpyhh : HexagonBuiltin<"double(double, double, double)">; + def F2_dfmpylh : HexagonBuiltin<"double(double, double, double)">; + def F2_dfmpyll : HexagonBuiltin<"double(double, double)">; +} +let Features = "audio" in { + def M7_dcmpyiw : HexagonBuiltin<"long long int(long long int, long long int)">; + def M7_dcmpyiw_acc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; + def M7_dcmpyiwc : HexagonBuiltin<"long long int(long long int, long long int)">; + def M7_dcmpyiwc_acc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; + def M7_dcmpyrw : HexagonBuiltin<"long long int(long long int, long long int)">; + def M7_dcmpyrw_acc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; + def M7_dcmpyrwc : HexagonBuiltin<"long long int(long long int, long long int)">; + def M7_dcmpyrwc_acc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +} +let Features = V67.Features in { + def M7_vdmpy : HexagonBuiltin<"long long int(long long int, long long int)">; + def M7_vdmpy_acc : HexagonBuiltin<"long long int(long long int, long long int, long long int)">; +} +let Features = "audio" in { + def M7_wcmpyiw : HexagonBuiltin<"int(long long int, long long int)">; + def M7_wcmpyiw_rnd : HexagonBuiltin<"int(long long int, long long int)">; + def M7_wcmpyiwc : HexagonBuiltin<"int(long long int, long long int)">; + def M7_wcmpyiwc_rnd : HexagonBuiltin<"int(long long int, long long int)">; + def M7_wcmpyrw : HexagonBuiltin<"int(long long int, long long int)">; + def M7_wcmpyrw_rnd : HexagonBuiltin<"int(long long int, long long int)">; + def M7_wcmpyrwc : HexagonBuiltin<"int(long long int, long long int)">; + def M7_wcmpyrwc_rnd : HexagonBuiltin<"int(long long int, long long int)">; +} + +// V68 Scalar Instructions. + +let Features = V68.Features in { + def Y6_dmlink : HexagonBuiltin<"void(void *, void *)">; + def Y6_dmpause : HexagonBuiltin<"int()">; + def Y6_dmpoll : HexagonBuiltin<"int()">; + def Y6_dmresume : HexagonBuiltin<"void(void *)">; + def Y6_dmstart : HexagonBuiltin<"void(void *)">; + def Y6_dmwait : HexagonBuiltin<"int()">; +} + +// V60 HVX Instructions. + +let Features = HVXV60.Features in { + def V6_extractw : HexagonBuiltin<"int(_Vector<16, int>, int)">; + def V6_extractw_128B : HexagonBuiltin<"int(_Vector<32, int>, int)">; + def V6_hi : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>)">; + def V6_hi_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>)">; + def V6_lo : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>)">; + def V6_lo_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>)">; + def V6_lvsplatw : HexagonBuiltin<"_Vector<16, int>(int)">; + def V6_lvsplatw_128B : HexagonBuiltin<"_Vector<32, int>(int)">; + def V6_pred_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<64, bool>)">; + def V6_pred_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<128, bool>)">; + def V6_pred_and_n : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<64, bool>)">; + def V6_pred_and_n_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<128, bool>)">; + def V6_pred_not : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>)">; + def V6_pred_not_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>)">; + def V6_pred_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<64, bool>)">; + def V6_pred_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<128, bool>)">; + def V6_pred_or_n : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<64, bool>)">; + def V6_pred_or_n_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<128, bool>)">; + def V6_pred_scalar2 : HexagonBuiltin<"_Vector<64, bool>(int)">; + def V6_pred_scalar2_128B : HexagonBuiltin<"_Vector<128, bool>(int)">; + def V6_pred_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<64, bool>)">; + def V6_pred_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<128, bool>)">; + def V6_vS32b_nqpred_ai : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vS32b_nqpred_ai_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; + def V6_vS32b_nt_nqpred_ai : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vS32b_nt_nqpred_ai_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; + def V6_vS32b_nt_qpred_ai : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vS32b_nt_qpred_ai_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; + def V6_vS32b_qpred_ai : HexagonBuiltin<"void(_Vector<64, bool>, void *, _Vector<16, int>)">; + def V6_vS32b_qpred_ai_128B : HexagonBuiltin<"void(_Vector<128, bool>, void *, _Vector<32, int>)">; + def V6_vabsdiffh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vabsdiffh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vabsdiffub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vabsdiffub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vabsdiffuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vabsdiffuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vabsdiffw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vabsdiffw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vabsh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabsh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabsh_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabsh_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabsw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabsw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabsw_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabsw_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vaddb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddb_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddb_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vaddbnq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddbnq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddbq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddbq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddh_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddh_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vaddhnq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddhnq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddhq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddhq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddhsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddhsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vaddhw : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddhw_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddubh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddubh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddubsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddubsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddubsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddubsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vadduhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadduhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadduhsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadduhsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vadduhw : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadduhw_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddw_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddw_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vaddwnq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddwnq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddwq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddwq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddwsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddwsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddwsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddwsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_valignb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_valignb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_valignbi : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, unsigned _Constant int)">; + def V6_valignbi_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_vand : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vand_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vandqrt : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, int)">; + def V6_vandqrt_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, int)">; + def V6_vandqrt_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<64, bool>, int)">; + def V6_vandqrt_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<128, bool>, int)">; + def V6_vandvrt : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, int)">; + def V6_vandvrt_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, int)">; + def V6_vandvrt_acc : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, int)">; + def V6_vandvrt_acc_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, int)">; + def V6_vaslh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vaslh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vaslhv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaslhv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaslw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vaslw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vaslw_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vaslw_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vaslwv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaslwv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vasrh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vasrh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vasrhbrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrhbrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrhubrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrhubrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrhubsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrhubsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrhv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vasrhv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vasrw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vasrw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vasrw_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrw_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrwh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrwh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrwhrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrwhrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrwhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrwhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrwuhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrwuhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrwv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vasrwv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vassign : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vassign_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vassignp : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vassignp_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>)">; + def V6_vavgh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavgh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavghrnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavghrnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavgub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavgub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavgubrnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavgubrnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavguh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavguh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavguhrnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavguhrnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavgw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavgw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavgwrnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavgwrnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcl0h : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vcl0h_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vcl0w : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vcl0w_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vcombine : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcombine_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vd0 : HexagonBuiltin<"_Vector<16, int>()">; + def V6_vd0_128B : HexagonBuiltin<"_Vector<32, int>()">; + def V6_vdealb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vdealb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vdealb4w : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vdealb4w_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vdealh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vdealh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vdealvdd : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vdealvdd_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdelta : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vdelta_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vdmpybus : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vdmpybus_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vdmpybus_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vdmpybus_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdmpybus_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vdmpybus_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vdmpybus_dv_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdmpybus_dv_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vdmpyhb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vdmpyhb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vdmpyhb_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vdmpyhb_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdmpyhb_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vdmpyhb_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vdmpyhb_dv_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdmpyhb_dv_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vdmpyhisat : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>, int)">; + def V6_vdmpyhisat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>, int)">; + def V6_vdmpyhisat_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, int>, int)">; + def V6_vdmpyhisat_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<64, int>, int)">; + def V6_vdmpyhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vdmpyhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vdmpyhsat_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vdmpyhsat_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdmpyhsuisat : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>, int)">; + def V6_vdmpyhsuisat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>, int)">; + def V6_vdmpyhsuisat_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<32, int>, int)">; + def V6_vdmpyhsuisat_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<64, int>, int)">; + def V6_vdmpyhsusat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vdmpyhsusat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vdmpyhsusat_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vdmpyhsusat_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdmpyhvsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vdmpyhvsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vdmpyhvsat_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vdmpyhvsat_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vdsaduh : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vdsaduh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vdsaduh_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vdsaduh_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_veqb : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_veqb_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_veqb_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqb_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqb_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqb_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqb_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqb_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqh : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_veqh_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_veqh_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqh_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqh_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqh_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqh_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqh_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqw : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_veqw_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_veqw_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqw_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqw_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqw_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_veqw_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_veqw_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtb : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgtb_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtb_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtb_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtb_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtb_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtb_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtb_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgth : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgth_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgth_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgth_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgth_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgth_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgth_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgth_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtub : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgtub_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtub_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtub_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtub_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtub_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtub_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtub_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuh : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuh_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuh_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuh_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuh_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuh_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuh_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuh_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuw : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuw_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuw_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuw_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuw_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuw_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtuw_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtuw_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtw : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgtw_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtw_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtw_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtw_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtw_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtw_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtw_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vinsertwr : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vinsertwr_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vlalignb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vlalignb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vlalignbi : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, unsigned _Constant int)">; + def V6_vlalignbi_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_vlsrh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vlsrh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vlsrhv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vlsrhv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vlsrw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vlsrw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vlsrwv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vlsrwv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vlutvvb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vlutvvb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vlutvvb_oracc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>, int)">; + def V6_vlutvvb_oracc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>, int)">; + def V6_vlutvwh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vlutvwh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vlutvwh_oracc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>, int)">; + def V6_vlutvwh_oracc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmaxh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmaxh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmaxub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmaxub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmaxuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmaxuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmaxw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmaxw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vminh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vminh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vminub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vminub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vminuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vminuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vminw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vminw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpabus : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpabus_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vmpabus_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpabus_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vmpabusv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpabusv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vmpabuuv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpabuuv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vmpahb : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpahb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vmpahb_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpahb_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vmpybus : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, int)">; + def V6_vmpybus_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, int)">; + def V6_vmpybus_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, int)">; + def V6_vmpybus_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, int)">; + def V6_vmpybusv : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpybusv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpybusv_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpybusv_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpybv : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpybv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpybv_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpybv_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyewuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyewuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, int)">; + def V6_vmpyh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, int)">; + def V6_vmpyhsat_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, int)">; + def V6_vmpyhsat_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, int)">; + def V6_vmpyhsrs : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpyhsrs_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpyhss : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpyhss_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpyhus : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyhus_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyhus_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyhus_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyhv : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyhv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyhv_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyhv_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyhvsrs : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyhvsrs_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyieoh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyieoh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyiewh_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyiewh_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyiewuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyiewuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyiewuh_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyiewuh_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyih : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyih_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyih_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyih_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyihb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpyihb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpyihb_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vmpyihb_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpyiowh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyiowh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyiwb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpyiwb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpyiwb_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vmpyiwb_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpyiwh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpyiwh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpyiwh_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vmpyiwh_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpyowh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyowh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyowh_rnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyowh_rnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyowh_rnd_sacc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyowh_rnd_sacc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyowh_sacc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyowh_sacc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyub : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, int)">; + def V6_vmpyub_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, int)">; + def V6_vmpyub_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, int)">; + def V6_vmpyub_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, int)">; + def V6_vmpyubv : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyubv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyubv_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyubv_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyuh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, int)">; + def V6_vmpyuh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, int)">; + def V6_vmpyuh_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, int)">; + def V6_vmpyuh_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, int)">; + def V6_vmpyuhv : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyuhv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyuhv_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyuhv_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmux : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmux_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vnavgh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vnavgh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vnavgub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vnavgub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vnavgw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vnavgw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vnormamth : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vnormamth_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vnormamtw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vnormamtw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vnot : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vnot_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vor : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vor_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackeb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackeb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackeh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackeh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackhb_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackhb_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackhub_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackhub_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackob : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackob_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackoh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackoh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackwh_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackwh_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpackwuh_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vpackwuh_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vpopcounth : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vpopcounth_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vrdelta : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vrdelta_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vrmpybus : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vrmpybus_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vrmpybus_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vrmpybus_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vrmpybusi : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int, unsigned _Constant int)">; + def V6_vrmpybusi_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int, unsigned _Constant int)">; + def V6_vrmpybusi_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int, unsigned _Constant int)">; + def V6_vrmpybusi_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int, unsigned _Constant int)">; + def V6_vrmpybusv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vrmpybusv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vrmpybusv_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vrmpybusv_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vrmpybv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vrmpybv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vrmpybv_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vrmpybv_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vrmpyub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vrmpyub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vrmpyub_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vrmpyub_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vrmpyubi : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int, unsigned _Constant int)">; + def V6_vrmpyubi_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int, unsigned _Constant int)">; + def V6_vrmpyubi_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int, unsigned _Constant int)">; + def V6_vrmpyubi_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int, unsigned _Constant int)">; + def V6_vrmpyubv : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vrmpyubv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vrmpyubv_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vrmpyubv_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vror : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vror_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vroundhb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vroundhb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vroundhub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vroundhub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vroundwh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vroundwh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vroundwuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vroundwuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vrsadubi : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int, unsigned _Constant int)">; + def V6_vrsadubi_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int, unsigned _Constant int)">; + def V6_vrsadubi_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int, unsigned _Constant int)">; + def V6_vrsadubi_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int, unsigned _Constant int)">; + def V6_vsathub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsathub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsatwh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsatwh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsb : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vsb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vsh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vsh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vshufeh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vshufeh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vshuffb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vshuffb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vshuffeb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vshuffeb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vshuffh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vshuffh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vshuffob : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vshuffob_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vshuffvdd : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vshuffvdd_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vshufoeb : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vshufoeb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vshufoeh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vshufoeh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vshufoh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vshufoh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubb_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubb_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vsubbnq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vsubbnq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vsubbq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vsubbq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vsubh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubh_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubh_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vsubhnq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vsubhnq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vsubhq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vsubhq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vsubhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubhsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubhsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vsubhw : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubhw_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsububh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsububh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsububsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsububsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsububsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsububsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vsubuhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubuhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubuhsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubuhsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vsubuhw : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubuhw_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubw_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubw_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vsubwnq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vsubwnq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vsubwq : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vsubwq_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vsubwsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubwsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubwsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubwsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vswap : HexagonBuiltin<"_Vector<32, int>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vswap_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vtmpyb : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vtmpyb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vtmpyb_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vtmpyb_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vtmpybus : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vtmpybus_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vtmpybus_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vtmpybus_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vtmpyhb : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vtmpyhb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vtmpyhb_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vtmpyhb_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vunpackb : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vunpackb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vunpackh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vunpackh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vunpackob : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>)">; + def V6_vunpackob_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>)">; + def V6_vunpackoh : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>)">; + def V6_vunpackoh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>)">; + def V6_vunpackub : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vunpackub_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vunpackuh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vunpackuh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vxor : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vxor_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vzb : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vzb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vzh : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vzh_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; +} + +// V62 HVX Instructions. + +let Features = HVXV62.Features in { + def V6_lvsplatb : HexagonBuiltin<"_Vector<16, int>(int)">; + def V6_lvsplatb_128B : HexagonBuiltin<"_Vector<32, int>(int)">; + def V6_lvsplath : HexagonBuiltin<"_Vector<16, int>(int)">; + def V6_lvsplath_128B : HexagonBuiltin<"_Vector<32, int>(int)">; + def V6_pred_scalar2v2 : HexagonBuiltin<"_Vector<64, bool>(int)">; + def V6_pred_scalar2v2_128B : HexagonBuiltin<"_Vector<128, bool>(int)">; + def V6_shuffeqh : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<64, bool>)">; + def V6_shuffeqh_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<128, bool>)">; + def V6_shuffeqw : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<64, bool>)">; + def V6_shuffeqw_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<128, bool>)">; + def V6_vaddbsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddbsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddbsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddbsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vaddcarry : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, void *)">; + def V6_vaddcarry_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, void *)">; + def V6_vaddclbh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddclbh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddclbw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddclbw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vaddhw_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddhw_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddubh_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vaddubh_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vaddububb_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vaddububb_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadduhw_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vadduhw_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vadduwsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadduwsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadduwsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadduwsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vandnqrt : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, int)">; + def V6_vandnqrt_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, int)">; + def V6_vandnqrt_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<64, bool>, int)">; + def V6_vandnqrt_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<128, bool>, int)">; + def V6_vandvnqv : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>)">; + def V6_vandvnqv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>)">; + def V6_vandvqv : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>, _Vector<16, int>)">; + def V6_vandvqv_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>, _Vector<32, int>)">; + def V6_vasrhbsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrhbsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasruwuhrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasruwuhrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrwuhrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrwuhrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vlsrb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vlsrb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vlutvvb_nm : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vlutvvb_nm_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vlutvvb_oracci : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>, unsigned _Constant int)">; + def V6_vlutvvb_oracci_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_vlutvvbi : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, unsigned _Constant int)">; + def V6_vlutvvbi_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_vlutvwh_nm : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vlutvwh_nm_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vlutvwh_oracci : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>, unsigned _Constant int)">; + def V6_vlutvwh_oracci_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_vlutvwhi : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>, unsigned _Constant int)">; + def V6_vlutvwhi_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_vmaxb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmaxb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vminb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vminb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpauhb : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpauhb_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vmpauhb_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpauhb_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vmpyewuh_64 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyewuh_64_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpyiwub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpyiwub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpyiwub_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vmpyiwub_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpyowh_64_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyowh_64_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vrounduhub : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vrounduhub_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vrounduwuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vrounduwuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsatuwuh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsatuwuh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubbsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubbsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubbsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubbsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; + def V6_vsubcarry : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, void *)">; + def V6_vsubcarry_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, void *)">; + def V6_vsubububb_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubububb_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubuwsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsubuwsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubuwsat_dv : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubuwsat_dv_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>)">; +} + +// V65 HVX Instructions. + +let Features = HVXV65.Features in { + def V6_vabsb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabsb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabsb_sat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabsb_sat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vaslh_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vaslh_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasrh_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasrh_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasruhubrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasruhubrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasruhubsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasruhubsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vasruwuhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vasruwuhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vavgb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavgb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavgbrnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavgbrnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavguw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavguw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vavguwrnd : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vavguwrnd_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vdd0 : HexagonBuiltin<"_Vector<32, int>()">; + def V6_vdd0_128B : HexagonBuiltin<"_Vector<64, int>()">; + def V6_vgathermh : HexagonBuiltin<"void(void *, int, int, _Vector<16, int>)">; + def V6_vgathermh_128B : HexagonBuiltin<"void(void *, int, int, _Vector<32, int>)">; + def V6_vgathermhq : HexagonBuiltin<"void(void *, _Vector<64, bool>, int, int, _Vector<16, int>)">; + def V6_vgathermhq_128B : HexagonBuiltin<"void(void *, _Vector<128, bool>, int, int, _Vector<32, int>)">; + def V6_vgathermhw : HexagonBuiltin<"void(void *, int, int, _Vector<32, int>)">; + def V6_vgathermhw_128B : HexagonBuiltin<"void(void *, int, int, _Vector<64, int>)">; + def V6_vgathermhwq : HexagonBuiltin<"void(void *, _Vector<64, bool>, int, int, _Vector<32, int>)">; + def V6_vgathermhwq_128B : HexagonBuiltin<"void(void *, _Vector<128, bool>, int, int, _Vector<64, int>)">; + def V6_vgathermw : HexagonBuiltin<"void(void *, int, int, _Vector<16, int>)">; + def V6_vgathermw_128B : HexagonBuiltin<"void(void *, int, int, _Vector<32, int>)">; + def V6_vgathermwq : HexagonBuiltin<"void(void *, _Vector<64, bool>, int, int, _Vector<16, int>)">; + def V6_vgathermwq_128B : HexagonBuiltin<"void(void *, _Vector<128, bool>, int, int, _Vector<32, int>)">; + def V6_vlut4 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, long long int)">; + def V6_vlut4_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, long long int)">; + def V6_vmpabuu : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpabuu_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, int)">; + def V6_vmpabuu_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vmpabuu_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, int)">; + def V6_vmpahhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, long long int)">; + def V6_vmpahhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, long long int)">; + def V6_vmpauhuhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, long long int)">; + def V6_vmpauhuhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, long long int)">; + def V6_vmpsuhuhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, long long int)">; + def V6_vmpsuhuhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, long long int)">; + def V6_vmpyh_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, int)">; + def V6_vmpyh_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, int)">; + def V6_vmpyuhe : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpyuhe_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpyuhe_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_vmpyuhe_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_vnavgb : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vnavgb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vprefixqb : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>)">; + def V6_vprefixqb_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>)">; + def V6_vprefixqh : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>)">; + def V6_vprefixqh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>)">; + def V6_vprefixqw : HexagonBuiltin<"_Vector<16, int>(_Vector<64, bool>)">; + def V6_vprefixqw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<128, bool>)">; + def V6_vscattermh : HexagonBuiltin<"void(int, int, _Vector<16, int>, _Vector<16, int>)">; + def V6_vscattermh_128B : HexagonBuiltin<"void(int, int, _Vector<32, int>, _Vector<32, int>)">; + def V6_vscattermh_add : HexagonBuiltin<"void(int, int, _Vector<16, int>, _Vector<16, int>)">; + def V6_vscattermh_add_128B : HexagonBuiltin<"void(int, int, _Vector<32, int>, _Vector<32, int>)">; + def V6_vscattermhq : HexagonBuiltin<"void(_Vector<64, bool>, int, int, _Vector<16, int>, _Vector<16, int>)">; + def V6_vscattermhq_128B : HexagonBuiltin<"void(_Vector<128, bool>, int, int, _Vector<32, int>, _Vector<32, int>)">; + def V6_vscattermhw : HexagonBuiltin<"void(int, int, _Vector<32, int>, _Vector<16, int>)">; + def V6_vscattermhw_128B : HexagonBuiltin<"void(int, int, _Vector<64, int>, _Vector<32, int>)">; + def V6_vscattermhw_add : HexagonBuiltin<"void(int, int, _Vector<32, int>, _Vector<16, int>)">; + def V6_vscattermhw_add_128B : HexagonBuiltin<"void(int, int, _Vector<64, int>, _Vector<32, int>)">; + def V6_vscattermhwq : HexagonBuiltin<"void(_Vector<64, bool>, int, int, _Vector<32, int>, _Vector<16, int>)">; + def V6_vscattermhwq_128B : HexagonBuiltin<"void(_Vector<128, bool>, int, int, _Vector<64, int>, _Vector<32, int>)">; + def V6_vscattermw : HexagonBuiltin<"void(int, int, _Vector<16, int>, _Vector<16, int>)">; + def V6_vscattermw_128B : HexagonBuiltin<"void(int, int, _Vector<32, int>, _Vector<32, int>)">; + def V6_vscattermw_add : HexagonBuiltin<"void(int, int, _Vector<16, int>, _Vector<16, int>)">; + def V6_vscattermw_add_128B : HexagonBuiltin<"void(int, int, _Vector<32, int>, _Vector<32, int>)">; + def V6_vscattermwq : HexagonBuiltin<"void(_Vector<64, bool>, int, int, _Vector<16, int>, _Vector<16, int>)">; + def V6_vscattermwq_128B : HexagonBuiltin<"void(_Vector<128, bool>, int, int, _Vector<32, int>, _Vector<32, int>)">; +} + +// V66 HVX Instructions. + +let Features = HVXV66.Features in { + def V6_vaddcarryo : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, void *)">; + def V6_vaddcarryo_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, void *)">; + def V6_vaddcarrysat : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<64, bool>)">; + def V6_vaddcarrysat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<128, bool>)">; + def V6_vasr_into : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vasr_into_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vrotr : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vrotr_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsatdw : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsatdw_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsubcarryo : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, void *)">; + def V6_vsubcarryo_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, void *)">; +} + +// V68 HVX Instructions. + +let Features = HVXV68.Features in { + def V6_v6mpyhubs10 : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_v6mpyhubs10_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, unsigned _Constant int)">; + def V6_v6mpyhubs10_vxx : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_v6mpyhubs10_vxx_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, _Vector<64, int>, unsigned _Constant int)">; + def V6_v6mpyvubs10 : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_v6mpyvubs10_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, unsigned _Constant int)">; + def V6_v6mpyvubs10_vxx : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>, unsigned _Constant int)">; + def V6_v6mpyvubs10_vxx_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<64, int>, _Vector<64, int>, unsigned _Constant int)">; + def V6_vabs_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabs_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vabs_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabs_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vadd_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_hf_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_hf_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_qf16_mix : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_qf16_mix_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_qf32_mix : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_qf32_mix_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_sf_hf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_sf_hf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vadd_sf_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_sf_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vassign_fp : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vassign_fp_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_hf_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_hf_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_hf_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>)">; + def V6_vconv_hf_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>)">; + def V6_vconv_sf_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_sf_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vcvt_b_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcvt_b_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcvt_h_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vcvt_h_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vcvt_hf_b : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vcvt_hf_b_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vcvt_hf_h : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vcvt_hf_h_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vcvt_hf_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcvt_hf_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcvt_hf_ub : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vcvt_hf_ub_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vcvt_hf_uh : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vcvt_hf_uh_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vcvt_sf_hf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vcvt_sf_hf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vcvt_ub_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcvt_ub_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcvt_uh_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vcvt_uh_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vdmpy_sf_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vdmpy_sf_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vdmpy_sf_hf_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vdmpy_sf_hf_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vfmax_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vfmax_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vfmax_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vfmax_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vfmin_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vfmin_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vfmin_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vfmin_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vfneg_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vfneg_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vfneg_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vfneg_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vgthf : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgthf_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgthf_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgthf_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgthf_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgthf_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgthf_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgthf_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtsf : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgtsf_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtsf_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtsf_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtsf_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtsf_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtsf_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtsf_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmax_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmax_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmax_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmax_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmin_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmin_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmin_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmin_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_hf_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_hf_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_hf_hf_acc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_hf_hf_acc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf16_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf16_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf16_mix_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf16_mix_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf32_hf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf32_hf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf32_mix_hf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf32_mix_hf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf32_qf16 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf32_qf16_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_qf32_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_qf32_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_sf_hf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_sf_hf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_sf_hf_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_sf_hf_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_sf_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_sf_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_hf_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_hf_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_qf16_mix : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_qf16_mix_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_qf32 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_qf32_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_qf32_mix : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_qf32_mix_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_sf_hf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_sf_hf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_sf_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_sf_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; +} + +// V69 HVX Instructions. + +let Features = HVXV69.Features in { + def V6_vasrvuhubrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>, _Vector<16, int>)">; + def V6_vasrvuhubrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>, _Vector<32, int>)">; + def V6_vasrvuhubsat : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>, _Vector<16, int>)">; + def V6_vasrvuhubsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>, _Vector<32, int>)">; + def V6_vasrvwuhrndsat : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>, _Vector<16, int>)">; + def V6_vasrvwuhrndsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>, _Vector<32, int>)">; + def V6_vasrvwuhsat : HexagonBuiltin<"_Vector<16, int>(_Vector<32, int>, _Vector<16, int>)">; + def V6_vasrvwuhsat_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<64, int>, _Vector<32, int>)">; + def V6_vmpyuhvs : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpyuhvs_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; +} + +// V73 HVX Instructions. + +let Features = HVXV73.Features in { + def V6_vadd_sf_bf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_sf_bf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vconv_h_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_h_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_hf_h : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_hf_h_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_sf_w : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_sf_w_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vconv_w_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vconv_w_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vcvt_bf_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcvt_bf_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtbf : HexagonBuiltin<"_Vector<64, bool>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vgtbf_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vgtbf_and : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtbf_and_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtbf_or : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtbf_or_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vgtbf_xor : HexagonBuiltin<"_Vector<64, bool>(_Vector<64, bool>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vgtbf_xor_128B : HexagonBuiltin<"_Vector<128, bool>(_Vector<128, bool>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmax_bf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmax_bf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmin_bf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmin_bf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_sf_bf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_sf_bf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_sf_bf_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_sf_bf_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vsub_sf_bf : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_sf_bf_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; +} + +// V79 HVX Instructions. + +let Features = HVXV79.Features in { + def V6_get_qfext : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_get_qfext_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_get_qfext_oracc : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, int)">; + def V6_get_qfext_oracc_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>, int)">; + def V6_set_qfext : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_set_qfext_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vabs_f8 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vabs_f8_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vadd_hf_f8 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vadd_hf_f8_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcvt2_b_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcvt2_b_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcvt2_hf_b : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vcvt2_hf_b_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vcvt2_hf_ub : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vcvt2_hf_ub_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vcvt2_ub_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcvt2_ub_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcvt_f8_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vcvt_f8_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vcvt_hf_f8 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>)">; + def V6_vcvt_hf_f8_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>)">; + def V6_vfmax_f8 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vfmax_f8_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vfmin_f8 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vfmin_f8_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vfneg_f8 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>)">; + def V6_vfneg_f8_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>)">; + def V6_vmerge_qf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmerge_qf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_hf_f8 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_hf_f8_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_hf_f8_acc : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, _Vector<16, int>, _Vector<16, int>)">; + def V6_vmpy_hf_f8_acc_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<64, int>, _Vector<32, int>, _Vector<32, int>)">; + def V6_vmpy_rt_hf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpy_rt_hf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpy_rt_qf16 : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpy_rt_qf16_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vmpy_rt_sf : HexagonBuiltin<"_Vector<16, int>(_Vector<16, int>, int)">; + def V6_vmpy_rt_sf_128B : HexagonBuiltin<"_Vector<32, int>(_Vector<32, int>, int)">; + def V6_vsub_hf_f8 : HexagonBuiltin<"_Vector<32, int>(_Vector<16, int>, _Vector<16, int>)">; + def V6_vsub_hf_f8_128B : HexagonBuiltin<"_Vector<64, int>(_Vector<32, int>, _Vector<32, int>)">; +} diff --git a/clang/include/clang/Basic/BuiltinsHexagonDep.def b/clang/include/clang/Basic/BuiltinsHexagonDep.def deleted file mode 100644 index 616ff3ccf5b6b..0000000000000 --- a/clang/include/clang/Basic/BuiltinsHexagonDep.def +++ /dev/null @@ -1,1970 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// Automatically generated file, do not edit! -//===----------------------------------------------------------------------===// - - -// V5 Scalar Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_A2_abs, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_absp, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_abssat, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_add, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_hh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_lh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_lh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addpsat, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addsat, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_addsp, "LLiiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_and, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_andir, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_andp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_aslh, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_asrh, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_hh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_lh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_combineii, "LLiIiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_combinew, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_max, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_maxp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_maxu, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_maxup, "ULLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_min, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_minp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_minu, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_minup, "ULLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_neg, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_negp, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_negsat, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_not, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_notp, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_or, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_orir, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_orp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_roundsat, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_sat, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_satb, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_sath, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_satub, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_satuh, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_sub, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_hh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_lh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_lh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_hl, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_ll, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subri, "iIii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_subsat, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svaddh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svaddhs, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svadduhs, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svavgh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svavghs, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svnavgh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svsubh, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svsubhs, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_svsubuhs, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_swiz, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_sxtb, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_sxth, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_sxtw, "LLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_tfr, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrih, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_tfril, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrp, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrpi, "LLiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrsi, "iIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vabsh, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vabshsat, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vabsw, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vabswsat, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddb_map, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddhs, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddub, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddubs, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vadduhs, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddws, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavghcr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavghr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgub, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgubr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguhr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguwr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgwcr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgwr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpbeq, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpheq, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmphgt, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmphgtu, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpweq, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpwgt, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vconj, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxb, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxub, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxuh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxuw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vminb, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vminh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vminub, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vminuh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vminuw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vminw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavghcr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavghr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgwcr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgwr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vraddub, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vraddub_acc, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vrsadub, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vrsadub_acc, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubb_map, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubhs, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubub, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsububs, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubuhs, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubws, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_xor, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_xorp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_zxtb, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A2_zxth, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_andn, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_andnp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_bitsplit, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_bitspliti, "LLiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_boundscheck, "iiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbeq, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbeqi, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgt, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgti, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgtu, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgtui, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpheq, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpheqi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgt, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgti, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgtu, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgtui, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_combineir, "LLiIii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_combineri, "LLiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cround_ri, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_cround_rr, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_modwrapu, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_orn, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_ornp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpeq, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpeqi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpneq, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpneqi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_round_ri, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_round_ri_sat, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_round_rr, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_round_rr_sat, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_tlbmatch, "iLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi, "iLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbgt, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbgti, "iLLiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui, "iLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpheqi, "iLLiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmphgti, "iLLiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmphgtui, "iLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpweqi, "iLLiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpwgti, "iLLiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui, "iLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxh, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxuh, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxuw, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxw, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminh, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminuh, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminuw, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminw, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_A5_vaddhubs, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_all8, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_and, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_andn, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_any8, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_bitsclr, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_bitsclri, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_bitsset, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpeq, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpeqi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpeqp, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgei, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgeui, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgt, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgti, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtp, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtu, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtui, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtup, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmplt, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpltu, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_mask, "LLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_mux, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_muxii, "iiIiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_muxir, "iiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_muxri, "iiIii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_not, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_or, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_orn, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_pxfer_map, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_tfrpr, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_tfrrp, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_vitpack, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_vmux, "LLiiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C2_xor, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_and_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_and_andn, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_and_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_and_orn, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_cmplte, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_cmpltei, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_cmplteu, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_cmplteui, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_cmpneq, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_cmpneqi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_fastcorner9, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_nbitsclr, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_nbitsclri, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_nbitsset, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_or_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_or_andn, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_or_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_C4_or_orn, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_d2df, "dLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_d2sf, "fLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2d, "LLid", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2d_chop, "LLid", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2sf, "fd", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2ud, "LLid", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2ud_chop, "LLid", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2uw, "id", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2uw_chop, "id", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2w, "id", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2w_chop, "id", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2d, "LLif", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2d_chop, "LLif", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2df, "df", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud, "LLif", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud_chop, "LLif", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw, "if", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw_chop, "if", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2w, "if", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2w_chop, "if", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_ud2df, "dLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_ud2sf, "fLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_uw2df, "di", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf, "fi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_w2df, "di", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_w2sf, "fi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfclass, "idUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpeq, "idd", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpge, "idd", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpgt, "idd", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpuo, "idd", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfimm_n, "dUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfimm_p, "dUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfadd, "fff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfclass, "ifUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpeq, "iff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpge, "iff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpgt, "iff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpuo, "iff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffixupd, "fff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffixupn, "fff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffixupr, "ff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffma, "ffff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffma_lib, "ffff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffma_sc, "ffffi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffms, "ffff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sffms_lib, "ffff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfimm_n, "fUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfimm_p, "fUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfmax, "fff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfmin, "fff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfmpy, "fff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_F2_sfsub, "fff", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_acci, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_accii, "iiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmaci_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacr_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacs_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacs_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacsc_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacsc_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyi_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyr_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpys_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpys_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpysc_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpysc_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacs_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacs_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacsc_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacsc_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_acc_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_nac_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_rnd_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_acc_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_nac_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_s0, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyh_rs1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyl_rs1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyl_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_maci, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_macsin, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_macsip, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_rs0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_rs1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_rs0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_rs1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_up, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1_sat, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyi, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpysmi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpysu_up, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s0, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s1, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s0, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s1, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s0, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s1, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s0, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s1, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s0, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s1, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_up, "Uiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s0, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s1, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s0, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s1, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s0, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s1, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s0, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s1, "ULLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyui, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_nacci, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_naccii, "iiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_subacc, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vabsdiffh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vabsdiffw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_i, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_r, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_i, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_r, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_i, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_r, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmacs_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmacs_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s0, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s1, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpys_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpys_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2es, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2es_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2es_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2s_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2s_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2su_s0, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2su_s1, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0pack, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1pack, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s0, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s1, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vraddh, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vradduh, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0c, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0c, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0c, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0c, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpys_acc_s1, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1rp, "iLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrmac_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_vrmpy_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M2_xor_xacc, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_and_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_and_andn, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_and_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_and_xor, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyi_wh, "iLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyi_whc, "iLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyr_wh, "iLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyr_whc, "iLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_mac_up_s1_sat, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyri_addi, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyri_addr, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyri_addr_u2, "iiUIii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyrr_addi, "iUIiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyrr_addr, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_nac_up_s1_sat, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_or_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_or_andn, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_or_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_or_xor, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_pmpyw, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_pmpyw_acc, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vpmpyh, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vpmpyh_acc, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s0, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s1, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s0, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s1, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_andn, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_xacc, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vdmacbsu, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vdmpybsu, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vmacbsu, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vmacbuu, "LLiLLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vmpybsu, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vmpybuu, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmacbsu, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmacbuu, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmpybsu, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmpybuu, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_addasl_rrri, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_acc, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_and, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_nac, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_or, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_xacc, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_acc, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_and, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_nac, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_or, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_sat, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_xacc, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_vh, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_vw, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_acc, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_and, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_nac, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_or, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_xor, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_acc, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_nac, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_sat, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_vh, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_vw, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_acc, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_and, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_nac, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_or, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_acc, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_and, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_nac, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_or, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_svw_trun, "iLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_vh, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_vw, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_acc, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_and, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_nac, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_or, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_xor, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_acc, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_nac, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_sat, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_svw_trun, "iLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_vh, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_vw, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_brev, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_brevp, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_cl0, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_cl0p, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_cl1, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_cl1p, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_clb, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_clbnorm, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_clbp, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_clrbit_i, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_clrbit_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_ct0, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_ct0p, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_ct1, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_ct1p, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_deinterleave, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_extractu, "iiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_extractu_rp, "iiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_extractup, "LLiLLiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_extractup_rp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_insert, "iiiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_insert_rp, "iiiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_insertp, "LLiLLiLLiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_insertp_rp, "LLiLLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_interleave, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lfsp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_acc, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_and, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_nac, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_or, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_xor, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_acc, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_nac, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_vh, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_vw, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_acc, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_and, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_nac, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_or, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_xacc, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_acc, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_and, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_nac, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_or, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_xacc, "iiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_vh, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_vw, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_acc, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_and, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_nac, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_or, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_xor, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_acc, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_and, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_nac, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_or, "iiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_vh, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_vw, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_packhl, "LLiii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_parityp, "iLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_setbit_i, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_setbit_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffeb, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffeh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffob, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffoh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_svsathb, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_svsathub, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxb_goodsyntax, "iiiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxd_goodsyntax, "iiiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxh_goodsyntax, "iiiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxw_goodsyntax, "iiiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_togglebit_i, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_togglebit_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_tstbit_i, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_tstbit_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_valignib, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_valignrb, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vcnegh, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vcrotate, "LLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vrcnegh, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vrndpackwh, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vrndpackwhs, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathb, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathb_nopack, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathub, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathub_nopack, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwh, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwh_nopack, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwuh, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwuh_nopack, "LLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsplatrb, "ii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsplatrh, "LLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vspliceib, "LLiLLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsplicerb, "LLiLLiLLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsxtbh, "LLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vsxthw, "LLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunehb, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunewh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunohb, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunowh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vzxtbh, "LLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S2_vzxthw, "LLii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_addaddi, "iiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_addi_asl_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_addi_lsr_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_andi_asl_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_andi_lsr_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_clbaddi, "iiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_clbpaddi, "iLLiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_clbpnorm, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_extract, "iiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_extract_rp, "iiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_extractp, "LLiLLiUIiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_extractp_rp, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_lsli, "iIii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_ntstbit_i, "iiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_ntstbit_r, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_or_andi, "iiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_or_andix, "iiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_or_ori, "iiiIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_ori_asl_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_ori_lsr_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_parity, "iii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_subaddi, "iiIii", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_subi_asl_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_subi_lsr_ri, "iUIiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vrcrotate, "LLiLLiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vrcrotate_acc, "LLiLLiLLiiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vxaddsubh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vxaddsubhr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vxaddsubw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vxsubaddh, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vxsubaddhr, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S4_vxsubaddw, "LLiLLiLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax, "iLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S5_asrhub_sat, "iLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S5_popcountp, "iLLi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_S5_vasrhrnd_goodsyntax, "LLiLLiUIi", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_Y2_dccleana, "vv*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_Y2_dccleaninva, "vv*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_Y2_dcfetch, "vv*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_Y2_dcinva, "vv*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_Y2_dczeroa, "vv*", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_Y4_l2fetch, "vv*i", "", V5) -TARGET_BUILTIN(__builtin_HEXAGON_Y5_l2fetch, "vv*LLi", "", V5) - -// V60 Scalar Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p, "LLiLLiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_acc, "LLiLLiLLiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_and, "LLiLLiLLiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_nac, "LLiLLiLLiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_or, "LLiLLiLLiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_xacc, "LLiLLiLLiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r, "iiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_acc, "iiiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_and, "iiiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_nac, "iiiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_or, "iiiUIi", "", V60) -TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_xacc, "iiiUIi", "", V60) - -// V62 Scalar Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_M6_vabsdiffb, "LLiLLiLLi", "", V62) -TARGET_BUILTIN(__builtin_HEXAGON_M6_vabsdiffub, "LLiLLiLLi", "", V62) -TARGET_BUILTIN(__builtin_HEXAGON_S6_vsplatrbp, "LLii", "", V62) -TARGET_BUILTIN(__builtin_HEXAGON_S6_vtrunehb_ppp, "LLiLLiLLi", "", V62) -TARGET_BUILTIN(__builtin_HEXAGON_S6_vtrunohb_ppp, "LLiLLiLLi", "", V62) - -// V65 Scalar Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany, "iLLiLLi", "", V65) - -// V66 Scalar Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfadd, "ddd", "", V66) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfsub, "ddd", "", V66) -TARGET_BUILTIN(__builtin_HEXAGON_M2_mnaci, "iiii", "", V66) -TARGET_BUILTIN(__builtin_HEXAGON_S2_mask, "iUIiUIi", "", V66) - -// V67 Scalar Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_A7_clip, "iiUIi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_A7_croundd_ri, "LLiLLiUIi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_A7_croundd_rr, "LLiLLii", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_A7_vclip, "LLiLLiUIi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmax, "ddd", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmin, "ddd", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpyfix, "ddd", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpyhh, "dddd", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpylh, "dddd", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpyll, "ddd", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiw, "LLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiw_acc, "LLiLLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiwc, "LLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiwc_acc, "LLiLLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrw, "LLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrw_acc, "LLiLLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrwc, "LLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrwc_acc, "LLiLLiLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_vdmpy, "LLiLLiLLi", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_M7_vdmpy_acc, "LLiLLiLLiLLi", "", V67) -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiw, "iLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiw_rnd, "iLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiwc, "iLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiwc_rnd, "iLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrw, "iLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrw_rnd, "iLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrwc, "iLLiLLi", "", "audio") -TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrwc_rnd, "iLLiLLi", "", "audio") - -// V68 Scalar Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_Y6_dmlink, "vv*v*", "", V68) -TARGET_BUILTIN(__builtin_HEXAGON_Y6_dmpause, "i", "", V68) -TARGET_BUILTIN(__builtin_HEXAGON_Y6_dmpoll, "i", "", V68) -TARGET_BUILTIN(__builtin_HEXAGON_Y6_dmresume, "vv*", "", V68) -TARGET_BUILTIN(__builtin_HEXAGON_Y6_dmstart, "vv*", "", V68) -TARGET_BUILTIN(__builtin_HEXAGON_Y6_dmwait, "i", "", V68) - -// V60 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_extractw, "iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_extractw_128B, "iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_hi, "V16iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_hi_128B, "V32iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_lo, "V16iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_lo_128B, "V32iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatw, "V16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatw_128B, "V32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and, "V64bV64bV64b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and_128B, "V128bV128bV128b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and_n, "V64bV64bV64b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and_n_128B, "V128bV128bV128b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_not, "V64bV64b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_not_128B, "V128bV128b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or, "V64bV64bV64b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or_128B, "V128bV128bV128b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or_n, "V64bV64bV64b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or_n_128B, "V128bV128bV128b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2, "V64bi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2_128B, "V128bi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_xor, "V64bV64bV64b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_xor_128B, "V128bV128bV128b", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai, "vV64bv*V16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai_128B, "vV128bv*V32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai, "vV64bv*V16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai_128B, "vV128bv*V32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai, "vV64bv*V16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai_128B, "vV128bv*V32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai, "vV64bv*V16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai_128B, "vV128bv*V32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffub, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffub_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffw, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffw_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh_sat, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh_sat_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw_sat, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw_sat_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbnq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbnq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhnq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhnq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwnq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwnq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_valignb, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_valignb_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_valignbi, "V16iV16iV16iUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_valignbi_128B, "V32iV32iV32iUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vand, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vand_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt, "V16iV64bi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt_128B, "V32iV128bi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc, "V16iV16iV64bi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc_128B, "V32iV32iV128bi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt, "V64bV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt_128B, "V128bV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc, "V64bV64bV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc_128B, "V128bV128bV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslhv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslhv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslwv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslwv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubsat, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubsat_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwh, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwh_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhsat, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhsat_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vassignp, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vassignp_128B, "V64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavghrnd, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavghrnd_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgub, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgub_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgubrnd, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgubrnd_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguhrnd, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguhrnd_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgw, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgw_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgwrnd, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgwrnd_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0h, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0h_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0w, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0w_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcombine, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcombine_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vd0, "V16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vd0_128B, "V32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb4w, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb4w_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealh, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealh_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealvdd, "V32iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealvdd_128B, "V64iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdelta, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdelta_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat, "V16iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_128B, "V32iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc, "V16iV16iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc_128B, "V32iV32iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat, "V16iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_128B, "V32iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc, "V16iV16iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B, "V32iV32iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw, "V64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_128B, "V128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_and, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_and_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_or, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_or_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_xor, "V64bV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_xor_128B, "V128bV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vinsertwr, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vinsertwr_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignb, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignb_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignbi, "V16iV16iV16iUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignbi_128B, "V32iV32iV32iUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrh, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrh_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrhv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrhv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrw, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrw_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrwv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrwv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc, "V16iV16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc_128B, "V32iV32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh, "V32iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_128B, "V64iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc, "V32iV32iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc_128B, "V64iV64iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxub, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxub_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxuh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxuh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxw, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxw_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminub, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminub_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminuh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminuh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminw, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminw_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabusv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabusv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuuv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuuv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus, "V32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus_128B, "V64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc, "V32iV32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc_128B, "V64iV64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc, "V32iV32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc, "V32iV32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh, "V32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh_128B, "V64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc, "V32iV32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc_128B, "V64iV64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhss, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhss_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc, "V32iV32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc_128B, "V64iV64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc, "V32iV32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyieoh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyieoh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiowh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiowh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub, "V32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub_128B, "V64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc, "V32iV32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc_128B, "V64iV64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc, "V32iV32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh, "V32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh_128B, "V64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc, "V32iV32iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc_128B, "V64iV64iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc, "V32iV32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmux, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmux_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgub, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgub_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgw, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgw_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamth, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamth_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamtw, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamtw_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnot, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnot_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vor, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vor_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeb, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeb_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackob, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackob_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackoh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackoh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpopcounth, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vpopcounth_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrdelta, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrdelta_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi, "V32iV32iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_128B, "V64iV64iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc, "V32iV32iV32iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc_128B, "V64iV64iV64iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc, "V16iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc_128B, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi, "V32iV32iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_128B, "V64iV64iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc, "V32iV32iV32iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc_128B, "V64iV64iV64iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc, "V16iV16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc_128B, "V32iV32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vror, "V16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vror_128B, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhb, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhb_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhub, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhub_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwuh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwuh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi, "V32iV32iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi_128B, "V64iV64iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc, "V32iV32iV32iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc_128B, "V64iV64iV64iiUIi", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsathub, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsathub_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatwh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatwh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsb, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsb_128B, "V64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsh, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsh_128B, "V64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufeh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufeh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffb, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffb_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffeb, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffeb_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffh, "V16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffh_128B, "V32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffob, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffob_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffvdd, "V32iV16iV16ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffvdd_128B, "V64iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeb, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeb_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeh, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeh_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbnq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbnq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhnq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhnq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhw, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhw_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububh, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububh_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhw, "V32iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhw_128B, "V64iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwnq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwnq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwq, "V16iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwq_128B, "V32iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv_128B, "V64iV64iV64i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vswap, "V32iV64bV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vswap_128B, "V64iV128bV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb, "V32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_128B, "V64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc, "V32iV32iV32ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc_128B, "V64iV64iV64ii", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackb, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackb_128B, "V64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackh, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackh_128B, "V64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackob, "V32iV32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackob_128B, "V64iV64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackoh, "V32iV32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackoh_128B, "V64iV64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackub, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackub_128B, "V64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackuh, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackuh_128B, "V64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vxor, "V16iV16iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vxor_128B, "V32iV32iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vzb, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vzb_128B, "V64iV32i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vzh, "V32iV16i", "", HVXV60) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vzh_128B, "V64iV32i", "", HVXV60) - -// V62 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatb, "V16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatb_128B, "V32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplath, "V16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplath_128B, "V32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2, "V64bi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2_128B, "V128bi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqh, "V64bV64bV64b", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqh_128B, "V128bV128bV128b", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqw, "V64bV64bV64b", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqw_128B, "V128bV128bV128b", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv_128B, "V64iV64iV64i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarry, "V16iV16iV16iv*", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarry_128B, "V32iV32iV32iv*", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbh, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbh_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbw, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbw_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc, "V32iV32iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc_128B, "V64iV64iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc, "V32iV32iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc_128B, "V64iV64iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc, "V32iV32iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc_128B, "V64iV64iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv_128B, "V64iV64iV64i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt, "V16iV64bi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt_128B, "V32iV128bi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc, "V16iV16iV64bi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc_128B, "V32iV32iV128bi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvnqv, "V16iV64bV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvnqv_128B, "V32iV128bV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvqv, "V16iV64bV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvqv_128B, "V32iV128bV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbsat, "V16iV16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbsat_128B, "V32iV32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat, "V16iV16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat_128B, "V32iV32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat, "V16iV16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat_128B, "V32iV32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrb, "V16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrb_128B, "V32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm, "V16iV16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm_128B, "V32iV32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci, "V16iV16iV16iV16iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci_128B, "V32iV32iV32iV32iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvbi, "V16iV16iV16iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvbi_128B, "V32iV32iV32iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm, "V32iV16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm_128B, "V64iV32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci, "V32iV32iV16iV16iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci_128B, "V64iV64iV32iV32iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwhi, "V32iV16iV16iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwhi_128B, "V64iV32iV32iUIi", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxb, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxb_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminb, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vminb_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb, "V32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb_128B, "V64iV64ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc, "V32iV32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc_128B, "V64iV64iV64ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64, "V32iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64_128B, "V64iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub, "V16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_128B, "V32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc, "V16iV16iV16ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc_128B, "V32iV32iV32ii", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc, "V32iV32iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc_128B, "V64iV64iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduhub, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduhub_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduwuh, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduwuh_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatuwuh, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatuwuh_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv_128B, "V64iV64iV64i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarry, "V16iV16iV16iv*", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarry_128B, "V32iV32iV32iv*", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat, "V16iV16iV16i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_128B, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv, "V32iV32iV32i", "", HVXV62) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv_128B, "V64iV64iV64i", "", HVXV62) - -// V65 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb, "V16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb_128B, "V32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb_sat, "V16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb_sat_128B, "V32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh_acc, "V16iV16iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh_acc_128B, "V32iV32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh_acc, "V16iV16iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh_acc_128B, "V32iV32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat, "V16iV16iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat_128B, "V32iV32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubsat, "V16iV16iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubsat_128B, "V32iV32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat, "V16iV16iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat_128B, "V32iV32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgb, "V16iV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgb_128B, "V32iV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgbrnd, "V16iV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgbrnd_128B, "V32iV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguw, "V16iV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguw_128B, "V32iV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguwrnd, "V16iV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguwrnd_128B, "V32iV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdd0, "V32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdd0_128B, "V64i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermh, "vv*iiV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermh_128B, "vv*iiV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhq, "vv*V64biiV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhq_128B, "vv*V128biiV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhw, "vv*iiV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhw_128B, "vv*iiV64i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhwq, "vv*V64biiV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhwq_128B, "vv*V128biiV64i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermw, "vv*iiV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermw_128B, "vv*iiV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermwq, "vv*V64biiV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermwq_128B, "vv*V128biiV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlut4, "V16iV16iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vlut4_128B, "V32iV32iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu, "V32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu_128B, "V64iV64ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc, "V32iV32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc_128B, "V64iV64iV64ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahhsat, "V16iV16iV16iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahhsat_128B, "V32iV32iV32iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat, "V16iV16iV16iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat_128B, "V32iV32iV32iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat, "V16iV16iV16iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat_128B, "V32iV32iV32iLLi", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc, "V32iV32iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc_128B, "V64iV64iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe, "V16iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_128B, "V32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc, "V16iV16iV16ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc_128B, "V32iV32iV32ii", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgb, "V16iV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgb_128B, "V32iV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqb, "V16iV64b", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqb_128B, "V32iV128b", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqh, "V16iV64b", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqh_128B, "V32iV128b", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqw, "V16iV64b", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqw_128B, "V32iV128b", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh, "viiV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh_128B, "viiV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh_add, "viiV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh_add_128B, "viiV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhq, "vV64biiV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhq_128B, "vV128biiV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw, "viiV32iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw_128B, "viiV64iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add, "viiV32iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add_128B, "viiV64iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhwq, "vV64biiV32iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhwq_128B, "vV128biiV64iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw, "viiV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw_128B, "viiV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw_add, "viiV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw_add_128B, "viiV32iV32i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermwq, "vV64biiV16iV16i", "", HVXV65) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B, "vV128biiV32iV32i", "", HVXV65) - -// V66 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo, "V16iV16iV16iv*", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarryo_128B, "V32iV32iV32iv*", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat, "V16iV16iV16iV64b", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat_128B, "V32iV32iV32iV128b", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasr_into, "V32iV32iV16iV16i", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasr_into_128B, "V64iV64iV32iV32i", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr, "V16iV16iV16i", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr_128B, "V32iV32iV32i", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw, "V16iV16iV16i", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw_128B, "V32iV32iV32i", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo, "V16iV16iV16iv*", "", HVXV66) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarryo_128B, "V32iV32iV32iv*", "", HVXV66) - -// V68 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyhubs10, "V32iV32iV32iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyhubs10_128B, "V64iV64iV64iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyhubs10_vxx, "V32iV32iV32iV32iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyhubs10_vxx_128B, "V64iV64iV64iV64iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10, "V32iV32iV32iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_128B, "V64iV64iV64iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_vxx, "V32iV32iV32iV32iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_v6mpyvubs10_vxx_128B, "V64iV64iV64iV64iUIi", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_hf, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_hf_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_sf, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_sf_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_mix, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf16_mix_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_mix, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_qf32_mix_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_hf, "V32iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_hf_128B, "V64iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_fp, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_fp_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf16, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf16_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf32, "V16iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_qf32_128B, "V32iV64i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_qf32, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_qf32_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_b_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_b_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_h_hf, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_h_hf_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_b, "V32iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_b_128B, "V64iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_h, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_h_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_ub, "V32iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_ub_128B, "V64iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_uh, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_uh_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_sf_hf, "V32iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_sf_hf_128B, "V64iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_ub_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_ub_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_uh_hf, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_uh_hf_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_acc, "V16iV16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpy_sf_hf_acc_128B, "V32iV32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_hf, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_hf_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_sf, "V16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_sf_128B, "V32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf, "V64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_128B, "V128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_and, "V64bV64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_and_128B, "V128bV128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_or, "V64bV64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_or_128B, "V128bV128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_xor, "V64bV64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgthf_xor_128B, "V128bV128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf, "V64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_128B, "V128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_and, "V64bV64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_and_128B, "V128bV128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_or, "V64bV64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_or_128B, "V128bV128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_xor, "V64bV64bV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtsf_xor_128B, "V128bV128bV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_acc, "V16iV16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_hf_acc_128B, "V32iV32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_mix_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf16_mix_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_hf, "V32iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_hf_128B, "V64iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_mix_hf, "V32iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_mix_hf_128B, "V64iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_qf16, "V32iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_qf16_128B, "V64iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_qf32_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf, "V32iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_128B, "V64iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_acc, "V32iV32iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_hf_acc_128B, "V64iV64iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_hf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_hf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_mix, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf16_mix_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_mix, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_qf32_mix_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_128B, "V32iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_hf, "V32iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_hf_128B, "V64iV32iV32i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_sf, "V16iV16iV16i", "", HVXV68) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_sf_128B, "V32iV32iV32i", "", HVXV68) - -// V69 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubrndsat, "V16iV32iV16i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubrndsat_128B, "V32iV64iV32i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubsat, "V16iV32iV16i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvuhubsat_128B, "V32iV64iV32i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhrndsat, "V16iV32iV16i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhrndsat_128B, "V32iV64iV32i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhsat, "V16iV32iV16i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrvwuhsat_128B, "V32iV64iV32i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhvs, "V16iV16iV16i", "", HVXV69) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhvs_128B, "V32iV32iV32i", "", HVXV69) - -// V73 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_bf, "V32iV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_sf_bf_128B, "V64iV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_h_hf, "V16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_h_hf_128B, "V32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_h, "V16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_hf_h_128B, "V32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_w, "V16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_sf_w_128B, "V32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_w_sf, "V16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vconv_w_sf_128B, "V32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_bf_sf, "V16iV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_bf_sf_128B, "V32iV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf, "V64bV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_128B, "V128bV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_and, "V64bV64bV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_and_128B, "V128bV128bV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_or, "V64bV64bV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_or_128B, "V128bV128bV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_xor, "V64bV64bV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtbf_xor_128B, "V128bV128bV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_bf, "V16iV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmax_bf_128B, "V32iV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_bf, "V16iV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmin_bf_128B, "V32iV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf, "V32iV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf_128B, "V64iV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf_acc, "V32iV32iV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_sf_bf_acc_128B, "V64iV64iV32iV32i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_bf, "V32iV16iV16i", "", HVXV73) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_sf_bf_128B, "V64iV32iV32i", "", HVXV73) - -// V79 HVX Instructions. - -TARGET_BUILTIN(__builtin_HEXAGON_V6_get_qfext, "V16iV16ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_get_qfext_128B, "V32iV32ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_get_qfext_oracc, "V16iV16iV16ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_get_qfext_oracc_128B, "V32iV32iV32ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_set_qfext, "V16iV16ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_set_qfext_128B, "V32iV32ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_f8, "V16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vabs_f8_128B, "V32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_f8, "V32iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vadd_hf_f8_128B, "V64iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_b_hf, "V16iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_b_hf_128B, "V32iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_hf_b, "V32iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_hf_b_128B, "V64iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_hf_ub, "V32iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_hf_ub_128B, "V64iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_ub_hf, "V16iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt2_ub_hf_128B, "V32iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_f8_hf, "V16iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_f8_hf_128B, "V32iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_f8, "V32iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vcvt_hf_f8_128B, "V64iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_f8, "V16iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmax_f8_128B, "V32iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_f8, "V16iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfmin_f8_128B, "V32iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_f8, "V16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vfneg_f8_128B, "V32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmerge_qf, "V16iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmerge_qf_128B, "V32iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_f8, "V32iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_f8_128B, "V64iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_f8_acc, "V32iV32iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_hf_f8_acc_128B, "V64iV64iV32iV32i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_rt_hf, "V16iV16ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_rt_hf_128B, "V32iV32ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_rt_qf16, "V16iV16ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_rt_qf16_128B, "V32iV32ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_rt_sf, "V16iV16ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpy_rt_sf_128B, "V32iV32ii", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_f8, "V32iV16iV16i", "", HVXV79) -TARGET_BUILTIN(__builtin_HEXAGON_V6_vsub_hf_f8_128B, "V64iV32iV32i", "", HVXV79) diff --git a/clang/include/clang/Basic/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def deleted file mode 100644 index 95359a3fdc711..0000000000000 --- a/clang/include/clang/Basic/BuiltinsLoongArch.def +++ /dev/null @@ -1,28 +0,0 @@ -//==- BuiltinsLoongArch.def - LoongArch Builtin function database -- C++ -*-==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the LoongArch-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -// Definition of LoongArch basic builtins. -#include "clang/Basic/BuiltinsLoongArchBase.def" - -// Definition of LSX builtins. -#include "clang/Basic/BuiltinsLoongArchLSX.def" - -// Definition of LASX builtins. -#include "clang/Basic/BuiltinsLoongArchLASX.def" - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsNEON.def b/clang/include/clang/Basic/BuiltinsNEON.def deleted file mode 100644 index 9627005ba9824..0000000000000 --- a/clang/include/clang/Basic/BuiltinsNEON.def +++ /dev/null @@ -1,22 +0,0 @@ -//===--- BuiltinsNEON.def - NEON Builtin function database ------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the NEON-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -// The format of this database matches clang/Basic/Builtins.def. - -#define GET_NEON_BUILTINS -#include "clang/Basic/arm_neon.inc" -#include "clang/Basic/arm_fp16.inc" -#undef GET_NEON_BUILTINS - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def b/clang/include/clang/Basic/BuiltinsNVPTX.def deleted file mode 100644 index 37b4e6ff77fda..0000000000000 --- a/clang/include/clang/Basic/BuiltinsNVPTX.def +++ /dev/null @@ -1,1119 +0,0 @@ -//===--- BuiltinsPTX.def - PTX Builtin function database ----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the PTX-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -// The format of this database matches clang/Basic/Builtins.def. - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -#pragma push_macro("SM_53") -#pragma push_macro("SM_70") -#pragma push_macro("SM_72") -#pragma push_macro("SM_75") -#pragma push_macro("SM_80") -#pragma push_macro("SM_86") -#pragma push_macro("SM_87") -#pragma push_macro("SM_89") -#pragma push_macro("SM_90") -#pragma push_macro("SM_90a") -#pragma push_macro("SM_100") -#pragma push_macro("SM_100a") -#define SM_100a "sm_100a" -#define SM_100 "sm_100|" SM_100a -#define SM_90a "sm_90a" -#define SM_90 "sm_90|" SM_90a "|" SM_100 -#define SM_89 "sm_89|" SM_90 -#define SM_87 "sm_87|" SM_89 -#define SM_86 "sm_86|" SM_87 -#define SM_80 "sm_80|" SM_86 -#define SM_75 "sm_75|" SM_80 -#define SM_72 "sm_72|" SM_75 -#define SM_70 "sm_70|" SM_72 - -#pragma push_macro("SM_60") -#define SM_60 "sm_60|sm_61|sm_62|" SM_70 -#define SM_53 "sm_53|" SM_60 - -#pragma push_macro("PTX42") -#pragma push_macro("PTX60") -#pragma push_macro("PTX61") -#pragma push_macro("PTX62") -#pragma push_macro("PTX63") -#pragma push_macro("PTX64") -#pragma push_macro("PTX65") -#pragma push_macro("PTX70") -#pragma push_macro("PTX71") -#pragma push_macro("PTX72") -#pragma push_macro("PTX73") -#pragma push_macro("PTX74") -#pragma push_macro("PTX75") -#pragma push_macro("PTX76") -#pragma push_macro("PTX77") -#pragma push_macro("PTX78") -#pragma push_macro("PTX80") -#pragma push_macro("PTX81") -#pragma push_macro("PTX82") -#pragma push_macro("PTX83") -#pragma push_macro("PTX84") -#pragma push_macro("PTX85") -#pragma push_macro("PTX86") -#define PTX86 "ptx86" -#define PTX85 "ptx85|" PTX86 -#define PTX84 "ptx84|" PTX85 -#define PTX83 "ptx83|" PTX84 -#define PTX82 "ptx82|" PTX83 -#define PTX81 "ptx81|" PTX82 -#define PTX80 "ptx80|" PTX81 -#define PTX78 "ptx78|" PTX80 -#define PTX77 "ptx77|" PTX78 -#define PTX76 "ptx76|" PTX77 -#define PTX75 "ptx75|" PTX76 -#define PTX74 "ptx74|" PTX75 -#define PTX73 "ptx73|" PTX74 -#define PTX72 "ptx72|" PTX73 -#define PTX71 "ptx71|" PTX72 -#define PTX70 "ptx70|" PTX71 -#define PTX65 "ptx65|" PTX70 -#define PTX64 "ptx64|" PTX65 -#define PTX63 "ptx63|" PTX64 -#define PTX62 "ptx62|" PTX63 -#define PTX61 "ptx61|" PTX62 -#define PTX60 "ptx60|" PTX61 -#define PTX42 "ptx42|" PTX60 - -#pragma push_macro("AND") -#define AND(a, b) "(" a "),(" b ")" - -// Special Registers - -BUILTIN(__nvvm_read_ptx_sreg_tid_x, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_tid_y, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_tid_z, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_tid_w, "i", "nc") - -BUILTIN(__nvvm_read_ptx_sreg_ntid_x, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_ntid_y, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_ntid_z, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_ntid_w, "i", "nc") - -BUILTIN(__nvvm_read_ptx_sreg_ctaid_x, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_ctaid_y, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_ctaid_z, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_ctaid_w, "i", "nc") - -BUILTIN(__nvvm_read_ptx_sreg_nctaid_x, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_nctaid_y, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_nctaid_z, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_nctaid_w, "i", "nc") - -TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_x, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_y, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_z, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_clusterid_w, "i", "nc", AND(SM_90, PTX78)) - -TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_x, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_y, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_z, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_nclusterid_w, "i", "nc", AND(SM_90, PTX78)) - -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_x, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_y, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_z, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctaid_w, "i", "nc", AND(SM_90, PTX78)) - -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_x, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_y, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_z, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctaid_w, "i", "nc", AND(SM_90, PTX78)) - -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_ctarank, "i", "nc", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_read_ptx_sreg_cluster_nctarank, "i", "nc", AND(SM_90, PTX78)) - -TARGET_BUILTIN(__nvvm_is_explicit_cluster, "b", "nc", AND(SM_90, PTX78)) - -BUILTIN(__nvvm_read_ptx_sreg_laneid, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_warpid, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_nwarpid, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_warpsize, "i", "nc") - -BUILTIN(__nvvm_read_ptx_sreg_smid, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_nsmid, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_gridid, "i", "nc") - -BUILTIN(__nvvm_read_ptx_sreg_lanemask_eq, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_lanemask_le, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_lanemask_lt, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_lanemask_ge, "i", "nc") -BUILTIN(__nvvm_read_ptx_sreg_lanemask_gt, "i", "nc") - -BUILTIN(__nvvm_read_ptx_sreg_clock, "i", "n") -BUILTIN(__nvvm_read_ptx_sreg_clock64, "LLi", "n") -BUILTIN(__nvvm_read_ptx_sreg_globaltimer, "LLi", "n") - -BUILTIN(__nvvm_read_ptx_sreg_pm0, "i", "n") -BUILTIN(__nvvm_read_ptx_sreg_pm1, "i", "n") -BUILTIN(__nvvm_read_ptx_sreg_pm2, "i", "n") -BUILTIN(__nvvm_read_ptx_sreg_pm3, "i", "n") - -// MISC - -BUILTIN(__nvvm_prmt, "UiUiUiUi", "") -BUILTIN(__nvvm_exit, "v", "r") -BUILTIN(__nvvm_reflect, "UicC*", "r") -TARGET_BUILTIN(__nvvm_nanosleep, "vUi", "n", AND(SM_70, PTX63)) - -// Min Max - -TARGET_BUILTIN(__nvvm_fmin_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_nan_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_ftz_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_xorsign_abs_f16, "hhh", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_ftz_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_nan_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_bf16, "yyy", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_bf16, "yyy", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_bf16x2, "V2yV2yV2y", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_bf16x2, "V2yV2yV2y", "", - AND(SM_86, PTX72)) -BUILTIN(__nvvm_fmin_f, "fff", "") -BUILTIN(__nvvm_fmin_ftz_f, "fff", "") -TARGET_BUILTIN(__nvvm_fmin_nan_f, "fff", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_f, "fff", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmin_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_ftz_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmin_ftz_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -BUILTIN(__nvvm_fmin_d, "ddd", "") - -TARGET_BUILTIN(__nvvm_fmax_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_nan_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_f16, "hhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_ftz_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_f16, "hhh", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_xorsign_abs_f16, "hhh", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_f16x2, "V2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_ftz_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_xorsign_abs_f16x2, "V2hV2hV2h", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_nan_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_bf16, "yyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_bf16, "yyy", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_bf16, "yyy", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_bf16x2, "V2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_bf16x2, "V2yV2yV2y", "", - AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_bf16x2, "V2yV2yV2y", "", - AND(SM_86, PTX72)) -BUILTIN(__nvvm_fmax_f, "fff", "") -BUILTIN(__nvvm_fmax_ftz_f, "fff", "") -TARGET_BUILTIN(__nvvm_fmax_nan_f, "fff", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_f, "fff", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fmax_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_ftz_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -TARGET_BUILTIN(__nvvm_fmax_ftz_nan_xorsign_abs_f, "fff", "", AND(SM_86, PTX72)) -BUILTIN(__nvvm_fmax_d, "ddd", "") - -// Multiplication - -BUILTIN(__nvvm_mulhi_i, "iii", "") -BUILTIN(__nvvm_mulhi_ui, "UiUiUi", "") -BUILTIN(__nvvm_mulhi_ll, "LLiLLiLLi", "") -BUILTIN(__nvvm_mulhi_ull, "ULLiULLiULLi", "") - -BUILTIN(__nvvm_mul_rn_ftz_f, "fff", "") -BUILTIN(__nvvm_mul_rn_f, "fff", "") -BUILTIN(__nvvm_mul_rz_ftz_f, "fff", "") -BUILTIN(__nvvm_mul_rz_f, "fff", "") -BUILTIN(__nvvm_mul_rm_ftz_f, "fff", "") -BUILTIN(__nvvm_mul_rm_f, "fff", "") -BUILTIN(__nvvm_mul_rp_ftz_f, "fff", "") -BUILTIN(__nvvm_mul_rp_f, "fff", "") - -BUILTIN(__nvvm_mul_rn_d, "ddd", "") -BUILTIN(__nvvm_mul_rz_d, "ddd", "") -BUILTIN(__nvvm_mul_rm_d, "ddd", "") -BUILTIN(__nvvm_mul_rp_d, "ddd", "") - -BUILTIN(__nvvm_mul24_i, "iii", "") -BUILTIN(__nvvm_mul24_ui, "UiUiUi", "") - -// Div - -BUILTIN(__nvvm_div_approx_ftz_f, "fff", "") -BUILTIN(__nvvm_div_approx_f, "fff", "") - -BUILTIN(__nvvm_div_rn_ftz_f, "fff", "") -BUILTIN(__nvvm_div_rn_f, "fff", "") -BUILTIN(__nvvm_div_rz_ftz_f, "fff", "") -BUILTIN(__nvvm_div_rz_f, "fff", "") -BUILTIN(__nvvm_div_rm_ftz_f, "fff", "") -BUILTIN(__nvvm_div_rm_f, "fff", "") -BUILTIN(__nvvm_div_rp_ftz_f, "fff", "") -BUILTIN(__nvvm_div_rp_f, "fff", "") - -BUILTIN(__nvvm_div_rn_d, "ddd", "") -BUILTIN(__nvvm_div_rz_d, "ddd", "") -BUILTIN(__nvvm_div_rm_d, "ddd", "") -BUILTIN(__nvvm_div_rp_d, "ddd", "") - -// Sad - -BUILTIN(__nvvm_sad_i, "iiii", "") -BUILTIN(__nvvm_sad_ui, "UiUiUiUi", "") - -// Floor, Ceil - -BUILTIN(__nvvm_floor_ftz_f, "ff", "") -BUILTIN(__nvvm_floor_f, "ff", "") -BUILTIN(__nvvm_floor_d, "dd", "") - -BUILTIN(__nvvm_ceil_ftz_f, "ff", "") -BUILTIN(__nvvm_ceil_f, "ff", "") -BUILTIN(__nvvm_ceil_d, "dd", "") - -// Abs - -BUILTIN(__nvvm_fabs_ftz_f, "ff", "") -BUILTIN(__nvvm_fabs_f, "ff", "") -BUILTIN(__nvvm_fabs_d, "dd", "") - -// Round - -BUILTIN(__nvvm_round_ftz_f, "ff", "") -BUILTIN(__nvvm_round_f, "ff", "") -BUILTIN(__nvvm_round_d, "dd", "") - -// Trunc - -BUILTIN(__nvvm_trunc_ftz_f, "ff", "") -BUILTIN(__nvvm_trunc_f, "ff", "") -BUILTIN(__nvvm_trunc_d, "dd", "") - -// Saturate - -BUILTIN(__nvvm_saturate_ftz_f, "ff", "") -BUILTIN(__nvvm_saturate_f, "ff", "") -BUILTIN(__nvvm_saturate_d, "dd", "") - -// Exp2, Log2 - -BUILTIN(__nvvm_ex2_approx_ftz_f, "ff", "") -BUILTIN(__nvvm_ex2_approx_f, "ff", "") -BUILTIN(__nvvm_ex2_approx_d, "dd", "") -TARGET_BUILTIN(__nvvm_ex2_approx_f16, "hh", "", AND(SM_75, PTX70)) -TARGET_BUILTIN(__nvvm_ex2_approx_f16x2, "V2hV2h", "", AND(SM_75, PTX70)) - -BUILTIN(__nvvm_lg2_approx_ftz_f, "ff", "") -BUILTIN(__nvvm_lg2_approx_f, "ff", "") -BUILTIN(__nvvm_lg2_approx_d, "dd", "") - -// Sin, Cos - -BUILTIN(__nvvm_sin_approx_ftz_f, "ff", "") -BUILTIN(__nvvm_sin_approx_f, "ff", "") - -BUILTIN(__nvvm_cos_approx_ftz_f, "ff", "") -BUILTIN(__nvvm_cos_approx_f, "ff", "") - -// Fma - -TARGET_BUILTIN(__nvvm_fma_rn_f16, "hhhh", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_ftz_f16, "hhhh", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_sat_f16, "hhhh", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_ftz_sat_f16, "hhhh", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_relu_f16, "hhhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fma_rn_ftz_relu_f16, "hhhh", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fma_rn_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_ftz_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_sat_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_ftz_sat_f16x2, "V2hV2hV2hV2h", "", AND(SM_53, PTX42)) -TARGET_BUILTIN(__nvvm_fma_rn_relu_f16x2, "V2hV2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fma_rn_ftz_relu_f16x2, "V2hV2hV2hV2h", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fma_rn_bf16, "yyyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fma_rn_relu_bf16, "yyyy", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fma_rn_bf16x2, "V2yV2yV2yV2y", "", AND(SM_80, PTX70)) -TARGET_BUILTIN(__nvvm_fma_rn_relu_bf16x2, "V2yV2yV2yV2y", "", AND(SM_80, PTX70)) -BUILTIN(__nvvm_fma_rn_ftz_f, "ffff", "") -BUILTIN(__nvvm_fma_rn_f, "ffff", "") -BUILTIN(__nvvm_fma_rz_ftz_f, "ffff", "") -BUILTIN(__nvvm_fma_rz_f, "ffff", "") -BUILTIN(__nvvm_fma_rm_ftz_f, "ffff", "") -BUILTIN(__nvvm_fma_rm_f, "ffff", "") -BUILTIN(__nvvm_fma_rp_ftz_f, "ffff", "") -BUILTIN(__nvvm_fma_rp_f, "ffff", "") -BUILTIN(__nvvm_fma_rn_d, "dddd", "") -BUILTIN(__nvvm_fma_rz_d, "dddd", "") -BUILTIN(__nvvm_fma_rm_d, "dddd", "") -BUILTIN(__nvvm_fma_rp_d, "dddd", "") - -// Rcp - -BUILTIN(__nvvm_rcp_rn_ftz_f, "ff", "") -BUILTIN(__nvvm_rcp_rn_f, "ff", "") -BUILTIN(__nvvm_rcp_rz_ftz_f, "ff", "") -BUILTIN(__nvvm_rcp_rz_f, "ff", "") -BUILTIN(__nvvm_rcp_rm_ftz_f, "ff", "") -BUILTIN(__nvvm_rcp_rm_f, "ff", "") -BUILTIN(__nvvm_rcp_rp_ftz_f, "ff", "") -BUILTIN(__nvvm_rcp_rp_f, "ff", "") - -BUILTIN(__nvvm_rcp_rn_d, "dd", "") -BUILTIN(__nvvm_rcp_rz_d, "dd", "") -BUILTIN(__nvvm_rcp_rm_d, "dd", "") -BUILTIN(__nvvm_rcp_rp_d, "dd", "") - -BUILTIN(__nvvm_rcp_approx_ftz_f, "ff", "") -BUILTIN(__nvvm_rcp_approx_ftz_d, "dd", "") - -// Sqrt - -BUILTIN(__nvvm_sqrt_rn_ftz_f, "ff", "") -BUILTIN(__nvvm_sqrt_rn_f, "ff", "") -BUILTIN(__nvvm_sqrt_rz_ftz_f, "ff", "") -BUILTIN(__nvvm_sqrt_rz_f, "ff", "") -BUILTIN(__nvvm_sqrt_rm_ftz_f, "ff", "") -BUILTIN(__nvvm_sqrt_rm_f, "ff", "") -BUILTIN(__nvvm_sqrt_rp_ftz_f, "ff", "") -BUILTIN(__nvvm_sqrt_rp_f, "ff", "") -BUILTIN(__nvvm_sqrt_approx_ftz_f, "ff", "") -BUILTIN(__nvvm_sqrt_approx_f, "ff", "") - -BUILTIN(__nvvm_sqrt_rn_d, "dd", "") -BUILTIN(__nvvm_sqrt_rz_d, "dd", "") -BUILTIN(__nvvm_sqrt_rm_d, "dd", "") -BUILTIN(__nvvm_sqrt_rp_d, "dd", "") - -// Rsqrt - -BUILTIN(__nvvm_rsqrt_approx_ftz_f, "ff", "") -BUILTIN(__nvvm_rsqrt_approx_f, "ff", "") -BUILTIN(__nvvm_rsqrt_approx_d, "dd", "") - -// Add - -BUILTIN(__nvvm_add_rn_ftz_f, "fff", "") -BUILTIN(__nvvm_add_rn_f, "fff", "") -BUILTIN(__nvvm_add_rz_ftz_f, "fff", "") -BUILTIN(__nvvm_add_rz_f, "fff", "") -BUILTIN(__nvvm_add_rm_ftz_f, "fff", "") -BUILTIN(__nvvm_add_rm_f, "fff", "") -BUILTIN(__nvvm_add_rp_ftz_f, "fff", "") -BUILTIN(__nvvm_add_rp_f, "fff", "") - -BUILTIN(__nvvm_add_rn_d, "ddd", "") -BUILTIN(__nvvm_add_rz_d, "ddd", "") -BUILTIN(__nvvm_add_rm_d, "ddd", "") -BUILTIN(__nvvm_add_rp_d, "ddd", "") - -// Convert - -BUILTIN(__nvvm_d2f_rn_ftz, "fd", "") -BUILTIN(__nvvm_d2f_rn, "fd", "") -BUILTIN(__nvvm_d2f_rz_ftz, "fd", "") -BUILTIN(__nvvm_d2f_rz, "fd", "") -BUILTIN(__nvvm_d2f_rm_ftz, "fd", "") -BUILTIN(__nvvm_d2f_rm, "fd", "") -BUILTIN(__nvvm_d2f_rp_ftz, "fd", "") -BUILTIN(__nvvm_d2f_rp, "fd", "") - -BUILTIN(__nvvm_d2i_rn, "id", "") -BUILTIN(__nvvm_d2i_rz, "id", "") -BUILTIN(__nvvm_d2i_rm, "id", "") -BUILTIN(__nvvm_d2i_rp, "id", "") - -BUILTIN(__nvvm_d2ui_rn, "Uid", "") -BUILTIN(__nvvm_d2ui_rz, "Uid", "") -BUILTIN(__nvvm_d2ui_rm, "Uid", "") -BUILTIN(__nvvm_d2ui_rp, "Uid", "") - -BUILTIN(__nvvm_i2d_rn, "di", "") -BUILTIN(__nvvm_i2d_rz, "di", "") -BUILTIN(__nvvm_i2d_rm, "di", "") -BUILTIN(__nvvm_i2d_rp, "di", "") - -BUILTIN(__nvvm_ui2d_rn, "dUi", "") -BUILTIN(__nvvm_ui2d_rz, "dUi", "") -BUILTIN(__nvvm_ui2d_rm, "dUi", "") -BUILTIN(__nvvm_ui2d_rp, "dUi", "") - -BUILTIN(__nvvm_f2i_rn_ftz, "if", "") -BUILTIN(__nvvm_f2i_rn, "if", "") -BUILTIN(__nvvm_f2i_rz_ftz, "if", "") -BUILTIN(__nvvm_f2i_rz, "if", "") -BUILTIN(__nvvm_f2i_rm_ftz, "if", "") -BUILTIN(__nvvm_f2i_rm, "if", "") -BUILTIN(__nvvm_f2i_rp_ftz, "if", "") -BUILTIN(__nvvm_f2i_rp, "if", "") - -BUILTIN(__nvvm_f2ui_rn_ftz, "Uif", "") -BUILTIN(__nvvm_f2ui_rn, "Uif", "") -BUILTIN(__nvvm_f2ui_rz_ftz, "Uif", "") -BUILTIN(__nvvm_f2ui_rz, "Uif", "") -BUILTIN(__nvvm_f2ui_rm_ftz, "Uif", "") -BUILTIN(__nvvm_f2ui_rm, "Uif", "") -BUILTIN(__nvvm_f2ui_rp_ftz, "Uif", "") -BUILTIN(__nvvm_f2ui_rp, "Uif", "") - -BUILTIN(__nvvm_i2f_rn, "fi", "") -BUILTIN(__nvvm_i2f_rz, "fi", "") -BUILTIN(__nvvm_i2f_rm, "fi", "") -BUILTIN(__nvvm_i2f_rp, "fi", "") - -BUILTIN(__nvvm_ui2f_rn, "fUi", "") -BUILTIN(__nvvm_ui2f_rz, "fUi", "") -BUILTIN(__nvvm_ui2f_rm, "fUi", "") -BUILTIN(__nvvm_ui2f_rp, "fUi", "") - -BUILTIN(__nvvm_lohi_i2d, "dii", "") - -BUILTIN(__nvvm_d2i_lo, "id", "") -BUILTIN(__nvvm_d2i_hi, "id", "") - -BUILTIN(__nvvm_f2ll_rn_ftz, "LLif", "") -BUILTIN(__nvvm_f2ll_rn, "LLif", "") -BUILTIN(__nvvm_f2ll_rz_ftz, "LLif", "") -BUILTIN(__nvvm_f2ll_rz, "LLif", "") -BUILTIN(__nvvm_f2ll_rm_ftz, "LLif", "") -BUILTIN(__nvvm_f2ll_rm, "LLif", "") -BUILTIN(__nvvm_f2ll_rp_ftz, "LLif", "") -BUILTIN(__nvvm_f2ll_rp, "LLif", "") - -BUILTIN(__nvvm_f2ull_rn_ftz, "ULLif", "") -BUILTIN(__nvvm_f2ull_rn, "ULLif", "") -BUILTIN(__nvvm_f2ull_rz_ftz, "ULLif", "") -BUILTIN(__nvvm_f2ull_rz, "ULLif", "") -BUILTIN(__nvvm_f2ull_rm_ftz, "ULLif", "") -BUILTIN(__nvvm_f2ull_rm, "ULLif", "") -BUILTIN(__nvvm_f2ull_rp_ftz, "ULLif", "") -BUILTIN(__nvvm_f2ull_rp, "ULLif", "") - -BUILTIN(__nvvm_d2ll_rn, "LLid", "") -BUILTIN(__nvvm_d2ll_rz, "LLid", "") -BUILTIN(__nvvm_d2ll_rm, "LLid", "") -BUILTIN(__nvvm_d2ll_rp, "LLid", "") - -BUILTIN(__nvvm_d2ull_rn, "ULLid", "") -BUILTIN(__nvvm_d2ull_rz, "ULLid", "") -BUILTIN(__nvvm_d2ull_rm, "ULLid", "") -BUILTIN(__nvvm_d2ull_rp, "ULLid", "") - -BUILTIN(__nvvm_ll2f_rn, "fLLi", "") -BUILTIN(__nvvm_ll2f_rz, "fLLi", "") -BUILTIN(__nvvm_ll2f_rm, "fLLi", "") -BUILTIN(__nvvm_ll2f_rp, "fLLi", "") - -BUILTIN(__nvvm_ull2f_rn, "fULLi", "") -BUILTIN(__nvvm_ull2f_rz, "fULLi", "") -BUILTIN(__nvvm_ull2f_rm, "fULLi", "") -BUILTIN(__nvvm_ull2f_rp, "fULLi", "") - -BUILTIN(__nvvm_ll2d_rn, "dLLi", "") -BUILTIN(__nvvm_ll2d_rz, "dLLi", "") -BUILTIN(__nvvm_ll2d_rm, "dLLi", "") -BUILTIN(__nvvm_ll2d_rp, "dLLi", "") - -BUILTIN(__nvvm_ull2d_rn, "dULLi", "") -BUILTIN(__nvvm_ull2d_rz, "dULLi", "") -BUILTIN(__nvvm_ull2d_rm, "dULLi", "") -BUILTIN(__nvvm_ull2d_rp, "dULLi", "") - -BUILTIN(__nvvm_f2h_rn_ftz, "Usf", "") -BUILTIN(__nvvm_f2h_rn, "Usf", "") - -TARGET_BUILTIN(__nvvm_ff2bf16x2_rn, "V2yff", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_ff2bf16x2_rn_relu, "V2yff", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_ff2bf16x2_rz, "V2yff", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_ff2bf16x2_rz_relu, "V2yff", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_ff2f16x2_rn, "V2hff", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_ff2f16x2_rn_relu, "V2hff", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_ff2f16x2_rz, "V2hff", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_ff2f16x2_rz_relu, "V2hff", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_f2bf16_rn, "yf", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_f2bf16_rn_relu, "yf", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_f2bf16_rz, "yf", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_f2bf16_rz_relu, "yf", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_f2tf32_rna, "ZUif", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_ff_to_e4m3x2_rn, "sff", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_ff_to_e4m3x2_rn_relu, "sff", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_ff_to_e5m2x2_rn, "sff", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_ff_to_e5m2x2_rn_relu, "sff", "", AND(SM_89,PTX81)) - -TARGET_BUILTIN(__nvvm_f16x2_to_e4m3x2_rn, "sV2h", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_f16x2_to_e4m3x2_rn_relu, "sV2h", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_f16x2_to_e5m2x2_rn, "sV2h", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_f16x2_to_e5m2x2_rn_relu, "sV2h", "", AND(SM_89,PTX81)) - -TARGET_BUILTIN(__nvvm_e4m3x2_to_f16x2_rn, "V2hs", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_e4m3x2_to_f16x2_rn_relu, "V2hs", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_e5m2x2_to_f16x2_rn, "V2hs", "", AND(SM_89,PTX81)) -TARGET_BUILTIN(__nvvm_e5m2x2_to_f16x2_rn_relu, "V2hs", "", AND(SM_89,PTX81)) - -// FNS -TARGET_BUILTIN(__nvvm_fns, "UiUiUii", "n", PTX60) - -// Sync - -BUILTIN(__syncthreads, "v", "") -BUILTIN(__nvvm_bar0_popc, "ii", "") -BUILTIN(__nvvm_bar0_and, "ii", "") -BUILTIN(__nvvm_bar0_or, "ii", "") -BUILTIN(__nvvm_bar_sync, "vi", "n") -TARGET_BUILTIN(__nvvm_bar_warp_sync, "vUi", "n", PTX60) -TARGET_BUILTIN(__nvvm_barrier_sync, "vUi", "n", PTX60) -TARGET_BUILTIN(__nvvm_barrier_sync_cnt, "vUiUi", "n", PTX60) - -TARGET_BUILTIN(__nvvm_barrier_cluster_arrive, "v", "n", AND(SM_90,PTX78)) -TARGET_BUILTIN(__nvvm_barrier_cluster_arrive_relaxed, "v", "n", AND(SM_90,PTX80)) -TARGET_BUILTIN(__nvvm_barrier_cluster_wait, "v", "n", AND(SM_90,PTX78)) -TARGET_BUILTIN(__nvvm_fence_sc_cluster, "v", "n", AND(SM_90,PTX78)) - -// Shuffle - -BUILTIN(__nvvm_shfl_down_i32, "iiii", "") -BUILTIN(__nvvm_shfl_down_f32, "ffii", "") -BUILTIN(__nvvm_shfl_up_i32, "iiii", "") -BUILTIN(__nvvm_shfl_up_f32, "ffii", "") -BUILTIN(__nvvm_shfl_bfly_i32, "iiii", "") -BUILTIN(__nvvm_shfl_bfly_f32, "ffii", "") -BUILTIN(__nvvm_shfl_idx_i32, "iiii", "") -BUILTIN(__nvvm_shfl_idx_f32, "ffii", "") - -TARGET_BUILTIN(__nvvm_shfl_sync_down_i32, "iUiiii", "", PTX60) -TARGET_BUILTIN(__nvvm_shfl_sync_down_f32, "fUifii", "", PTX60) -TARGET_BUILTIN(__nvvm_shfl_sync_up_i32, "iUiiii", "", PTX60) -TARGET_BUILTIN(__nvvm_shfl_sync_up_f32, "fUifii", "", PTX60) -TARGET_BUILTIN(__nvvm_shfl_sync_bfly_i32, "iUiiii", "", PTX60) -TARGET_BUILTIN(__nvvm_shfl_sync_bfly_f32, "fUifii", "", PTX60) -TARGET_BUILTIN(__nvvm_shfl_sync_idx_i32, "iUiiii", "", PTX60) -TARGET_BUILTIN(__nvvm_shfl_sync_idx_f32, "fUifii", "", PTX60) - -// Vote -BUILTIN(__nvvm_vote_all, "bb", "") -BUILTIN(__nvvm_vote_any, "bb", "") -BUILTIN(__nvvm_vote_uni, "bb", "") -BUILTIN(__nvvm_vote_ballot, "Uib", "") - -TARGET_BUILTIN(__nvvm_vote_all_sync, "bUib", "", PTX60) -TARGET_BUILTIN(__nvvm_vote_any_sync, "bUib", "", PTX60) -TARGET_BUILTIN(__nvvm_vote_uni_sync, "bUib", "", PTX60) -TARGET_BUILTIN(__nvvm_vote_ballot_sync, "UiUib", "", PTX60) - -// Mask -TARGET_BUILTIN(__nvvm_activemask, "Ui", "n", PTX62) - -// Match -TARGET_BUILTIN(__nvvm_match_any_sync_i32, "UiUiUi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__nvvm_match_any_sync_i64, "UiUiWi", "", AND(SM_70,PTX60)) -// These return a pair {value, predicate}, which requires custom lowering. -TARGET_BUILTIN(__nvvm_match_all_sync_i32p, "UiUiUii*", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__nvvm_match_all_sync_i64p, "UiUiWii*", "", AND(SM_70,PTX60)) - -// Redux -TARGET_BUILTIN(__nvvm_redux_sync_add, "iii", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_redux_sync_min, "iii", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_redux_sync_max, "iii", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_redux_sync_umin, "UiUii", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_redux_sync_umax, "UiUii", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_redux_sync_and, "iii", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_redux_sync_xor, "iii", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_redux_sync_or, "iii", "", AND(SM_80,PTX70)) - -// Membar - -BUILTIN(__nvvm_membar_cta, "v", "") -BUILTIN(__nvvm_membar_gl, "v", "") -BUILTIN(__nvvm_membar_sys, "v", "") - -// mbarrier - -TARGET_BUILTIN(__nvvm_mbarrier_init, "vWi*i", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_init_shared, "vWi*3i", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_mbarrier_inval, "vWi*", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_inval_shared, "vWi*3", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_mbarrier_arrive, "WiWi*", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_arrive_shared, "WiWi*3", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_arrive_noComplete, "WiWi*i", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_arrive_noComplete_shared, "WiWi*3i", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_mbarrier_arrive_drop, "WiWi*", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_arrive_drop_shared, "WiWi*3", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_arrive_drop_noComplete, "WiWi*i", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_arrive_drop_noComplete_shared, "WiWi*3i", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_mbarrier_test_wait, "bWi*Wi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_mbarrier_test_wait_shared, "bWi*3Wi", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_mbarrier_pending_count, "iWi", "", AND(SM_80,PTX70)) - -// Memcpy, Memset - -BUILTIN(__nvvm_memcpy, "vUc*Uc*zi","") -BUILTIN(__nvvm_memset, "vUc*Uczi","") - -// Image - -BUILTIN(__builtin_ptx_read_image2Dfi_, "V4fiiii", "") -BUILTIN(__builtin_ptx_read_image2Dff_, "V4fiiff", "") -BUILTIN(__builtin_ptx_read_image2Dii_, "V4iiiii", "") -BUILTIN(__builtin_ptx_read_image2Dif_, "V4iiiff", "") - -BUILTIN(__builtin_ptx_read_image3Dfi_, "V4fiiiiii", "") -BUILTIN(__builtin_ptx_read_image3Dff_, "V4fiiffff", "") -BUILTIN(__builtin_ptx_read_image3Dii_, "V4iiiiiii", "") -BUILTIN(__builtin_ptx_read_image3Dif_, "V4iiiffff", "") - -BUILTIN(__builtin_ptx_write_image2Df_, "viiiffff", "") -BUILTIN(__builtin_ptx_write_image2Di_, "viiiiiii", "") -BUILTIN(__builtin_ptx_write_image2Dui_, "viiiUiUiUiUi", "") -BUILTIN(__builtin_ptx_get_image_depthi_, "ii", "") -BUILTIN(__builtin_ptx_get_image_heighti_, "ii", "") -BUILTIN(__builtin_ptx_get_image_widthi_, "ii", "") -BUILTIN(__builtin_ptx_get_image_channel_data_typei_, "ii", "") -BUILTIN(__builtin_ptx_get_image_channel_orderi_, "ii", "") - -// Atomic -// -// We need the atom intrinsics because -// - they are used in converging analysis -// - they are used in address space analysis and optimization -// So it does not hurt to expose them as builtins. -// -BUILTIN(__nvvm_atom_add_gen_i, "iiD*i", "n") -TARGET_BUILTIN(__nvvm_atom_cta_add_gen_i, "iiD*i", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_add_gen_i, "iiD*i", "n", SM_60) -BUILTIN(__nvvm_atom_add_gen_l, "LiLiD*Li", "n") -TARGET_BUILTIN(__nvvm_atom_cta_add_gen_l, "LiLiD*Li", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_add_gen_l, "LiLiD*Li", "n", SM_60) -BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_add_gen_ll, "LLiLLiD*LLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_add_gen_ll, "LLiLLiD*LLi", "n", SM_60) -BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n") -TARGET_BUILTIN(__nvvm_atom_cta_add_gen_f, "ffD*f", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_add_gen_f, "ffD*f", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", SM_60) - -BUILTIN(__nvvm_atom_sub_gen_i, "iiD*i", "n") -BUILTIN(__nvvm_atom_sub_gen_l, "LiLiD*Li", "n") -BUILTIN(__nvvm_atom_sub_gen_ll, "LLiLLiD*LLi", "n") - -BUILTIN(__nvvm_atom_xchg_gen_i, "iiD*i", "n") -TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_i, "iiD*i", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_i, "iiD*i", "n", SM_60) -BUILTIN(__nvvm_atom_xchg_gen_l, "LiLiD*Li", "n") -TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_l, "LiLiD*Li", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_l, "LiLiD*Li", "n", SM_60) -BUILTIN(__nvvm_atom_xchg_gen_ll, "LLiLLiD*LLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_xchg_gen_ll, "LLiLLiD*LLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_xchg_gen_ll, "LLiLLiD*LLi", "n", SM_60) - -BUILTIN(__nvvm_atom_max_gen_i, "iiD*i", "n") -TARGET_BUILTIN(__nvvm_atom_cta_max_gen_i, "iiD*i", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_max_gen_i, "iiD*i", "n", SM_60) -BUILTIN(__nvvm_atom_max_gen_ui, "UiUiD*Ui", "n") -TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ui, "UiUiD*Ui", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ui, "UiUiD*Ui", "n", SM_60) -BUILTIN(__nvvm_atom_max_gen_l, "LiLiD*Li", "n") -TARGET_BUILTIN(__nvvm_atom_cta_max_gen_l, "LiLiD*Li", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_max_gen_l, "LiLiD*Li", "n", SM_60) -BUILTIN(__nvvm_atom_max_gen_ul, "ULiULiD*ULi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ul, "ULiULiD*ULi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ul, "ULiULiD*ULi", "n", SM_60) -BUILTIN(__nvvm_atom_max_gen_ll, "LLiLLiD*LLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ll, "LLiLLiD*LLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ll, "LLiLLiD*LLi", "n", SM_60) -BUILTIN(__nvvm_atom_max_gen_ull, "ULLiULLiD*ULLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_max_gen_ull, "ULLiULLiD*ULLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_max_gen_ull, "ULLiULLiD*ULLi", "n", SM_60) - -BUILTIN(__nvvm_atom_min_gen_i, "iiD*i", "n") -TARGET_BUILTIN(__nvvm_atom_cta_min_gen_i, "iiD*i", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_min_gen_i, "iiD*i", "n", SM_60) -BUILTIN(__nvvm_atom_min_gen_ui, "UiUiD*Ui", "n") -TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ui, "UiUiD*Ui", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ui, "UiUiD*Ui", "n", SM_60) -BUILTIN(__nvvm_atom_min_gen_l, "LiLiD*Li", "n") -TARGET_BUILTIN(__nvvm_atom_cta_min_gen_l, "LiLiD*Li", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_min_gen_l, "LiLiD*Li", "n", SM_60) -BUILTIN(__nvvm_atom_min_gen_ul, "ULiULiD*ULi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ul, "ULiULiD*ULi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ul, "ULiULiD*ULi", "n", SM_60) -BUILTIN(__nvvm_atom_min_gen_ll, "LLiLLiD*LLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ll, "LLiLLiD*LLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ll, "LLiLLiD*LLi", "n", SM_60) -BUILTIN(__nvvm_atom_min_gen_ull, "ULLiULLiD*ULLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_min_gen_ull, "ULLiULLiD*ULLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_min_gen_ull, "ULLiULLiD*ULLi", "n", SM_60) - -BUILTIN(__nvvm_atom_inc_gen_ui, "UiUiD*Ui", "n") -TARGET_BUILTIN(__nvvm_atom_cta_inc_gen_ui, "UiUiD*Ui", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_inc_gen_ui, "UiUiD*Ui", "n", SM_60) -BUILTIN(__nvvm_atom_dec_gen_ui, "UiUiD*Ui", "n") -TARGET_BUILTIN(__nvvm_atom_cta_dec_gen_ui, "UiUiD*Ui", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_dec_gen_ui, "UiUiD*Ui", "n", SM_60) - -BUILTIN(__nvvm_atom_and_gen_i, "iiD*i", "n") -TARGET_BUILTIN(__nvvm_atom_cta_and_gen_i, "iiD*i", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_and_gen_i, "iiD*i", "n", SM_60) -BUILTIN(__nvvm_atom_and_gen_l, "LiLiD*Li", "n") -TARGET_BUILTIN(__nvvm_atom_cta_and_gen_l, "LiLiD*Li", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_and_gen_l, "LiLiD*Li", "n", SM_60) -BUILTIN(__nvvm_atom_and_gen_ll, "LLiLLiD*LLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_and_gen_ll, "LLiLLiD*LLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_and_gen_ll, "LLiLLiD*LLi", "n", SM_60) - -BUILTIN(__nvvm_atom_or_gen_i, "iiD*i", "n") -TARGET_BUILTIN(__nvvm_atom_cta_or_gen_i, "iiD*i", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_or_gen_i, "iiD*i", "n", SM_60) -BUILTIN(__nvvm_atom_or_gen_l, "LiLiD*Li", "n") -TARGET_BUILTIN(__nvvm_atom_cta_or_gen_l, "LiLiD*Li", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_or_gen_l, "LiLiD*Li", "n", SM_60) -BUILTIN(__nvvm_atom_or_gen_ll, "LLiLLiD*LLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_or_gen_ll, "LLiLLiD*LLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_or_gen_ll, "LLiLLiD*LLi", "n", SM_60) - -BUILTIN(__nvvm_atom_xor_gen_i, "iiD*i", "n") -TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_i, "iiD*i", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_i, "iiD*i", "n", SM_60) -BUILTIN(__nvvm_atom_xor_gen_l, "LiLiD*Li", "n") -TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_l, "LiLiD*Li", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_l, "LiLiD*Li", "n", SM_60) -BUILTIN(__nvvm_atom_xor_gen_ll, "LLiLLiD*LLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_xor_gen_ll, "LLiLLiD*LLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_xor_gen_ll, "LLiLLiD*LLi", "n", SM_60) - -TARGET_BUILTIN(__nvvm_atom_cas_gen_us, "UsUsD*UsUs", "n", SM_70) -TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_us, "UsUsD*UsUs", "n", SM_70) -TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_us, "UsUsD*UsUs", "n", SM_70) -BUILTIN(__nvvm_atom_cas_gen_i, "iiD*ii", "n") -TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_i, "iiD*ii", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_i, "iiD*ii", "n", SM_60) -BUILTIN(__nvvm_atom_cas_gen_l, "LiLiD*LiLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_l, "LiLiD*LiLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_l, "LiLiD*LiLi", "n", SM_60) -BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n") -TARGET_BUILTIN(__nvvm_atom_cta_cas_gen_ll, "LLiLLiD*LLiLLi", "n", SM_60) -TARGET_BUILTIN(__nvvm_atom_sys_cas_gen_ll, "LLiLLiD*LLiLLi", "n", SM_60) - -// Compiler Error Warn -BUILTIN(__nvvm_compiler_error, "vcC*4", "n") -BUILTIN(__nvvm_compiler_warn, "vcC*4", "n") - -BUILTIN(__nvvm_ldu_c, "ccC*", "") -BUILTIN(__nvvm_ldu_sc, "ScScC*", "") -BUILTIN(__nvvm_ldu_s, "ssC*", "") -BUILTIN(__nvvm_ldu_i, "iiC*", "") -BUILTIN(__nvvm_ldu_l, "LiLiC*", "") -BUILTIN(__nvvm_ldu_ll, "LLiLLiC*", "") - -BUILTIN(__nvvm_ldu_uc, "UcUcC*", "") -BUILTIN(__nvvm_ldu_us, "UsUsC*", "") -BUILTIN(__nvvm_ldu_ui, "UiUiC*", "") -BUILTIN(__nvvm_ldu_ul, "ULiULiC*", "") -BUILTIN(__nvvm_ldu_ull, "ULLiULLiC*", "") - -BUILTIN(__nvvm_ldu_h, "hhC*", "") -BUILTIN(__nvvm_ldu_f, "ffC*", "") -BUILTIN(__nvvm_ldu_d, "ddC*", "") - -BUILTIN(__nvvm_ldu_c2, "E2cE2cC*", "") -BUILTIN(__nvvm_ldu_sc2, "E2ScE2ScC*", "") -BUILTIN(__nvvm_ldu_c4, "E4cE4cC*", "") -BUILTIN(__nvvm_ldu_sc4, "E4ScE4ScC*", "") -BUILTIN(__nvvm_ldu_s2, "E2sE2sC*", "") -BUILTIN(__nvvm_ldu_s4, "E4sE4sC*", "") -BUILTIN(__nvvm_ldu_i2, "E2iE2iC*", "") -BUILTIN(__nvvm_ldu_i4, "E4iE4iC*", "") -BUILTIN(__nvvm_ldu_l2, "E2LiE2LiC*", "") -BUILTIN(__nvvm_ldu_ll2, "E2LLiE2LLiC*", "") - -BUILTIN(__nvvm_ldu_uc2, "E2UcE2UcC*", "") -BUILTIN(__nvvm_ldu_uc4, "E4UcE4UcC*", "") -BUILTIN(__nvvm_ldu_us2, "E2UsE2UsC*", "") -BUILTIN(__nvvm_ldu_us4, "E4UsE4UsC*", "") -BUILTIN(__nvvm_ldu_ui2, "E2UiE2UiC*", "") -BUILTIN(__nvvm_ldu_ui4, "E4UiE4UiC*", "") -BUILTIN(__nvvm_ldu_ul2, "E2ULiE2ULiC*", "") -BUILTIN(__nvvm_ldu_ull2, "E2ULLiE2ULLiC*", "") - -BUILTIN(__nvvm_ldu_h2, "E2hE2hC*", "") -BUILTIN(__nvvm_ldu_f2, "E2fE2fC*", "") -BUILTIN(__nvvm_ldu_f4, "E4fE4fC*", "") -BUILTIN(__nvvm_ldu_d2, "E2dE2dC*", "") - -BUILTIN(__nvvm_ldg_c, "ccC*", "") -BUILTIN(__nvvm_ldg_sc, "ScScC*", "") -BUILTIN(__nvvm_ldg_s, "ssC*", "") -BUILTIN(__nvvm_ldg_i, "iiC*", "") -BUILTIN(__nvvm_ldg_l, "LiLiC*", "") -BUILTIN(__nvvm_ldg_ll, "LLiLLiC*", "") - -BUILTIN(__nvvm_ldg_uc, "UcUcC*", "") -BUILTIN(__nvvm_ldg_us, "UsUsC*", "") -BUILTIN(__nvvm_ldg_ui, "UiUiC*", "") -BUILTIN(__nvvm_ldg_ul, "ULiULiC*", "") -BUILTIN(__nvvm_ldg_ull, "ULLiULLiC*", "") - -BUILTIN(__nvvm_ldg_h, "hhC*", "") -BUILTIN(__nvvm_ldg_f, "ffC*", "") -BUILTIN(__nvvm_ldg_d, "ddC*", "") - -BUILTIN(__nvvm_ldg_c2, "E2cE2cC*", "") -BUILTIN(__nvvm_ldg_sc2, "E2ScE2ScC*", "") -BUILTIN(__nvvm_ldg_c4, "E4cE4cC*", "") -BUILTIN(__nvvm_ldg_sc4, "E4ScE4ScC*", "") -BUILTIN(__nvvm_ldg_s2, "E2sE2sC*", "") -BUILTIN(__nvvm_ldg_s4, "E4sE4sC*", "") -BUILTIN(__nvvm_ldg_i2, "E2iE2iC*", "") -BUILTIN(__nvvm_ldg_i4, "E4iE4iC*", "") -BUILTIN(__nvvm_ldg_l2, "E2LiE2LiC*", "") -BUILTIN(__nvvm_ldg_ll2, "E2LLiE2LLiC*", "") - -BUILTIN(__nvvm_ldg_uc2, "E2UcE2UcC*", "") -BUILTIN(__nvvm_ldg_uc4, "E4UcE4UcC*", "") -BUILTIN(__nvvm_ldg_us2, "E2UsE2UsC*", "") -BUILTIN(__nvvm_ldg_us4, "E4UsE4UsC*", "") -BUILTIN(__nvvm_ldg_ui2, "E2UiE2UiC*", "") -BUILTIN(__nvvm_ldg_ui4, "E4UiE4UiC*", "") -BUILTIN(__nvvm_ldg_ul2, "E2ULiE2ULiC*", "") -BUILTIN(__nvvm_ldg_ull2, "E2ULLiE2ULLiC*", "") - -BUILTIN(__nvvm_ldg_h2, "E2hE2hC*", "") -BUILTIN(__nvvm_ldg_f2, "E2fE2fC*", "") -BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "") -BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "") - -// Address space predicates. -BUILTIN(__nvvm_isspacep_const, "bvC*", "nc") -BUILTIN(__nvvm_isspacep_global, "bvC*", "nc") -BUILTIN(__nvvm_isspacep_local, "bvC*", "nc") -BUILTIN(__nvvm_isspacep_shared, "bvC*", "nc") -TARGET_BUILTIN(__nvvm_isspacep_shared_cluster,"bvC*", "nc", AND(SM_90,PTX78)) - -// Builtins to support WMMA instructions on sm_70 -TARGET_BUILTIN(__hmma_m16n16k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_st_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_st_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX60)) - -TARGET_BUILTIN(__hmma_m32n8k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_st_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_st_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61)) - -TARGET_BUILTIN(__hmma_m8n32k16_ld_a, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_ld_b, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_ld_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_ld_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_st_c_f16, "vi*iC*UiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_st_c_f32, "vf*fC*UiIi", "", AND(SM_70,PTX61)) - -TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX60)) -TARGET_BUILTIN(__hmma_m16n16k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX60)) - -TARGET_BUILTIN(__hmma_m32n8k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m32n8k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) - -TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f16, "vi*iC*iC*iC*IiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f16, "vf*iC*iC*iC*IiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_mma_f32f32, "vf*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) -TARGET_BUILTIN(__hmma_m8n32k16_mma_f16f32, "vi*iC*iC*fC*IiIi", "", AND(SM_70,PTX61)) - -// Builtins to support integer and sub-integer WMMA instructions on sm_72/sm_75 -TARGET_BUILTIN(__bmma_m8n8k128_ld_a_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__bmma_m8n8k128_ld_b_b1, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__bmma_m8n8k128_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__bmma_m8n8k128_mma_and_popc_b1, "vi*iC*iC*iC*Ii", "", AND(SM_80,PTX71)) -TARGET_BUILTIN(__bmma_m8n8k128_mma_xor_popc_b1, "vi*iC*iC*iC*Ii", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__bmma_m8n8k128_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m16n16k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m32n8k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_ld_a_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_ld_a_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_ld_b_s8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_ld_b_u8, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_ld_c, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_mma_s8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_mma_u8, "vi*iC*iC*iC*IiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n32k16_st_c_i32, "vi*iC*UiIi", "", AND(SM_72,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_ld_a_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_ld_a_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_ld_b_s4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_ld_b_u4, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_ld_c, "vi*iC*UiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_mma_s4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_mma_u4, "vi*iC*iC*iC*IiIi", "", AND(SM_75,PTX63)) -TARGET_BUILTIN(__imma_m8n8k32_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63)) - -// Builtins to support double and alternate float WMMA instructions on sm_80 -TARGET_BUILTIN(__dmma_m8n8k4_ld_a, "vd*dC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__dmma_m8n8k4_ld_b, "vd*dC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__dmma_m8n8k4_ld_c, "vd*dC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__dmma_m8n8k4_st_c_f64, "vd*dC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__dmma_m8n8k4_mma_f64, "vd*dC*dC*dC*IiIi", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__mma_bf16_m16n16k16_ld_a, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m16n16k16_ld_b, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m16n16k16_mma_f32, "vf*iC*iC*fC*IiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m8n32k16_ld_a, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m8n32k16_ld_b, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m8n32k16_mma_f32, "vf*iC*iC*fC*IiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m32n8k16_ld_a, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m32n8k16_ld_b, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_bf16_m32n8k16_mma_f32, "vf*iC*iC*fC*IiIi", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__mma_tf32_m16n16k8_ld_a, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_tf32_m16n16k8_ld_b, "vi*iC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_tf32_m16n16k8_ld_c, "vf*fC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_m16n16k8_st_c_f32, "vf*fC*UiIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__mma_tf32_m16n16k8_mma_f32, "vf*iC*iC*fC*IiIi", "", AND(SM_80,PTX70)) - -// Async Copy -TARGET_BUILTIN(__nvvm_cp_async_mbarrier_arrive, "vWi*", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_mbarrier_arrive_shared, "vWi*3", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_mbarrier_arrive_noinc, "vWi*", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_mbarrier_arrive_noinc_shared, "vWi*3", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_4, "vv*3vC*1.", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_8, "vv*3vC*1.", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_ca_shared_global_16, "vv*3vC*1.", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_cg_shared_global_16, "vv*3vC*1.", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_cp_async_commit_group, "v", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_wait_group, "vIi", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_cp_async_wait_all, "v", "", AND(SM_80,PTX70)) - - -// bf16, bf16x2 abs, neg -TARGET_BUILTIN(__nvvm_abs_bf16, "yy", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_abs_bf16x2, "V2yV2y", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_neg_bf16, "yy", "", AND(SM_80,PTX70)) -TARGET_BUILTIN(__nvvm_neg_bf16x2, "V2yV2y", "", AND(SM_80,PTX70)) - -TARGET_BUILTIN(__nvvm_mapa, "v*v*i", "", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_mapa_shared_cluster, "v*3v*3i", "", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_getctarank, "iv*", "", AND(SM_90, PTX78)) -TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78)) - -#undef BUILTIN -#undef TARGET_BUILTIN -#pragma pop_macro("AND") -#pragma pop_macro("SM_53") -#pragma pop_macro("SM_60") -#pragma pop_macro("SM_70") -#pragma pop_macro("SM_72") -#pragma pop_macro("SM_75") -#pragma pop_macro("SM_80") -#pragma pop_macro("SM_86") -#pragma pop_macro("SM_87") -#pragma pop_macro("SM_89") -#pragma pop_macro("SM_90") -#pragma pop_macro("SM_90a") -#pragma pop_macro("SM_100") -#pragma pop_macro("SM_100a") -#pragma pop_macro("PTX42") -#pragma pop_macro("PTX60") -#pragma pop_macro("PTX61") -#pragma pop_macro("PTX62") -#pragma pop_macro("PTX63") -#pragma pop_macro("PTX64") -#pragma pop_macro("PTX65") -#pragma pop_macro("PTX70") -#pragma pop_macro("PTX71") -#pragma pop_macro("PTX72") -#pragma pop_macro("PTX73") -#pragma pop_macro("PTX74") -#pragma pop_macro("PTX75") -#pragma pop_macro("PTX76") -#pragma pop_macro("PTX77") -#pragma pop_macro("PTX78") -#pragma pop_macro("PTX80") -#pragma pop_macro("PTX81") -#pragma pop_macro("PTX82") -#pragma pop_macro("PTX83") -#pragma pop_macro("PTX84") -#pragma pop_macro("PTX85") -#pragma pop_macro("PTX86") diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.td b/clang/include/clang/Basic/BuiltinsNVPTX.td new file mode 100644 index 0000000000000..9d24a992563a4 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsNVPTX.td @@ -0,0 +1,1079 @@ +//===--- BuiltinsNVPTX.td - NVPTX Builtin function defs ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the PTX-specific builtin function database. +// +//===----------------------------------------------------------------------===// + +include "clang/Basic/BuiltinsBase.td" + +class SMFeatures { + string Features; +} + +class SM newer_list> : SMFeatures { + let Features = !foldl(!strconcat("sm_", version), newer_list, f, newer, + !strconcat(f, "|", newer.Features)); +} + +let Features = "sm_100a" in def SM_100a : SMFeatures; + +def SM_100 : SM<"100", [SM_100a]>; + +let Features = "sm_90a" in def SM_90a : SMFeatures; + +def SM_90 : SM<"90", [SM_90a, SM_100]>; +def SM_89 : SM<"89", [SM_90]>; +def SM_87 : SM<"87", [SM_89]>; +def SM_86 : SM<"86", [SM_87]>; +def SM_80 : SM<"80", [SM_86]>; +def SM_75 : SM<"75", [SM_80]>; +def SM_72 : SM<"72", [SM_75]>; +def SM_70 : SM<"70", [SM_72]>; +def SM_62 : SM<"62", [SM_70]>; +def SM_61 : SM<"61", [SM_62]>; +def SM_60 : SM<"60", [SM_61]>; +def SM_53 : SM<"53", [SM_60]>; + +class PTXFeatures { + string Features; +} + +class PTX : PTXFeatures { + let Features = !strconcat("ptx", version, "|", newer.Features); +} + +let Features = "ptx87" in def PTX87 : PTXFeatures; + +def PTX86 : PTX<"86", PTX87>; +def PTX85 : PTX<"85", PTX86>; +def PTX84 : PTX<"84", PTX85>; +def PTX83 : PTX<"83", PTX84>; +def PTX82 : PTX<"82", PTX83>; +def PTX81 : PTX<"81", PTX82>; +def PTX80 : PTX<"80", PTX81>; +def PTX78 : PTX<"78", PTX80>; +def PTX77 : PTX<"77", PTX78>; +def PTX76 : PTX<"76", PTX77>; +def PTX75 : PTX<"75", PTX76>; +def PTX74 : PTX<"74", PTX75>; +def PTX73 : PTX<"73", PTX74>; +def PTX72 : PTX<"72", PTX73>; +def PTX71 : PTX<"71", PTX72>; +def PTX70 : PTX<"70", PTX71>; +def PTX65 : PTX<"65", PTX70>; +def PTX64 : PTX<"64", PTX65>; +def PTX63 : PTX<"63", PTX64>; +def PTX62 : PTX<"62", PTX63>; +def PTX61 : PTX<"61", PTX62>; +def PTX60 : PTX<"60", PTX61>; +def PTX42 : PTX<"42", PTX60>; + +class NVPTXBuiltin : TargetBuiltin { + let Spellings = [NAME]; + let Prototype = prototype; +} + +class NVPTXBuiltinSM : NVPTXBuiltin { + let Features = sm.Features; +} + +class NVPTXBuiltinPTX : NVPTXBuiltin { + let Features = ptx.Features; +} + +class NVPTXBuiltinSMAndPTX : NVPTXBuiltin { + let Features = !strconcat("(", sm.Features, "),(", ptx.Features, ")"); +} + +// Special Registers + +let Attributes = [NoThrow, Const] in { + def __nvvm_read_ptx_sreg_tid_x : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_tid_y : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_tid_z : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_tid_w : NVPTXBuiltin<"int()">; + + def __nvvm_read_ptx_sreg_ntid_x : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_ntid_y : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_ntid_z : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_ntid_w : NVPTXBuiltin<"int()">; + + def __nvvm_read_ptx_sreg_ctaid_x : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_ctaid_y : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_ctaid_z : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_ctaid_w : NVPTXBuiltin<"int()">; + + def __nvvm_read_ptx_sreg_nctaid_x : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_nctaid_y : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_nctaid_z : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_nctaid_w : NVPTXBuiltin<"int()">; + + def __nvvm_read_ptx_sreg_clusterid_x : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_clusterid_y : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_clusterid_z : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_clusterid_w : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + + def __nvvm_read_ptx_sreg_nclusterid_x : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_nclusterid_y : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_nclusterid_z : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_nclusterid_w : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + + def __nvvm_read_ptx_sreg_cluster_ctaid_x : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_cluster_ctaid_y : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_cluster_ctaid_z : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_cluster_ctaid_w : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + + def __nvvm_read_ptx_sreg_cluster_nctaid_x : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_cluster_nctaid_y : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_cluster_nctaid_z : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_cluster_nctaid_w : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + + def __nvvm_read_ptx_sreg_cluster_ctarank : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + def __nvvm_read_ptx_sreg_cluster_nctarank : NVPTXBuiltinSMAndPTX<"int()", SM_90, PTX78>; + + def __nvvm_is_explicit_cluster : NVPTXBuiltinSMAndPTX<"bool()", SM_90, PTX78>; + + def __nvvm_read_ptx_sreg_laneid : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_warpid : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_nwarpid : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_warpsize : NVPTXBuiltin<"int()">; + + def __nvvm_read_ptx_sreg_smid : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_nsmid : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_gridid : NVPTXBuiltin<"int()">; + + def __nvvm_read_ptx_sreg_lanemask_eq : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_lanemask_le : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_lanemask_lt : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_lanemask_ge : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_lanemask_gt : NVPTXBuiltin<"int()">; +} + +let Attributes = [NoThrow] in { + def __nvvm_read_ptx_sreg_clock : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_clock64 : NVPTXBuiltin<"long long int()">; + def __nvvm_read_ptx_sreg_globaltimer : NVPTXBuiltin<"long long int()">; + + def __nvvm_read_ptx_sreg_pm0 : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_pm1 : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_pm2 : NVPTXBuiltin<"int()">; + def __nvvm_read_ptx_sreg_pm3 : NVPTXBuiltin<"int()">; +} + +// MISC + +def __nvvm_prmt : NVPTXBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)">; +let Attributes = [NoReturn] in { + def __nvvm_exit : NVPTXBuiltin<"void()">; + def __nvvm_reflect : NVPTXBuiltin<"unsigned int(char const *)">; +} +let Attributes = [NoThrow] in { + def __nvvm_nanosleep : NVPTXBuiltinSMAndPTX<"void(unsigned int)", SM_70, PTX63>; +} + +// Min Max + +def __nvvm_fmin_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmin_ftz_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmin_nan_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmin_ftz_nan_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmin_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmin_ftz_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmin_nan_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmin_ftz_nan_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmin_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmin_ftz_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmin_nan_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmin_ftz_nan_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmin_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmin_ftz_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmin_nan_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmin_ftz_nan_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmin_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmin_ftz_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmin_nan_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmin_ftz_nan_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmin_xorsign_abs_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_86, PTX72>; +def __nvvm_fmin_nan_xorsign_abs_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_86, PTX72>; +def __nvvm_fmin_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmin_ftz_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmin_nan_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmin_ftz_nan_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmin_xorsign_abs_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_86, PTX72>; +def __nvvm_fmin_nan_xorsign_abs_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_86, PTX72>; +def __nvvm_fmin_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_fmin_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_fmin_nan_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_80, PTX70>; +def __nvvm_fmin_ftz_nan_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_80, PTX70>; +def __nvvm_fmin_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmin_ftz_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmin_nan_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmin_ftz_nan_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmin_d : NVPTXBuiltin<"double(double, double)">; + +def __nvvm_fmax_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmax_ftz_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmax_nan_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmax_ftz_nan_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fmax_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmax_ftz_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmax_nan_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmax_ftz_nan_xorsign_abs_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16)", SM_86, PTX72>; +def __nvvm_fmax_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmax_ftz_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmax_nan_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmax_ftz_nan_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fmax_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmax_ftz_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmax_nan_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmax_ftz_nan_xorsign_abs_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>)", SM_86, PTX72>; +def __nvvm_fmax_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmax_ftz_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmax_nan_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmax_ftz_nan_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fmax_xorsign_abs_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_86, PTX72>; +def __nvvm_fmax_nan_xorsign_abs_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16)", SM_86, PTX72>; +def __nvvm_fmax_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmax_ftz_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmax_nan_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmax_ftz_nan_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fmax_xorsign_abs_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_86, PTX72>; +def __nvvm_fmax_nan_xorsign_abs_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>)", SM_86, PTX72>; +def __nvvm_fmax_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_fmax_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_fmax_nan_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_80, PTX70>; +def __nvvm_fmax_ftz_nan_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_80, PTX70>; +def __nvvm_fmax_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmax_ftz_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmax_nan_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmax_ftz_nan_xorsign_abs_f : NVPTXBuiltinSMAndPTX<"float(float, float)", SM_86, PTX72>; +def __nvvm_fmax_d : NVPTXBuiltin<"double(double, double)">; + +// Multiplication + +def __nvvm_mulhi_i : NVPTXBuiltin<"int(int, int)">; +def __nvvm_mulhi_ui : NVPTXBuiltin<"unsigned int(unsigned int, unsigned int)">; +def __nvvm_mulhi_ll : NVPTXBuiltin<"long long int(long long int, long long int)">; +def __nvvm_mulhi_ull : NVPTXBuiltin<"unsigned long long int(unsigned long long int, unsigned long long int)">; + +def __nvvm_mul_rn_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_mul_rn_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_mul_rz_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_mul_rz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_mul_rm_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_mul_rm_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_mul_rp_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_mul_rp_f : NVPTXBuiltin<"float(float, float)">; + +def __nvvm_mul_rn_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_mul_rz_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_mul_rm_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_mul_rp_d : NVPTXBuiltin<"double(double, double)">; + +def __nvvm_mul24_i : NVPTXBuiltin<"int(int, int)">; +def __nvvm_mul24_ui : NVPTXBuiltin<"unsigned int(unsigned int, unsigned int)">; + +// Div + +def __nvvm_div_approx_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_approx_f : NVPTXBuiltin<"float(float, float)">; + +def __nvvm_div_rn_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_rn_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_rz_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_rz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_rm_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_rm_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_rp_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_div_rp_f : NVPTXBuiltin<"float(float, float)">; + +def __nvvm_div_rn_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_div_rz_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_div_rm_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_div_rp_d : NVPTXBuiltin<"double(double, double)">; + +// Sad + +def __nvvm_sad_i : NVPTXBuiltin<"int(int, int, int)">; +def __nvvm_sad_ui : NVPTXBuiltin<"unsigned int(unsigned int, unsigned int, unsigned int)">; + +// Floor, Ceil + +def __nvvm_floor_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_floor_f : NVPTXBuiltin<"float(float)">; +def __nvvm_floor_d : NVPTXBuiltin<"double(double)">; + +def __nvvm_ceil_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_ceil_f : NVPTXBuiltin<"float(float)">; +def __nvvm_ceil_d : NVPTXBuiltin<"double(double)">; + +// Abs + +def __nvvm_fabs_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_fabs_f : NVPTXBuiltin<"float(float)">; +def __nvvm_fabs_d : NVPTXBuiltin<"double(double)">; + +// Round + +def __nvvm_round_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_round_f : NVPTXBuiltin<"float(float)">; +def __nvvm_round_d : NVPTXBuiltin<"double(double)">; + +// Trunc + +def __nvvm_trunc_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_trunc_f : NVPTXBuiltin<"float(float)">; +def __nvvm_trunc_d : NVPTXBuiltin<"double(double)">; + +// Saturate + +def __nvvm_saturate_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_saturate_f : NVPTXBuiltin<"float(float)">; +def __nvvm_saturate_d : NVPTXBuiltin<"double(double)">; + +// Exp2, Log2 + +def __nvvm_ex2_approx_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_ex2_approx_f : NVPTXBuiltin<"float(float)">; +def __nvvm_ex2_approx_d : NVPTXBuiltin<"double(double)">; +def __nvvm_ex2_approx_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16)", SM_75, PTX70>; +def __nvvm_ex2_approx_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>)", SM_75, PTX70>; + +def __nvvm_lg2_approx_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_lg2_approx_f : NVPTXBuiltin<"float(float)">; +def __nvvm_lg2_approx_d : NVPTXBuiltin<"double(double)">; + +// Sin, Cos + +def __nvvm_sin_approx_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sin_approx_f : NVPTXBuiltin<"float(float)">; + +def __nvvm_cos_approx_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_cos_approx_f : NVPTXBuiltin<"float(float)">; + +// Fma + +def __nvvm_fma_rn_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16, __fp16)", SM_53, PTX42>; +def __nvvm_fma_rn_ftz_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16, __fp16)", SM_53, PTX42>; +def __nvvm_fma_rn_sat_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16, __fp16)", SM_53, PTX42>; +def __nvvm_fma_rn_ftz_sat_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16, __fp16)", SM_53, PTX42>; +def __nvvm_fma_rn_relu_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fma_rn_ftz_relu_f16 : NVPTXBuiltinSMAndPTX<"__fp16(__fp16, __fp16, __fp16)", SM_80, PTX70>; +def __nvvm_fma_rn_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>, _Vector<2, __fp16>)", SM_53, PTX42>; +def __nvvm_fma_rn_ftz_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>, _Vector<2, __fp16>)", SM_53, PTX42>; +def __nvvm_fma_rn_sat_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>, _Vector<2, __fp16>)", SM_53, PTX42>; +def __nvvm_fma_rn_ftz_sat_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>, _Vector<2, __fp16>)", SM_53, PTX42>; +def __nvvm_fma_rn_relu_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fma_rn_ftz_relu_f16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(_Vector<2, __fp16>, _Vector<2, __fp16>, _Vector<2, __fp16>)", SM_80, PTX70>; +def __nvvm_fma_rn_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fma_rn_relu_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16, __bf16, __bf16)", SM_80, PTX70>; +def __nvvm_fma_rn_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fma_rn_relu_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>, _Vector<2, __bf16>, _Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_fma_rn_ftz_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rn_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rz_ftz_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rz_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rm_ftz_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rm_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rp_ftz_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rp_f : NVPTXBuiltin<"float(float, float, float)">; +def __nvvm_fma_rn_d : NVPTXBuiltin<"double(double, double, double)">; +def __nvvm_fma_rz_d : NVPTXBuiltin<"double(double, double, double)">; +def __nvvm_fma_rm_d : NVPTXBuiltin<"double(double, double, double)">; +def __nvvm_fma_rp_d : NVPTXBuiltin<"double(double, double, double)">; + +// Rcp + +def __nvvm_rcp_rn_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_rn_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_rz_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_rz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_rm_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_rm_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_rp_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_rp_f : NVPTXBuiltin<"float(float)">; + +def __nvvm_rcp_rn_d : NVPTXBuiltin<"double(double)">; +def __nvvm_rcp_rz_d : NVPTXBuiltin<"double(double)">; +def __nvvm_rcp_rm_d : NVPTXBuiltin<"double(double)">; +def __nvvm_rcp_rp_d : NVPTXBuiltin<"double(double)">; + +def __nvvm_rcp_approx_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rcp_approx_ftz_d : NVPTXBuiltin<"double(double)">; + +// Sqrt + +def __nvvm_sqrt_rn_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_rn_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_rz_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_rz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_rm_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_rm_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_rp_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_rp_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_approx_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_sqrt_approx_f : NVPTXBuiltin<"float(float)">; + +def __nvvm_sqrt_rn_d : NVPTXBuiltin<"double(double)">; +def __nvvm_sqrt_rz_d : NVPTXBuiltin<"double(double)">; +def __nvvm_sqrt_rm_d : NVPTXBuiltin<"double(double)">; +def __nvvm_sqrt_rp_d : NVPTXBuiltin<"double(double)">; + +// Rsqrt + +def __nvvm_rsqrt_approx_ftz_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rsqrt_approx_f : NVPTXBuiltin<"float(float)">; +def __nvvm_rsqrt_approx_d : NVPTXBuiltin<"double(double)">; + +// Add + +def __nvvm_add_rn_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_add_rn_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_add_rz_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_add_rz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_add_rm_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_add_rm_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_add_rp_ftz_f : NVPTXBuiltin<"float(float, float)">; +def __nvvm_add_rp_f : NVPTXBuiltin<"float(float, float)">; + +def __nvvm_add_rn_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_add_rz_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_add_rm_d : NVPTXBuiltin<"double(double, double)">; +def __nvvm_add_rp_d : NVPTXBuiltin<"double(double, double)">; + +// Convert + +def __nvvm_d2f_rn_ftz : NVPTXBuiltin<"float(double)">; +def __nvvm_d2f_rn : NVPTXBuiltin<"float(double)">; +def __nvvm_d2f_rz_ftz : NVPTXBuiltin<"float(double)">; +def __nvvm_d2f_rz : NVPTXBuiltin<"float(double)">; +def __nvvm_d2f_rm_ftz : NVPTXBuiltin<"float(double)">; +def __nvvm_d2f_rm : NVPTXBuiltin<"float(double)">; +def __nvvm_d2f_rp_ftz : NVPTXBuiltin<"float(double)">; +def __nvvm_d2f_rp : NVPTXBuiltin<"float(double)">; + +def __nvvm_d2i_rn : NVPTXBuiltin<"int(double)">; +def __nvvm_d2i_rz : NVPTXBuiltin<"int(double)">; +def __nvvm_d2i_rm : NVPTXBuiltin<"int(double)">; +def __nvvm_d2i_rp : NVPTXBuiltin<"int(double)">; + +def __nvvm_d2ui_rn : NVPTXBuiltin<"unsigned int(double)">; +def __nvvm_d2ui_rz : NVPTXBuiltin<"unsigned int(double)">; +def __nvvm_d2ui_rm : NVPTXBuiltin<"unsigned int(double)">; +def __nvvm_d2ui_rp : NVPTXBuiltin<"unsigned int(double)">; + +def __nvvm_i2d_rn : NVPTXBuiltin<"double(int)">; +def __nvvm_i2d_rz : NVPTXBuiltin<"double(int)">; +def __nvvm_i2d_rm : NVPTXBuiltin<"double(int)">; +def __nvvm_i2d_rp : NVPTXBuiltin<"double(int)">; + +def __nvvm_ui2d_rn : NVPTXBuiltin<"double(unsigned int)">; +def __nvvm_ui2d_rz : NVPTXBuiltin<"double(unsigned int)">; +def __nvvm_ui2d_rm : NVPTXBuiltin<"double(unsigned int)">; +def __nvvm_ui2d_rp : NVPTXBuiltin<"double(unsigned int)">; + +def __nvvm_f2i_rn_ftz : NVPTXBuiltin<"int(float)">; +def __nvvm_f2i_rn : NVPTXBuiltin<"int(float)">; +def __nvvm_f2i_rz_ftz : NVPTXBuiltin<"int(float)">; +def __nvvm_f2i_rz : NVPTXBuiltin<"int(float)">; +def __nvvm_f2i_rm_ftz : NVPTXBuiltin<"int(float)">; +def __nvvm_f2i_rm : NVPTXBuiltin<"int(float)">; +def __nvvm_f2i_rp_ftz : NVPTXBuiltin<"int(float)">; +def __nvvm_f2i_rp : NVPTXBuiltin<"int(float)">; + +def __nvvm_f2ui_rn_ftz : NVPTXBuiltin<"unsigned int(float)">; +def __nvvm_f2ui_rn : NVPTXBuiltin<"unsigned int(float)">; +def __nvvm_f2ui_rz_ftz : NVPTXBuiltin<"unsigned int(float)">; +def __nvvm_f2ui_rz : NVPTXBuiltin<"unsigned int(float)">; +def __nvvm_f2ui_rm_ftz : NVPTXBuiltin<"unsigned int(float)">; +def __nvvm_f2ui_rm : NVPTXBuiltin<"unsigned int(float)">; +def __nvvm_f2ui_rp_ftz : NVPTXBuiltin<"unsigned int(float)">; +def __nvvm_f2ui_rp : NVPTXBuiltin<"unsigned int(float)">; + +def __nvvm_i2f_rn : NVPTXBuiltin<"float(int)">; +def __nvvm_i2f_rz : NVPTXBuiltin<"float(int)">; +def __nvvm_i2f_rm : NVPTXBuiltin<"float(int)">; +def __nvvm_i2f_rp : NVPTXBuiltin<"float(int)">; + +def __nvvm_ui2f_rn : NVPTXBuiltin<"float(unsigned int)">; +def __nvvm_ui2f_rz : NVPTXBuiltin<"float(unsigned int)">; +def __nvvm_ui2f_rm : NVPTXBuiltin<"float(unsigned int)">; +def __nvvm_ui2f_rp : NVPTXBuiltin<"float(unsigned int)">; + +def __nvvm_lohi_i2d : NVPTXBuiltin<"double(int, int)">; + +def __nvvm_d2i_lo : NVPTXBuiltin<"int(double)">; +def __nvvm_d2i_hi : NVPTXBuiltin<"int(double)">; + +def __nvvm_f2ll_rn_ftz : NVPTXBuiltin<"long long int(float)">; +def __nvvm_f2ll_rn : NVPTXBuiltin<"long long int(float)">; +def __nvvm_f2ll_rz_ftz : NVPTXBuiltin<"long long int(float)">; +def __nvvm_f2ll_rz : NVPTXBuiltin<"long long int(float)">; +def __nvvm_f2ll_rm_ftz : NVPTXBuiltin<"long long int(float)">; +def __nvvm_f2ll_rm : NVPTXBuiltin<"long long int(float)">; +def __nvvm_f2ll_rp_ftz : NVPTXBuiltin<"long long int(float)">; +def __nvvm_f2ll_rp : NVPTXBuiltin<"long long int(float)">; + +def __nvvm_f2ull_rn_ftz : NVPTXBuiltin<"unsigned long long int(float)">; +def __nvvm_f2ull_rn : NVPTXBuiltin<"unsigned long long int(float)">; +def __nvvm_f2ull_rz_ftz : NVPTXBuiltin<"unsigned long long int(float)">; +def __nvvm_f2ull_rz : NVPTXBuiltin<"unsigned long long int(float)">; +def __nvvm_f2ull_rm_ftz : NVPTXBuiltin<"unsigned long long int(float)">; +def __nvvm_f2ull_rm : NVPTXBuiltin<"unsigned long long int(float)">; +def __nvvm_f2ull_rp_ftz : NVPTXBuiltin<"unsigned long long int(float)">; +def __nvvm_f2ull_rp : NVPTXBuiltin<"unsigned long long int(float)">; + +def __nvvm_d2ll_rn : NVPTXBuiltin<"long long int(double)">; +def __nvvm_d2ll_rz : NVPTXBuiltin<"long long int(double)">; +def __nvvm_d2ll_rm : NVPTXBuiltin<"long long int(double)">; +def __nvvm_d2ll_rp : NVPTXBuiltin<"long long int(double)">; + +def __nvvm_d2ull_rn : NVPTXBuiltin<"unsigned long long int(double)">; +def __nvvm_d2ull_rz : NVPTXBuiltin<"unsigned long long int(double)">; +def __nvvm_d2ull_rm : NVPTXBuiltin<"unsigned long long int(double)">; +def __nvvm_d2ull_rp : NVPTXBuiltin<"unsigned long long int(double)">; + +def __nvvm_ll2f_rn : NVPTXBuiltin<"float(long long int)">; +def __nvvm_ll2f_rz : NVPTXBuiltin<"float(long long int)">; +def __nvvm_ll2f_rm : NVPTXBuiltin<"float(long long int)">; +def __nvvm_ll2f_rp : NVPTXBuiltin<"float(long long int)">; + +def __nvvm_ull2f_rn : NVPTXBuiltin<"float(unsigned long long int)">; +def __nvvm_ull2f_rz : NVPTXBuiltin<"float(unsigned long long int)">; +def __nvvm_ull2f_rm : NVPTXBuiltin<"float(unsigned long long int)">; +def __nvvm_ull2f_rp : NVPTXBuiltin<"float(unsigned long long int)">; + +def __nvvm_ll2d_rn : NVPTXBuiltin<"double(long long int)">; +def __nvvm_ll2d_rz : NVPTXBuiltin<"double(long long int)">; +def __nvvm_ll2d_rm : NVPTXBuiltin<"double(long long int)">; +def __nvvm_ll2d_rp : NVPTXBuiltin<"double(long long int)">; + +def __nvvm_ull2d_rn : NVPTXBuiltin<"double(unsigned long long int)">; +def __nvvm_ull2d_rz : NVPTXBuiltin<"double(unsigned long long int)">; +def __nvvm_ull2d_rm : NVPTXBuiltin<"double(unsigned long long int)">; +def __nvvm_ull2d_rp : NVPTXBuiltin<"double(unsigned long long int)">; + +def __nvvm_f2h_rn_ftz : NVPTXBuiltin<"unsigned short(float)">; +def __nvvm_f2h_rn : NVPTXBuiltin<"unsigned short(float)">; + +def __nvvm_ff2bf16x2_rn : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2bf16x2_rn_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2bf16x2_rz : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2bf16x2_rz_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(float, float)", SM_80, PTX70>; + +def __nvvm_ff2f16x2_rn : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2f16x2_rn_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2f16x2_rz : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX70>; +def __nvvm_ff2f16x2_rz_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(float, float)", SM_80, PTX70>; + +def __nvvm_f2bf16_rn : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; +def __nvvm_f2bf16_rn_relu : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; +def __nvvm_f2bf16_rz : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; +def __nvvm_f2bf16_rz_relu : NVPTXBuiltinSMAndPTX<"__bf16(float)", SM_80, PTX70>; + +def __nvvm_f2tf32_rna : NVPTXBuiltinSMAndPTX<"int32_t(float)", SM_80, PTX70>; + +def __nvvm_ff_to_e4m3x2_rn : NVPTXBuiltinSMAndPTX<"short(float, float)", SM_89, PTX81>; +def __nvvm_ff_to_e4m3x2_rn_relu : NVPTXBuiltinSMAndPTX<"short(float, float)", SM_89, PTX81>; +def __nvvm_ff_to_e5m2x2_rn : NVPTXBuiltinSMAndPTX<"short(float, float)", SM_89, PTX81>; +def __nvvm_ff_to_e5m2x2_rn_relu : NVPTXBuiltinSMAndPTX<"short(float, float)", SM_89, PTX81>; + +def __nvvm_f16x2_to_e4m3x2_rn : NVPTXBuiltinSMAndPTX<"short(_Vector<2, __fp16>)", SM_89, PTX81>; +def __nvvm_f16x2_to_e4m3x2_rn_relu : NVPTXBuiltinSMAndPTX<"short(_Vector<2, __fp16>)", SM_89, PTX81>; +def __nvvm_f16x2_to_e5m2x2_rn : NVPTXBuiltinSMAndPTX<"short(_Vector<2, __fp16>)", SM_89, PTX81>; +def __nvvm_f16x2_to_e5m2x2_rn_relu : NVPTXBuiltinSMAndPTX<"short(_Vector<2, __fp16>)", SM_89, PTX81>; + +def __nvvm_e4m3x2_to_f16x2_rn : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(short)", SM_89, PTX81>; +def __nvvm_e4m3x2_to_f16x2_rn_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(short)", SM_89, PTX81>; +def __nvvm_e5m2x2_to_f16x2_rn : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(short)", SM_89, PTX81>; +def __nvvm_e5m2x2_to_f16x2_rn_relu : NVPTXBuiltinSMAndPTX<"_Vector<2, __fp16>(short)", SM_89, PTX81>; + +// FNS +let Attributes = [NoThrow] in { + def __nvvm_fns : NVPTXBuiltinPTX<"unsigned int(unsigned int, unsigned int, int)", PTX60>; +} + +// Sync + +def __syncthreads : NVPTXBuiltin<"void()">; +def __nvvm_bar0_popc : NVPTXBuiltin<"int(int)">; +def __nvvm_bar0_and : NVPTXBuiltin<"int(int)">; +def __nvvm_bar0_or : NVPTXBuiltin<"int(int)">; +let Attributes = [NoThrow] in { + def __nvvm_bar_sync : NVPTXBuiltin<"void(int)">; + def __nvvm_bar_warp_sync : NVPTXBuiltinPTX<"void(unsigned int)", PTX60>; + def __nvvm_barrier_sync : NVPTXBuiltinPTX<"void(unsigned int)", PTX60>; + def __nvvm_barrier_sync_cnt : NVPTXBuiltinPTX<"void(unsigned int, unsigned int)", PTX60>; + + def __nvvm_barrier_cluster_arrive : NVPTXBuiltinSMAndPTX<"void()", SM_90, PTX78>; + def __nvvm_barrier_cluster_arrive_relaxed : NVPTXBuiltinSMAndPTX<"void()", SM_90, PTX80>; + def __nvvm_barrier_cluster_wait : NVPTXBuiltinSMAndPTX<"void()", SM_90, PTX78>; + def __nvvm_fence_sc_cluster : NVPTXBuiltinSMAndPTX<"void()", SM_90, PTX78>; +} + +// Shuffle + +def __nvvm_shfl_down_i32 : NVPTXBuiltin<"int(int, int, int)">; +def __nvvm_shfl_down_f32 : NVPTXBuiltin<"float(float, int, int)">; +def __nvvm_shfl_up_i32 : NVPTXBuiltin<"int(int, int, int)">; +def __nvvm_shfl_up_f32 : NVPTXBuiltin<"float(float, int, int)">; +def __nvvm_shfl_bfly_i32 : NVPTXBuiltin<"int(int, int, int)">; +def __nvvm_shfl_bfly_f32 : NVPTXBuiltin<"float(float, int, int)">; +def __nvvm_shfl_idx_i32 : NVPTXBuiltin<"int(int, int, int)">; +def __nvvm_shfl_idx_f32 : NVPTXBuiltin<"float(float, int, int)">; + +def __nvvm_shfl_sync_down_i32 : NVPTXBuiltinPTX<"int(unsigned int, int, int, int)", PTX60>; +def __nvvm_shfl_sync_down_f32 : NVPTXBuiltinPTX<"float(unsigned int, float, int, int)", PTX60>; +def __nvvm_shfl_sync_up_i32 : NVPTXBuiltinPTX<"int(unsigned int, int, int, int)", PTX60>; +def __nvvm_shfl_sync_up_f32 : NVPTXBuiltinPTX<"float(unsigned int, float, int, int)", PTX60>; +def __nvvm_shfl_sync_bfly_i32 : NVPTXBuiltinPTX<"int(unsigned int, int, int, int)", PTX60>; +def __nvvm_shfl_sync_bfly_f32 : NVPTXBuiltinPTX<"float(unsigned int, float, int, int)", PTX60>; +def __nvvm_shfl_sync_idx_i32 : NVPTXBuiltinPTX<"int(unsigned int, int, int, int)", PTX60>; +def __nvvm_shfl_sync_idx_f32 : NVPTXBuiltinPTX<"float(unsigned int, float, int, int)", PTX60>; + +// Vote +def __nvvm_vote_all : NVPTXBuiltin<"bool(bool)">; +def __nvvm_vote_any : NVPTXBuiltin<"bool(bool)">; +def __nvvm_vote_uni : NVPTXBuiltin<"bool(bool)">; +def __nvvm_vote_ballot : NVPTXBuiltin<"unsigned int(bool)">; + +def __nvvm_vote_all_sync : NVPTXBuiltinPTX<"bool(unsigned int, bool)", PTX60>; +def __nvvm_vote_any_sync : NVPTXBuiltinPTX<"bool(unsigned int, bool)", PTX60>; +def __nvvm_vote_uni_sync : NVPTXBuiltinPTX<"bool(unsigned int, bool)", PTX60>; +def __nvvm_vote_ballot_sync : NVPTXBuiltinPTX<"unsigned int(unsigned int, bool)", PTX60>; + +// Mask +let Attributes = [NoThrow] in { + def __nvvm_activemask : NVPTXBuiltinPTX<"unsigned int()", PTX62>; +} + +// Match +def __nvvm_match_any_sync_i32 : NVPTXBuiltinSMAndPTX<"unsigned int(unsigned int, unsigned int)", SM_70, PTX60>; +def __nvvm_match_any_sync_i64 : NVPTXBuiltinSMAndPTX<"unsigned int(unsigned int, int64_t)", SM_70, PTX60>; +// These return a pair {value, predicate}, which requires custom lowering. +def __nvvm_match_all_sync_i32p : NVPTXBuiltinSMAndPTX<"unsigned int(unsigned int, unsigned int, int *)", SM_70, PTX60>; +def __nvvm_match_all_sync_i64p : NVPTXBuiltinSMAndPTX<"unsigned int(unsigned int, int64_t, int *)", SM_70, PTX60>; + +// Redux +def __nvvm_redux_sync_add : NVPTXBuiltinSMAndPTX<"int(int, int)", SM_80, PTX70>; +def __nvvm_redux_sync_min : NVPTXBuiltinSMAndPTX<"int(int, int)", SM_80, PTX70>; +def __nvvm_redux_sync_max : NVPTXBuiltinSMAndPTX<"int(int, int)", SM_80, PTX70>; +def __nvvm_redux_sync_umin : NVPTXBuiltinSMAndPTX<"unsigned int(unsigned int, int)", SM_80, PTX70>; +def __nvvm_redux_sync_umax : NVPTXBuiltinSMAndPTX<"unsigned int(unsigned int, int)", SM_80, PTX70>; +def __nvvm_redux_sync_and : NVPTXBuiltinSMAndPTX<"int(int, int)", SM_80, PTX70>; +def __nvvm_redux_sync_xor : NVPTXBuiltinSMAndPTX<"int(int, int)", SM_80, PTX70>; +def __nvvm_redux_sync_or : NVPTXBuiltinSMAndPTX<"int(int, int)", SM_80, PTX70>; + +// Membar + +def __nvvm_membar_cta : NVPTXBuiltin<"void()">; +def __nvvm_membar_gl : NVPTXBuiltin<"void()">; +def __nvvm_membar_sys : NVPTXBuiltin<"void()">; + +// mbarrier + +def __nvvm_mbarrier_init : NVPTXBuiltinSMAndPTX<"void(int64_t *, int)", SM_80, PTX70>; +def __nvvm_mbarrier_init_shared : NVPTXBuiltinSMAndPTX<"void(int64_t address_space<3> *, int)", SM_80, PTX70>; + +def __nvvm_mbarrier_inval : NVPTXBuiltinSMAndPTX<"void(int64_t *)", SM_80, PTX70>; +def __nvvm_mbarrier_inval_shared : NVPTXBuiltinSMAndPTX<"void(int64_t address_space<3> *)", SM_80, PTX70>; + +def __nvvm_mbarrier_arrive : NVPTXBuiltinSMAndPTX<"int64_t(int64_t *)", SM_80, PTX70>; +def __nvvm_mbarrier_arrive_shared : NVPTXBuiltinSMAndPTX<"int64_t(int64_t address_space<3> *)", SM_80, PTX70>; +def __nvvm_mbarrier_arrive_noComplete : NVPTXBuiltinSMAndPTX<"int64_t(int64_t *, int)", SM_80, PTX70>; +def __nvvm_mbarrier_arrive_noComplete_shared : NVPTXBuiltinSMAndPTX<"int64_t(int64_t address_space<3> *, int)", SM_80, PTX70>; + +def __nvvm_mbarrier_arrive_drop : NVPTXBuiltinSMAndPTX<"int64_t(int64_t *)", SM_80, PTX70>; +def __nvvm_mbarrier_arrive_drop_shared : NVPTXBuiltinSMAndPTX<"int64_t(int64_t address_space<3> *)", SM_80, PTX70>; +def __nvvm_mbarrier_arrive_drop_noComplete : NVPTXBuiltinSMAndPTX<"int64_t(int64_t *, int)", SM_80, PTX70>; +def __nvvm_mbarrier_arrive_drop_noComplete_shared : NVPTXBuiltinSMAndPTX<"int64_t(int64_t address_space<3> *, int)", SM_80, PTX70>; + +def __nvvm_mbarrier_test_wait : NVPTXBuiltinSMAndPTX<"bool(int64_t *, int64_t)", SM_80, PTX70>; +def __nvvm_mbarrier_test_wait_shared : NVPTXBuiltinSMAndPTX<"bool(int64_t address_space<3> *, int64_t)", SM_80, PTX70>; + +def __nvvm_mbarrier_pending_count : NVPTXBuiltinSMAndPTX<"int(int64_t)", SM_80, PTX70>; + +// Memcpy, Memset + +def __nvvm_memcpy : NVPTXBuiltin<"void(unsigned char *, unsigned char *, size_t, int)">; +def __nvvm_memset : NVPTXBuiltin<"void(unsigned char *, unsigned char, size_t, int)">; + +// Image + +def __builtin_ptx_read_image2Dfi_ : NVPTXBuiltin<"_Vector<4, float>(int, int, int, int)">; +def __builtin_ptx_read_image2Dff_ : NVPTXBuiltin<"_Vector<4, float>(int, int, float, float)">; +def __builtin_ptx_read_image2Dii_ : NVPTXBuiltin<"_Vector<4, int>(int, int, int, int)">; +def __builtin_ptx_read_image2Dif_ : NVPTXBuiltin<"_Vector<4, int>(int, int, float, float)">; + +def __builtin_ptx_read_image3Dfi_ : NVPTXBuiltin<"_Vector<4, float>(int, int, int, int, int, int)">; +def __builtin_ptx_read_image3Dff_ : NVPTXBuiltin<"_Vector<4, float>(int, int, float, float, float, float)">; +def __builtin_ptx_read_image3Dii_ : NVPTXBuiltin<"_Vector<4, int>(int, int, int, int, int, int)">; +def __builtin_ptx_read_image3Dif_ : NVPTXBuiltin<"_Vector<4, int>(int, int, float, float, float, float)">; + +def __builtin_ptx_write_image2Df_ : NVPTXBuiltin<"void(int, int, int, float, float, float, float)">; +def __builtin_ptx_write_image2Di_ : NVPTXBuiltin<"void(int, int, int, int, int, int, int)">; +def __builtin_ptx_write_image2Dui_ : NVPTXBuiltin<"void(int, int, int, unsigned int, unsigned int, unsigned int, unsigned int)">; +def __builtin_ptx_get_image_depthi_ : NVPTXBuiltin<"int(int)">; +def __builtin_ptx_get_image_heighti_ : NVPTXBuiltin<"int(int)">; +def __builtin_ptx_get_image_widthi_ : NVPTXBuiltin<"int(int)">; +def __builtin_ptx_get_image_channel_data_typei_ : NVPTXBuiltin<"int(int)">; +def __builtin_ptx_get_image_channel_orderi_ : NVPTXBuiltin<"int(int)">; + +// Atomic +// +// We need the atom intrinsics because +// - they are used in converging analysis +// - they are used in address space analysis and optimization +// So it does not hurt to expose them as builtins. +// +let Attributes = [NoThrow] in { + def __nvvm_atom_add_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_cta_add_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_sys_add_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_add_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_cta_add_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_sys_add_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_add_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + def __nvvm_atom_cta_add_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_sys_add_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_add_gen_f : NVPTXBuiltin<"float(float volatile *, float)">; + def __nvvm_atom_cta_add_gen_f : NVPTXBuiltinSM<"float(float volatile *, float)", SM_60>; + def __nvvm_atom_sys_add_gen_f : NVPTXBuiltinSM<"float(float volatile *, float)", SM_60>; + def __nvvm_atom_add_gen_d : NVPTXBuiltinSM<"double(double volatile *, double)", SM_60>; + def __nvvm_atom_cta_add_gen_d : NVPTXBuiltinSM<"double(double volatile *, double)", SM_60>; + def __nvvm_atom_sys_add_gen_d : NVPTXBuiltinSM<"double(double volatile *, double)", SM_60>; + + def __nvvm_atom_sub_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_sub_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_sub_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + + def __nvvm_atom_xchg_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_cta_xchg_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_sys_xchg_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_xchg_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_cta_xchg_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_sys_xchg_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_xchg_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + def __nvvm_atom_cta_xchg_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_sys_xchg_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + + def __nvvm_atom_max_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_cta_max_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_sys_max_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_max_gen_ui : NVPTXBuiltin<"unsigned int(unsigned int volatile *, unsigned int)">; + def __nvvm_atom_cta_max_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + def __nvvm_atom_sys_max_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + def __nvvm_atom_max_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_cta_max_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_sys_max_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_max_gen_ul : NVPTXBuiltin<"unsigned long int(unsigned long int volatile *, unsigned long int)">; + def __nvvm_atom_cta_max_gen_ul : NVPTXBuiltinSM<"unsigned long int(unsigned long int volatile *, unsigned long int)", SM_60>; + def __nvvm_atom_sys_max_gen_ul : NVPTXBuiltinSM<"unsigned long int(unsigned long int volatile *, unsigned long int)", SM_60>; + def __nvvm_atom_max_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + def __nvvm_atom_cta_max_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_sys_max_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_max_gen_ull : NVPTXBuiltin<"unsigned long long int(unsigned long long int volatile *, unsigned long long int)">; + def __nvvm_atom_cta_max_gen_ull : NVPTXBuiltinSM<"unsigned long long int(unsigned long long int volatile *, unsigned long long int)", SM_60>; + def __nvvm_atom_sys_max_gen_ull : NVPTXBuiltinSM<"unsigned long long int(unsigned long long int volatile *, unsigned long long int)", SM_60>; + + def __nvvm_atom_min_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_cta_min_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_sys_min_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_min_gen_ui : NVPTXBuiltin<"unsigned int(unsigned int volatile *, unsigned int)">; + def __nvvm_atom_cta_min_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + def __nvvm_atom_sys_min_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + def __nvvm_atom_min_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_cta_min_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_sys_min_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_min_gen_ul : NVPTXBuiltin<"unsigned long int(unsigned long int volatile *, unsigned long int)">; + def __nvvm_atom_cta_min_gen_ul : NVPTXBuiltinSM<"unsigned long int(unsigned long int volatile *, unsigned long int)", SM_60>; + def __nvvm_atom_sys_min_gen_ul : NVPTXBuiltinSM<"unsigned long int(unsigned long int volatile *, unsigned long int)", SM_60>; + def __nvvm_atom_min_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + def __nvvm_atom_cta_min_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_sys_min_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_min_gen_ull : NVPTXBuiltin<"unsigned long long int(unsigned long long int volatile *, unsigned long long int)">; + def __nvvm_atom_cta_min_gen_ull : NVPTXBuiltinSM<"unsigned long long int(unsigned long long int volatile *, unsigned long long int)", SM_60>; + def __nvvm_atom_sys_min_gen_ull : NVPTXBuiltinSM<"unsigned long long int(unsigned long long int volatile *, unsigned long long int)", SM_60>; + + def __nvvm_atom_inc_gen_ui : NVPTXBuiltin<"unsigned int(unsigned int volatile *, unsigned int)">; + def __nvvm_atom_cta_inc_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + def __nvvm_atom_sys_inc_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + def __nvvm_atom_dec_gen_ui : NVPTXBuiltin<"unsigned int(unsigned int volatile *, unsigned int)">; + def __nvvm_atom_cta_dec_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + def __nvvm_atom_sys_dec_gen_ui : NVPTXBuiltinSM<"unsigned int(unsigned int volatile *, unsigned int)", SM_60>; + + def __nvvm_atom_and_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_cta_and_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_sys_and_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_and_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_cta_and_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_sys_and_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_and_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + def __nvvm_atom_cta_and_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_sys_and_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + + def __nvvm_atom_or_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_cta_or_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_sys_or_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_or_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_cta_or_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_sys_or_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_or_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + def __nvvm_atom_cta_or_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_sys_or_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + + def __nvvm_atom_xor_gen_i : NVPTXBuiltin<"int(int volatile *, int)">; + def __nvvm_atom_cta_xor_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_sys_xor_gen_i : NVPTXBuiltinSM<"int(int volatile *, int)", SM_60>; + def __nvvm_atom_xor_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int)">; + def __nvvm_atom_cta_xor_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_sys_xor_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int)", SM_60>; + def __nvvm_atom_xor_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int)">; + def __nvvm_atom_cta_xor_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + def __nvvm_atom_sys_xor_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int)", SM_60>; + + def __nvvm_atom_cas_gen_us : NVPTXBuiltinSM<"unsigned short(unsigned short volatile *, unsigned short, unsigned short)", SM_70>; + def __nvvm_atom_cta_cas_gen_us : NVPTXBuiltinSM<"unsigned short(unsigned short volatile *, unsigned short, unsigned short)", SM_70>; + def __nvvm_atom_sys_cas_gen_us : NVPTXBuiltinSM<"unsigned short(unsigned short volatile *, unsigned short, unsigned short)", SM_70>; + def __nvvm_atom_cas_gen_i : NVPTXBuiltin<"int(int volatile *, int, int)">; + def __nvvm_atom_cta_cas_gen_i : NVPTXBuiltinSM<"int(int volatile *, int, int)", SM_60>; + def __nvvm_atom_sys_cas_gen_i : NVPTXBuiltinSM<"int(int volatile *, int, int)", SM_60>; + def __nvvm_atom_cas_gen_l : NVPTXBuiltin<"long int(long int volatile *, long int, long int)">; + def __nvvm_atom_cta_cas_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int, long int)", SM_60>; + def __nvvm_atom_sys_cas_gen_l : NVPTXBuiltinSM<"long int(long int volatile *, long int, long int)", SM_60>; + def __nvvm_atom_cas_gen_ll : NVPTXBuiltin<"long long int(long long int volatile *, long long int, long long int)">; + def __nvvm_atom_cta_cas_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int, long long int)", SM_60>; + def __nvvm_atom_sys_cas_gen_ll : NVPTXBuiltinSM<"long long int(long long int volatile *, long long int, long long int)", SM_60>; +} + +// Compiler Error Warn +let Attributes = [NoThrow] in { + def __nvvm_compiler_error : NVPTXBuiltin<"void(char const address_space<4> *)">; + def __nvvm_compiler_warn : NVPTXBuiltin<"void(char const address_space<4> *)">; +} + +def __nvvm_ldu_c : NVPTXBuiltin<"char(char const *)">; +def __nvvm_ldu_sc : NVPTXBuiltin<"signed char(signed char const *)">; +def __nvvm_ldu_s : NVPTXBuiltin<"short(short const *)">; +def __nvvm_ldu_i : NVPTXBuiltin<"int(int const *)">; +def __nvvm_ldu_l : NVPTXBuiltin<"long int(long int const *)">; +def __nvvm_ldu_ll : NVPTXBuiltin<"long long int(long long int const *)">; + +def __nvvm_ldu_uc : NVPTXBuiltin<"unsigned char(unsigned char const *)">; +def __nvvm_ldu_us : NVPTXBuiltin<"unsigned short(unsigned short const *)">; +def __nvvm_ldu_ui : NVPTXBuiltin<"unsigned int(unsigned int const *)">; +def __nvvm_ldu_ul : NVPTXBuiltin<"unsigned long int(unsigned long int const *)">; +def __nvvm_ldu_ull : NVPTXBuiltin<"unsigned long long int(unsigned long long int const *)">; + +def __nvvm_ldu_h : NVPTXBuiltin<"__fp16(__fp16 const *)">; +def __nvvm_ldu_f : NVPTXBuiltin<"float(float const *)">; +def __nvvm_ldu_d : NVPTXBuiltin<"double(double const *)">; + +def __nvvm_ldu_c2 : NVPTXBuiltin<"_ExtVector<2, char>(_ExtVector<2, char const *>)">; +def __nvvm_ldu_sc2 : NVPTXBuiltin<"_ExtVector<2, signed char>(_ExtVector<2, signed char const *>)">; +def __nvvm_ldu_c4 : NVPTXBuiltin<"_ExtVector<4, char>(_ExtVector<4, char const *>)">; +def __nvvm_ldu_sc4 : NVPTXBuiltin<"_ExtVector<4, signed char>(_ExtVector<4, signed char const *>)">; +def __nvvm_ldu_s2 : NVPTXBuiltin<"_ExtVector<2, short>(_ExtVector<2, short const *>)">; +def __nvvm_ldu_s4 : NVPTXBuiltin<"_ExtVector<4, short>(_ExtVector<4, short const *>)">; +def __nvvm_ldu_i2 : NVPTXBuiltin<"_ExtVector<2, int>(_ExtVector<2, int const *>)">; +def __nvvm_ldu_i4 : NVPTXBuiltin<"_ExtVector<4, int>(_ExtVector<4, int const *>)">; +def __nvvm_ldu_l2 : NVPTXBuiltin<"_ExtVector<2, long int>(_ExtVector<2, long int const *>)">; +def __nvvm_ldu_ll2 : NVPTXBuiltin<"_ExtVector<2, long long int>(_ExtVector<2, long long int const *>)">; + +def __nvvm_ldu_uc2 : NVPTXBuiltin<"_ExtVector<2, unsigned char>(_ExtVector<2, unsigned char const *>)">; +def __nvvm_ldu_uc4 : NVPTXBuiltin<"_ExtVector<4, unsigned char>(_ExtVector<4, unsigned char const *>)">; +def __nvvm_ldu_us2 : NVPTXBuiltin<"_ExtVector<2, unsigned short>(_ExtVector<2, unsigned short const *>)">; +def __nvvm_ldu_us4 : NVPTXBuiltin<"_ExtVector<4, unsigned short>(_ExtVector<4, unsigned short const *>)">; +def __nvvm_ldu_ui2 : NVPTXBuiltin<"_ExtVector<2, unsigned int>(_ExtVector<2, unsigned int const *>)">; +def __nvvm_ldu_ui4 : NVPTXBuiltin<"_ExtVector<4, unsigned int>(_ExtVector<4, unsigned int const *>)">; +def __nvvm_ldu_ul2 : NVPTXBuiltin<"_ExtVector<2, unsigned long int>(_ExtVector<2, unsigned long int const *>)">; +def __nvvm_ldu_ull2 : NVPTXBuiltin<"_ExtVector<2, unsigned long long int>(_ExtVector<2, unsigned long long int const *>)">; + +def __nvvm_ldu_h2 : NVPTXBuiltin<"_ExtVector<2, __fp16>(_ExtVector<2, __fp16 const *>)">; +def __nvvm_ldu_f2 : NVPTXBuiltin<"_ExtVector<2, float>(_ExtVector<2, float const *>)">; +def __nvvm_ldu_f4 : NVPTXBuiltin<"_ExtVector<4, float>(_ExtVector<4, float const *>)">; +def __nvvm_ldu_d2 : NVPTXBuiltin<"_ExtVector<2, double>(_ExtVector<2, double const *>)">; + +def __nvvm_ldg_c : NVPTXBuiltin<"char(char const *)">; +def __nvvm_ldg_sc : NVPTXBuiltin<"signed char(signed char const *)">; +def __nvvm_ldg_s : NVPTXBuiltin<"short(short const *)">; +def __nvvm_ldg_i : NVPTXBuiltin<"int(int const *)">; +def __nvvm_ldg_l : NVPTXBuiltin<"long int(long int const *)">; +def __nvvm_ldg_ll : NVPTXBuiltin<"long long int(long long int const *)">; + +def __nvvm_ldg_uc : NVPTXBuiltin<"unsigned char(unsigned char const *)">; +def __nvvm_ldg_us : NVPTXBuiltin<"unsigned short(unsigned short const *)">; +def __nvvm_ldg_ui : NVPTXBuiltin<"unsigned int(unsigned int const *)">; +def __nvvm_ldg_ul : NVPTXBuiltin<"unsigned long int(unsigned long int const *)">; +def __nvvm_ldg_ull : NVPTXBuiltin<"unsigned long long int(unsigned long long int const *)">; + +def __nvvm_ldg_h : NVPTXBuiltin<"__fp16(__fp16 const *)">; +def __nvvm_ldg_f : NVPTXBuiltin<"float(float const *)">; +def __nvvm_ldg_d : NVPTXBuiltin<"double(double const *)">; + +def __nvvm_ldg_c2 : NVPTXBuiltin<"_ExtVector<2, char>(_ExtVector<2, char const *>)">; +def __nvvm_ldg_sc2 : NVPTXBuiltin<"_ExtVector<2, signed char>(_ExtVector<2, signed char const *>)">; +def __nvvm_ldg_c4 : NVPTXBuiltin<"_ExtVector<4, char>(_ExtVector<4, char const *>)">; +def __nvvm_ldg_sc4 : NVPTXBuiltin<"_ExtVector<4, signed char>(_ExtVector<4, signed char const *>)">; +def __nvvm_ldg_s2 : NVPTXBuiltin<"_ExtVector<2, short>(_ExtVector<2, short const *>)">; +def __nvvm_ldg_s4 : NVPTXBuiltin<"_ExtVector<4, short>(_ExtVector<4, short const *>)">; +def __nvvm_ldg_i2 : NVPTXBuiltin<"_ExtVector<2, int>(_ExtVector<2, int const *>)">; +def __nvvm_ldg_i4 : NVPTXBuiltin<"_ExtVector<4, int>(_ExtVector<4, int const *>)">; +def __nvvm_ldg_l2 : NVPTXBuiltin<"_ExtVector<2, long int>(_ExtVector<2, long int const *>)">; +def __nvvm_ldg_ll2 : NVPTXBuiltin<"_ExtVector<2, long long int>(_ExtVector<2, long long int const *>)">; + +def __nvvm_ldg_uc2 : NVPTXBuiltin<"_ExtVector<2, unsigned char>(_ExtVector<2, unsigned char const *>)">; +def __nvvm_ldg_uc4 : NVPTXBuiltin<"_ExtVector<4, unsigned char>(_ExtVector<4, unsigned char const *>)">; +def __nvvm_ldg_us2 : NVPTXBuiltin<"_ExtVector<2, unsigned short>(_ExtVector<2, unsigned short const *>)">; +def __nvvm_ldg_us4 : NVPTXBuiltin<"_ExtVector<4, unsigned short>(_ExtVector<4, unsigned short const *>)">; +def __nvvm_ldg_ui2 : NVPTXBuiltin<"_ExtVector<2, unsigned int>(_ExtVector<2, unsigned int const *>)">; +def __nvvm_ldg_ui4 : NVPTXBuiltin<"_ExtVector<4, unsigned int>(_ExtVector<4, unsigned int const *>)">; +def __nvvm_ldg_ul2 : NVPTXBuiltin<"_ExtVector<2, unsigned long int>(_ExtVector<2, unsigned long int const *>)">; +def __nvvm_ldg_ull2 : NVPTXBuiltin<"_ExtVector<2, unsigned long long int>(_ExtVector<2, unsigned long long int const *>)">; + +def __nvvm_ldg_h2 : NVPTXBuiltin<"_ExtVector<2, __fp16>(_ExtVector<2, __fp16 const *>)">; +def __nvvm_ldg_f2 : NVPTXBuiltin<"_ExtVector<2, float>(_ExtVector<2, float const *>)">; +def __nvvm_ldg_f4 : NVPTXBuiltin<"_ExtVector<4, float>(_ExtVector<4, float const *>)">; +def __nvvm_ldg_d2 : NVPTXBuiltin<"_ExtVector<2, double>(_ExtVector<2, double const *>)">; + +// Address space predicates. +let Attributes = [NoThrow, Const] in { + def __nvvm_isspacep_const : NVPTXBuiltin<"bool(void const *)">; + def __nvvm_isspacep_global : NVPTXBuiltin<"bool(void const *)">; + def __nvvm_isspacep_local : NVPTXBuiltin<"bool(void const *)">; + def __nvvm_isspacep_shared : NVPTXBuiltin<"bool(void const *)">; + def __nvvm_isspacep_shared_cluster : NVPTXBuiltinSMAndPTX<"bool(void const *)", SM_90, PTX78>; +} + +// Builtins to support WMMA instructions on sm_70 +def __hmma_m16n16k16_ld_a : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_ld_b : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_ld_c_f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_ld_c_f32 : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_st_c_f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_st_c_f32 : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_70, PTX60>; + +def __hmma_m32n8k16_ld_a : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_ld_b : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_ld_c_f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_ld_c_f32 : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_st_c_f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_st_c_f32 : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_70, PTX61>; + +def __hmma_m8n32k16_ld_a : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_ld_b : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_ld_c_f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_ld_c_f32 : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_st_c_f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_st_c_f32 : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_70, PTX61>; + +def __hmma_m16n16k16_mma_f16f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_mma_f32f16 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_mma_f32f32 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_70, PTX60>; +def __hmma_m16n16k16_mma_f16f32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_70, PTX60>; + +def __hmma_m32n8k16_mma_f16f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_mma_f32f16 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_mma_f32f32 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_70, PTX61>; +def __hmma_m32n8k16_mma_f16f32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_70, PTX61>; + +def __hmma_m8n32k16_mma_f16f16 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_mma_f32f16 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_mma_f32f32 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_70, PTX61>; +def __hmma_m8n32k16_mma_f16f32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_70, PTX61>; + +// Builtins to support integer and sub-integer WMMA instructions on sm_72/sm_75 +def __bmma_m8n8k128_ld_a_b1 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __bmma_m8n8k128_ld_b_b1 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __bmma_m8n8k128_ld_c : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __bmma_m8n8k128_mma_and_popc_b1 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int)", SM_80, PTX71>; +def __bmma_m8n8k128_mma_xor_popc_b1 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int)", SM_75, PTX63>; +def __bmma_m8n8k128_st_c_i32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __imma_m16n16k16_ld_a_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m16n16k16_ld_a_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m16n16k16_ld_b_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m16n16k16_ld_b_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m16n16k16_ld_c : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m16n16k16_mma_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_72, PTX63>; +def __imma_m16n16k16_mma_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_72, PTX63>; +def __imma_m16n16k16_st_c_i32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_ld_a_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_ld_a_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_ld_b_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_ld_b_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_ld_c : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_mma_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_mma_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_72, PTX63>; +def __imma_m32n8k16_st_c_i32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_ld_a_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_ld_a_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_ld_b_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_ld_b_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_ld_c : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_mma_s8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_mma_u8 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_72, PTX63>; +def __imma_m8n32k16_st_c_i32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_72, PTX63>; +def __imma_m8n8k32_ld_a_s4 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __imma_m8n8k32_ld_a_u4 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __imma_m8n8k32_ld_b_s4 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __imma_m8n8k32_ld_b_u4 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __imma_m8n8k32_ld_c : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; +def __imma_m8n8k32_mma_s4 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_75, PTX63>; +def __imma_m8n8k32_mma_u4 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, int const *, int const *, _Constant int, _Constant int)", SM_75, PTX63>; +def __imma_m8n8k32_st_c_i32 : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_75, PTX63>; + +// Builtins to support double and alternate float WMMA instructions on sm_80 +def __dmma_m8n8k4_ld_a : NVPTXBuiltinSMAndPTX<"void(double *, double const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __dmma_m8n8k4_ld_b : NVPTXBuiltinSMAndPTX<"void(double *, double const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __dmma_m8n8k4_ld_c : NVPTXBuiltinSMAndPTX<"void(double *, double const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __dmma_m8n8k4_st_c_f64 : NVPTXBuiltinSMAndPTX<"void(double *, double const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __dmma_m8n8k4_mma_f64 : NVPTXBuiltinSMAndPTX<"void(double *, double const *, double const *, double const *, _Constant int, _Constant int)", SM_80, PTX70>; + +def __mma_bf16_m16n16k16_ld_a : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m16n16k16_ld_b : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m16n16k16_mma_f32 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m8n32k16_ld_a : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m8n32k16_ld_b : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m8n32k16_mma_f32 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m32n8k16_ld_a : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m32n8k16_ld_b : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_bf16_m32n8k16_mma_f32 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_80, PTX70>; + +def __mma_tf32_m16n16k8_ld_a : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_tf32_m16n16k8_ld_b : NVPTXBuiltinSMAndPTX<"void(int *, int const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_tf32_m16n16k8_ld_c : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_m16n16k8_st_c_f32 : NVPTXBuiltinSMAndPTX<"void(float *, float const *, unsigned int, _Constant int)", SM_80, PTX70>; +def __mma_tf32_m16n16k8_mma_f32 : NVPTXBuiltinSMAndPTX<"void(float *, int const *, int const *, float const *, _Constant int, _Constant int)", SM_80, PTX70>; + +// Async Copy +def __nvvm_cp_async_mbarrier_arrive : NVPTXBuiltinSMAndPTX<"void(int64_t *)", SM_80, PTX70>; +def __nvvm_cp_async_mbarrier_arrive_shared : NVPTXBuiltinSMAndPTX<"void(int64_t address_space<3> *)", SM_80, PTX70>; +def __nvvm_cp_async_mbarrier_arrive_noinc : NVPTXBuiltinSMAndPTX<"void(int64_t *)", SM_80, PTX70>; +def __nvvm_cp_async_mbarrier_arrive_noinc_shared : NVPTXBuiltinSMAndPTX<"void(int64_t address_space<3> *)", SM_80, PTX70>; + +def __nvvm_cp_async_ca_shared_global_4 : NVPTXBuiltinSMAndPTX<"void(void address_space<3> *, void const address_space<1> *, ...)", SM_80, PTX70>; +def __nvvm_cp_async_ca_shared_global_8 : NVPTXBuiltinSMAndPTX<"void(void address_space<3> *, void const address_space<1> *, ...)", SM_80, PTX70>; +def __nvvm_cp_async_ca_shared_global_16 : NVPTXBuiltinSMAndPTX<"void(void address_space<3> *, void const address_space<1> *, ...)", SM_80, PTX70>; +def __nvvm_cp_async_cg_shared_global_16 : NVPTXBuiltinSMAndPTX<"void(void address_space<3> *, void const address_space<1> *, ...)", SM_80, PTX70>; + +def __nvvm_cp_async_commit_group : NVPTXBuiltinSMAndPTX<"void()", SM_80, PTX70>; +def __nvvm_cp_async_wait_group : NVPTXBuiltinSMAndPTX<"void(_Constant int)", SM_80, PTX70>; +def __nvvm_cp_async_wait_all : NVPTXBuiltinSMAndPTX<"void()", SM_80, PTX70>; + + +// bf16, bf16x2 abs, neg +def __nvvm_abs_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16)", SM_80, PTX70>; +def __nvvm_abs_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>)", SM_80, PTX70>; +def __nvvm_neg_bf16 : NVPTXBuiltinSMAndPTX<"__bf16(__bf16)", SM_80, PTX70>; +def __nvvm_neg_bf16x2 : NVPTXBuiltinSMAndPTX<"_Vector<2, __bf16>(_Vector<2, __bf16>)", SM_80, PTX70>; + +def __nvvm_mapa : NVPTXBuiltinSMAndPTX<"void *(void *, int)", SM_90, PTX78>; +def __nvvm_mapa_shared_cluster : NVPTXBuiltinSMAndPTX<"void address_space<3> *(void address_space<3> *, int)", SM_90, PTX78>; +def __nvvm_getctarank : NVPTXBuiltinSMAndPTX<"int(void *)", SM_90, PTX78>; +def __nvvm_getctarank_shared_cluster : NVPTXBuiltinSMAndPTX<"int(void address_space<3> *)", SM_90, PTX78>; diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 161df386f00f0..bb7d54bbb793e 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -1138,5 +1138,6 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true, // FIXME: Obviously incomplete. #undef BUILTIN +#undef TARGET_BUILTIN #undef CUSTOM_BUILTIN #undef UNALIASED_CUSTOM_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsRISCVVector.def b/clang/include/clang/Basic/BuiltinsRISCVVector.def deleted file mode 100644 index 6dfa87a1a1d31..0000000000000 --- a/clang/include/clang/Basic/BuiltinsRISCVVector.def +++ /dev/null @@ -1,22 +0,0 @@ -//==- BuiltinsRISCVVector.def - RISC-V Vector Builtin Database ---*- C++ -*-==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the RISC-V-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -#if defined(BUILTIN) && !defined(TARGET_BUILTIN) -# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) -#endif - -#include "clang/Basic/riscv_vector_builtins.inc" -#include "clang/Basic/riscv_sifive_vector_builtins.inc" - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsSME.def b/clang/include/clang/Basic/BuiltinsSME.def deleted file mode 100644 index 180ee20295ccd..0000000000000 --- a/clang/include/clang/Basic/BuiltinsSME.def +++ /dev/null @@ -1,21 +0,0 @@ -//===--- BuiltinsSME.def - SME Builtin function database --------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the SME-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -// The format of this database matches clang/Basic/Builtins.def. - -#define GET_SME_BUILTINS -#include "clang/Basic/arm_sme_builtins.inc" -#undef GET_SME_BUILTINS - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsSVE.def b/clang/include/clang/Basic/BuiltinsSVE.def deleted file mode 100644 index a83f1c8f82dd0..0000000000000 --- a/clang/include/clang/Basic/BuiltinsSVE.def +++ /dev/null @@ -1,22 +0,0 @@ -//===--- BuiltinsSVE.def - SVE Builtin function database --------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the SVE-specific builtin function database. Users of -// this file must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// - -// The format of this database matches clang/Basic/Builtins.def. - -#define GET_SVE_BUILTINS -#include "clang/Basic/arm_sve_builtins.inc" -#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def" -#undef GET_SVE_BUILTINS - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsX86Base.td b/clang/include/clang/Basic/BuiltinsX86Base.td index aca39c204516a..0d739ee0b0b69 100644 --- a/clang/include/clang/Basic/BuiltinsX86Base.td +++ b/clang/include/clang/Basic/BuiltinsX86Base.td @@ -12,10 +12,13 @@ include "clang/Basic/BuiltinsBase.td" +def X86Prefix : NamePrefix<"__builtin_ia32_">; + class X86Builtin : TargetBuiltin { - let Spellings = ["__builtin_ia32_" # NAME]; + let Spellings = [NAME]; let Prototype = prototype; let EnableOpenCLLong = 1; + let RequiredNamePrefix = X86Prefix; // Adds a prefix to the name. } class X86NoPrefixBuiltin : TargetBuiltin { diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 4103d2753abc5..93dbc9c8ca62f 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -72,6 +72,14 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins SOURCE BuiltinsBPF.td TARGET ClangBuiltinsBPF) +clang_tablegen(BuiltinsHexagon.inc -gen-clang-builtins + SOURCE BuiltinsHexagon.td + TARGET ClangBuiltinsHexagon) + +clang_tablegen(BuiltinsNVPTX.inc -gen-clang-builtins + SOURCE BuiltinsNVPTX.td + TARGET ClangBuiltinsNVPTX) + clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins SOURCE BuiltinsRISCV.td TARGET ClangBuiltinsRISCV) diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 1ab8c7fb4d3c3..a7f5f1abbb825 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -221,6 +221,7 @@ AFFECTING_VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option spec AFFECTING_VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified. CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic +CODEGENOPT(ContinuousProfileSync, 1, 0) ///< Enable continuous instrumentation profiling /// Choose profile instrumenation kind or no instrumentation. ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone) /// Choose profile kind for PGO use compilation. @@ -277,6 +278,7 @@ CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0) ///< Normalize integer types ///< CFI icall function signatures CODEGENOPT(SanitizeCfiCanonicalJumpTables, 1, 0) ///< Make jump table symbols canonical ///< instead of creating a local jump table. +CODEGENOPT(SanitizeKcfiArity, 1, 0) ///< Embed arity in KCFI patchable function prefix CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage ///< instrumentation. CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage @@ -319,6 +321,7 @@ CODEGENOPT(TimePassesPerRun , 1, 0) ///< Set when -ftime-report=per-pass-run is CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled. VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (in microseconds), ///< traced by time profiler +CODEGENOPT(InterchangeLoops , 1, 0) ///< Run loop-interchange. CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled. @@ -393,6 +396,9 @@ CODEGENOPT(EnableTLSDESC, 1, 0) /// Bit size of immediate TLS offsets (0 == use the default). VALUE_CODEGENOPT(TLSSize, 8, 0) +/// The types of variables that we will extend the live ranges of. +ENUM_CODEGENOPT(ExtendVariableLiveness, ExtendVariableLivenessKind, 2, ExtendVariableLivenessKind::None) + /// The default stack protector guard offset to use. VALUE_CODEGENOPT(StackProtectorGuardOffset, 32, INT_MAX) @@ -462,6 +468,14 @@ ENUM_CODEGENOPT(ZeroCallUsedRegs, llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind, /// non-deleting destructors. (No effect on Microsoft ABI.) CODEGENOPT(CtorDtorReturnThis, 1, 0) +/// Enables emitting Import Call sections on supported targets that can be used +/// by the Windows kernel to enable import call optimization. +CODEGENOPT(ImportCallOptimization, 1, 0) + +/// Controls whether we generate code for static linking of libclosure +/// (BlocksRuntime) on Windows. +CODEGENOPT(StaticClosure, 1, 0) + /// FIXME: Make DebugOptions its own top-level .def file. #include "DebugOptions.def" diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index b64ad74d711c6..c531c656f42b7 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -95,6 +95,12 @@ class CodeGenOptions : public CodeGenOptionsBase { Embed_Marker // Embed a marker as a placeholder for bitcode. }; + enum class ExtendVariableLivenessKind { + None, + This, + All, + }; + enum InlineAsmDialectKind { IAD_ATT, IAD_Intel, diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 510b782e35d06..848acce3c4f13 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -375,10 +375,12 @@ class DiagnosticsEngine : public RefCountedBase { // Map extensions to warnings or errors? diag::Severity ExtBehavior = diag::Severity::Ignored; - DiagState() + DiagnosticIDs &DiagIDs; + + DiagState(DiagnosticIDs &DiagIDs) : IgnoreAllWarnings(false), EnableAllWarnings(false), WarningsAsErrors(false), ErrorsAsFatal(false), - SuppressSystemWarnings(false) {} + SuppressSystemWarnings(false), DiagIDs(DiagIDs) {} using iterator = llvm::DenseMap::iterator; using const_iterator = @@ -893,6 +895,8 @@ class DiagnosticsEngine : public RefCountedBase { /// \param FormatString A fixed diagnostic format string that will be hashed /// and mapped to a unique DiagID. template + // TODO: Deprecate this once all uses are removed from Clang. + // [[deprecated("Use a CustomDiagDesc instead of a Level")]] unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) { return Diags->getCustomDiagID((DiagnosticIDs::Level)L, StringRef(FormatString, N - 1)); diff --git a/clang/include/clang/Basic/DiagnosticCategories.h b/clang/include/clang/Basic/DiagnosticCategories.h index 14be326f7515f..839f8dee3ca89 100644 --- a/clang/include/clang/Basic/DiagnosticCategories.h +++ b/clang/include/clang/Basic/DiagnosticCategories.h @@ -21,11 +21,12 @@ namespace clang { }; enum class Group { -#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \ - GroupName, +#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \ + GroupName, #include "clang/Basic/DiagnosticGroups.inc" #undef CATEGORY #undef DIAG_ENTRY + NUM_GROUPS }; } // end namespace diag } // end namespace clang diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index f4a155bb00bb3..f26c906b46447 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -402,16 +402,6 @@ def note_file_misc_sloc_usage : Note< def err_module_format_unhandled : Error< "no handler registered for module format '%0'">, DefaultFatal; -// TransformActions -// TODO: Use a custom category name to distinguish rewriter errors. -def err_mt_message : Error<"[rewriter] %0">, SuppressInSystemHeader; -def warn_mt_message : Warning<"[rewriter] %0">; -def note_mt_message : Note<"[rewriter] %0">; - -// ARCMigrate -def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">; -def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">; - // API notes def err_apinotes_message : Error<"%0">; def warn_apinotes_message : Warning<"%0">, InGroup>; diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 288786b8ce939..2e571ee33cafa 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -209,6 +209,8 @@ def err_drv_cannot_open_randomize_layout_seed_file : Error< "cannot read randomize layout seed file '%0'">; def err_drv_invalid_version_number : Error< "invalid version number in '%0'">; +def err_drv_kcfi_arity_unsupported_target : Error< + "target '%0' is unsupported by -fsanitize-kcfi-arity">; def err_drv_no_linker_llvm_support : Error< "'%0': unable to pass LLVM bit-code files to linker">; def err_drv_no_ast_support : Error< @@ -445,9 +447,6 @@ def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; def warn_drv_deprecated_arg : Warning< "argument '%0' is deprecated%select{|, use '%2' instead}1">, InGroup; -def warn_drv_deprecated_arg_no_relaxed_template_template_args : Warning< - "argument '-fno-relaxed-template-template-args' is deprecated">, - InGroup; def warn_drv_deprecated_arg_ofast : Warning< "argument '-Ofast' is deprecated; use '-O3 -ffast-math' for the same behavior," " or '-O3' to enable only conforming optimizations">, diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 209792f851b6a..05e39899e6f25 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -102,7 +102,6 @@ def EnumConversion : DiagGroup<"enum-conversion", [EnumEnumConversion, EnumFloatConversion, EnumCompareConditional]>; -def DeprecatedNoRelaxedTemplateTemplateArgs : DiagGroup<"deprecated-no-relaxed-template-template-args">; def DeprecatedOFast : DiagGroup<"deprecated-ofast">; def ObjCSignedCharBoolImplicitIntConversion : DiagGroup<"objc-signed-char-bool-implicit-int-conversion">; @@ -230,7 +229,6 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion, DeprecatedLiteralOperator, DeprecatedPragma, DeprecatedRegister, - DeprecatedNoRelaxedTemplateTemplateArgs, DeprecatedOFast, DeprecatedThisCapture, DeprecatedType, @@ -696,6 +694,36 @@ def SuspiciousMemaccess : DiagGroup<"suspicious-memaccess", NonTrivialMemaccess, MemsetTransposedArgs, SuspiciousBzero]>; def StaticInInline : DiagGroup<"static-in-inline">; def StaticLocalInInline : DiagGroup<"static-local-in-inline">; +def UniqueObjectDuplication : DiagGroup<"unique-object-duplication"> { + code Documentation = [{ +Warns when objects which are supposed to be globally unique might get duplicated +when built into a shared library. + +If an object with hidden visibility is built into a shared library, each instance +of the library will get its own copy. This can cause very subtle bugs if there was +only supposed to be one copy of the object in question: singletons aren't single, +changes to one object won't affect the others, the object's initializer will run +once per copy, etc. + +Specifically, this warning fires when it detects an object which: + 1. Appears in a header file (so it might get compiled into multiple libaries), and + 2. Has external linkage (otherwise it's supposed to be duplicated), and + 3. Has hidden visibility. + +As well as one of the following: + 1. The object is mutable, or + 2. The object's initializer definitely has side effects. + +The warning is best resolved by making the object ``const`` (if possible), or by explicitly +giving the object non-hidden visibility, e.g. using ``__attribute((visibility("default")))``. +Note that all levels of a pointer variable must be constant; ``const int*`` will +trigger the warning because the pointer itself is mutable. + +This warning is currently disabled on Windows since it uses import/export rules +instead of visibility. +}]; +} + def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">; def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>; // Allow differentiation between GNU statement expressions in a macro versus @@ -1306,6 +1334,8 @@ def MicrosoftStaticAssert : DiagGroup<"microsoft-static-assert">; def MicrosoftInitFromPredefined : DiagGroup<"microsoft-init-from-predefined">; def MicrosoftStringLiteralFromPredefined : DiagGroup< "microsoft-string-literal-from-predefined">; +def MicrosoftInlineOnNonFunction : DiagGroup< + "microsoft-inline-on-non-function">; // Aliases. def : DiagGroup<"msvc-include", [MicrosoftInclude]>; @@ -1324,7 +1354,7 @@ def Microsoft : DiagGroup<"microsoft", MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag, MicrosoftCommentPaste, MicrosoftEndOfFile, MicrosoftStaticAssert, MicrosoftInitFromPredefined, MicrosoftStringLiteralFromPredefined, - MicrosoftInconsistentDllImport]>; + MicrosoftInconsistentDllImport, MicrosoftInlineOnNonFunction]>; def ClangClPch : DiagGroup<"clang-cl-pch">; diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h index a051af327de28..b49185c3335d8 100644 --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H #define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H +#include "clang/Basic/DiagnosticCategories.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" @@ -84,7 +85,7 @@ namespace clang { /// to either Ignore (nothing), Remark (emit a remark), Warning /// (emit a warning) or Error (emit as an error). It allows clients to /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one). - enum class Severity { + enum class Severity : uint8_t { // NOTE: 0 means "uncomputed". Ignored = 1, ///< Do not present this diagnostic, ignore it. Remark = 2, ///< Present this diagnostic as a remark. @@ -181,13 +182,96 @@ class DiagnosticMapping { class DiagnosticIDs : public RefCountedBase { public: /// The level of the diagnostic, after it has been through mapping. - enum Level { - Ignored, Note, Remark, Warning, Error, Fatal + enum Level : uint8_t { Ignored, Note, Remark, Warning, Error, Fatal }; + + // Diagnostic classes. + enum Class { + CLASS_INVALID = 0x00, + CLASS_NOTE = 0x01, + CLASS_REMARK = 0x02, + CLASS_WARNING = 0x03, + CLASS_EXTENSION = 0x04, + CLASS_ERROR = 0x05 + }; + + static bool IsCustomDiag(diag::kind Diag) { + return Diag >= diag::DIAG_UPPER_LIMIT; + } + + class CustomDiagDesc { + LLVM_PREFERRED_TYPE(diag::Severity) + unsigned DefaultSeverity : 3; + LLVM_PREFERRED_TYPE(Class) + unsigned DiagClass : 3; + LLVM_PREFERRED_TYPE(bool) + unsigned ShowInSystemHeader : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned ShowInSystemMacro : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned HasGroup : 1; + diag::Group Group; + std::string Description; + + auto get_as_tuple() const { + return std::tuple(DefaultSeverity, DiagClass, ShowInSystemHeader, + ShowInSystemMacro, HasGroup, Group, + std::string_view{Description}); + } + + public: + CustomDiagDesc(diag::Severity DefaultSeverity, std::string Description, + unsigned Class = CLASS_WARNING, + bool ShowInSystemHeader = false, + bool ShowInSystemMacro = false, + std::optional Group = std::nullopt) + : DefaultSeverity(static_cast(DefaultSeverity)), + DiagClass(Class), ShowInSystemHeader(ShowInSystemHeader), + ShowInSystemMacro(ShowInSystemMacro), HasGroup(Group != std::nullopt), + Group(Group.value_or(diag::Group{})), + Description(std::move(Description)) {} + + std::optional GetGroup() const { + if (HasGroup) + return Group; + return std::nullopt; + } + + diag::Severity GetDefaultSeverity() const { + return static_cast(DefaultSeverity); + } + + Class GetClass() const { return static_cast(DiagClass); } + std::string_view GetDescription() const { return Description; } + bool ShouldShowInSystemHeader() const { return ShowInSystemHeader; } + + friend bool operator==(const CustomDiagDesc &lhs, + const CustomDiagDesc &rhs) { + return lhs.get_as_tuple() == rhs.get_as_tuple(); + } + + friend bool operator<(const CustomDiagDesc &lhs, + const CustomDiagDesc &rhs) { + return lhs.get_as_tuple() < rhs.get_as_tuple(); + } + }; + + struct GroupInfo { + LLVM_PREFERRED_TYPE(diag::Severity) + unsigned Severity : 3; + LLVM_PREFERRED_TYPE(bool) + unsigned HasNoWarningAsError : 1; }; private: /// Information for uniquing and looking up custom diags. std::unique_ptr CustomDiagInfo; + std::unique_ptr GroupInfos = []() { + auto GIs = std::make_unique( + static_cast(diag::Group::NUM_GROUPS)); + for (size_t i = 0; i != static_cast(diag::Group::NUM_GROUPS); ++i) + GIs[i] = {{}, false}; + return GIs; + }(); public: DiagnosticIDs(); @@ -202,7 +286,35 @@ class DiagnosticIDs : public RefCountedBase { // FIXME: Replace this function with a create-only facilty like // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of // writing, nearly all callers of this function were invalid. - unsigned getCustomDiagID(Level L, StringRef FormatString); + unsigned getCustomDiagID(CustomDiagDesc Diag); + + // TODO: Deprecate this once all uses are removed from LLVM + // [[deprecated("Use a CustomDiagDesc instead of a Level")]] + unsigned getCustomDiagID(Level Level, StringRef Message) { + return getCustomDiagID([&]() -> CustomDiagDesc { + switch (Level) { + case DiagnosticIDs::Level::Ignored: + return {diag::Severity::Ignored, std::string(Message), CLASS_WARNING, + /*ShowInSystemHeader*/ true, /*ShowInSystemMacro=*/true}; + case DiagnosticIDs::Level::Note: + return {diag::Severity::Fatal, std::string(Message), CLASS_NOTE, + /*ShowInSystemHeader*/ true, /*ShowInSystemMacro=*/true}; + case DiagnosticIDs::Level::Remark: + return {diag::Severity::Remark, std::string(Message), CLASS_REMARK, + /*ShowInSystemHeader*/ true, /*ShowInSystemMacro=*/true}; + case DiagnosticIDs::Level::Warning: + return {diag::Severity::Warning, std::string(Message), CLASS_WARNING, + /*ShowInSystemHeader*/ true, /*ShowInSystemMacro=*/true}; + case DiagnosticIDs::Level::Error: + return {diag::Severity::Error, std::string(Message), CLASS_ERROR, + /*ShowInSystemHeader*/ true, /*ShowInSystemMacro=*/true}; + case DiagnosticIDs::Level::Fatal: + return {diag::Severity::Fatal, std::string(Message), CLASS_ERROR, + /*ShowInSystemHeader*/ true, /*ShowInSystemMacro=*/true}; + } + llvm_unreachable("Fully covered switch above!"); + }()); + } //===--------------------------------------------------------------------===// // Diagnostic classification and reporting interfaces. @@ -214,35 +326,36 @@ class DiagnosticIDs : public RefCountedBase { /// Return true if the unmapped diagnostic levelof the specified /// diagnostic ID is a Warning or Extension. /// - /// This only works on builtin diagnostics, not custom ones, and is not - /// legal to call on NOTEs. - static bool isBuiltinWarningOrExtension(unsigned DiagID); + /// This is not legal to call on NOTEs. + bool isWarningOrExtension(unsigned DiagID) const; /// Return true if the specified diagnostic is mapped to errors by /// default. - static bool isDefaultMappingAsError(unsigned DiagID); + bool isDefaultMappingAsError(unsigned DiagID) const; /// Get the default mapping for this diagnostic. - static DiagnosticMapping getDefaultMapping(unsigned DiagID); + DiagnosticMapping getDefaultMapping(unsigned DiagID) const; + + void initCustomDiagMapping(DiagnosticMapping &, unsigned DiagID); - /// Determine whether the given built-in diagnostic ID is a Note. - static bool isBuiltinNote(unsigned DiagID); + /// Determine whether the given diagnostic ID is a Note. + bool isNote(unsigned DiagID) const; - /// Determine whether the given built-in diagnostic ID is for an + /// Determine whether the given diagnostic ID is for an /// extension of some sort. - static bool isBuiltinExtensionDiag(unsigned DiagID) { + bool isExtensionDiag(unsigned DiagID) const { bool ignored; - return isBuiltinExtensionDiag(DiagID, ignored); + return isExtensionDiag(DiagID, ignored); } - /// Determine whether the given built-in diagnostic ID is for an + /// Determine whether the given diagnostic ID is for an /// extension of some sort, and whether it is enabled by default. /// /// This also returns EnabledByDefault, which is set to indicate whether the /// diagnostic is ignored by default (in which case -pedantic enables it) or /// treated as a warning/error by default. /// - static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault); + bool isExtensionDiag(unsigned DiagID, bool &EnabledByDefault) const; /// Given a group ID, returns the flag that toggles the group. /// For example, for Group::DeprecatedDeclarations, returns @@ -252,19 +365,22 @@ class DiagnosticIDs : public RefCountedBase { /// Given a diagnostic group ID, return its documentation. static StringRef getWarningOptionDocumentation(diag::Group GroupID); + void setGroupSeverity(StringRef Group, diag::Severity); + void setGroupNoWarningsAsError(StringRef Group, bool); + /// Given a group ID, returns the flag that toggles the group. /// For example, for "deprecated-declarations", returns /// Group::DeprecatedDeclarations. static std::optional getGroupForWarningOption(StringRef); /// Return the lowest-level group that contains the specified diagnostic. - static std::optional getGroupForDiag(unsigned DiagID); + std::optional getGroupForDiag(unsigned DiagID) const; /// Return the lowest-level warning option that enables the specified /// diagnostic. /// /// If there is no -Wfoo flag that controls the diagnostic, this returns null. - static StringRef getWarningOptionForDiag(unsigned DiagID); + StringRef getWarningOptionForDiag(unsigned DiagID); /// Return the category number that a specified \p DiagID belongs to, /// or 0 if no category. @@ -365,6 +481,8 @@ class DiagnosticIDs : public RefCountedBase { getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, const DiagnosticsEngine &Diag) const LLVM_READONLY; + Class getDiagClass(unsigned DiagID) const; + /// Used to report a diagnostic that is finally fully formed. /// /// \returns \c true if the diagnostic was emitted, \c false if it was diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 3309f59a981fc..c513dab810d1f 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1099,6 +1099,16 @@ def err_lambda_capture_misplaced_ellipsis : Error< "the name of the capture">; def err_lambda_capture_multiple_ellipses : Error< "multiple ellipses in pack capture">; +def err_binding_multiple_ellipses : Error< + "multiple packs in structured binding declaration">; +def note_previous_ellipsis : Note< + "previous binding pack specified here">; +def ext_cxx_binding_pack : ExtWarn< + "structured binding packs are a C++2c extension ">, + InGroup; +def warn_cxx23_compat_binding_pack : Warning< + "structured binding packs are incompatible with C++ standards before C++2c">, + InGroup, DefaultIgnore; def err_capture_default_first : Error< "capture default must be first">; def ext_decl_attrs_on_lambda : ExtWarn< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 774e5484cfa0e..e78339ee924ff 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -82,11 +82,11 @@ def err_typecheck_converted_constant_expression_indirect : Error< "conversion from %0 to %1 in converted constant expression would " "bind reference to a temporary">; def err_expr_not_cce : Error< - "%select{case value|enumerator value|non-type template argument|" + "%select{case value|enumerator value|non-type template argument|non-type parameter of template template parameter|" "array size|explicit specifier argument|noexcept specifier argument|" "call to 'size()'|call to 'data()'}0 is not a constant expression">; def ext_cce_narrowing : ExtWarn< - "%select{case value|enumerator value|non-type template argument|" + "%select{case value|enumerator value|non-type template argument|non-type parameter of template template parameter|" "array size|explicit specifier argument|noexcept specifier argument|" "call to 'size()'|call to 'data()'}0 %select{cannot be narrowed from " "type %2 to %3|evaluates to %2, which cannot be narrowed to type %3}1">, @@ -350,10 +350,11 @@ def warn_arm_interrupt_vfp_clobber : Warning< InGroup>; def err_arm_interrupt_called : Error< "interrupt service routine cannot be called directly">; -def warn_interrupt_attribute_invalid : Warning< - "%select{MIPS|MSP430|RISC-V}0 'interrupt' attribute only applies to " - "functions that have %select{no parameters|a 'void' return type}1">, - InGroup; +def warn_interrupt_signal_attribute_invalid : Warning< + "%select{MIPS|MSP430|RISC-V|AVR}0 '%select{interrupt|signal}1' " + "attribute only applies to functions that have " + "%select{no parameters|a 'void' return type}2">, + InGroup; def warn_riscv_repeated_interrupt_attribute : Warning< "repeated RISC-V 'interrupt' attribute">, InGroup; def note_riscv_repeated_interrupt_attribute : Note< @@ -482,13 +483,15 @@ def ext_use_out_of_scope_declaration : ExtWarn< InGroup>; def err_inline_non_function : Error< "'inline' can only appear on functions%select{| and non-local variables}0">; +def warn_ms_inline_non_function : ExtWarn, + InGroup; def err_noreturn_non_function : Error< "'_Noreturn' can only appear on functions">; def warn_qual_return_type : Warning< "'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect">, InGroup, DefaultIgnore; def warn_qual_base_type : Warning< - "'%0' qualifier%s1 on base class type %2 have no effect">, + "'%0' qualifier%s1 on base class type %2 %plural{1:has|:have}1 no effect">, InGroup, DefaultIgnore; def warn_deprecated_redundant_constexpr_static_def : Warning< @@ -2953,9 +2956,15 @@ def ext_constexpr_function_never_constant_expr : ExtWarn< "constant expression">, InGroup>, DefaultError; def err_attr_cond_never_constant_expr : Error< "%0 attribute expression never produces a constant expression">; +def err_diagnose_if_unknown_warning : Error<"unknown warning group '%0'">; def err_diagnose_if_invalid_diagnostic_type : Error< "invalid diagnostic type for 'diagnose_if'; use \"error\" or \"warning\" " "instead">; +def err_diagnose_if_unknown_option : Error<"unknown diagnostic option">; +def err_diagnose_if_expected_equals : Error< + "expected '=' after diagnostic option">; +def err_diagnose_if_unexpected_value : Error< + "unexpected value; use 'true' or 'false'">; def err_constexpr_body_no_return : Error< "no return statement in %select{constexpr|consteval}0 function">; def err_constexpr_return_missing_expr : Error< @@ -3824,6 +3833,9 @@ def warn_type_attribute_wrong_type : Warning< "'%0' only applies to %select{function|pointer|" "Objective-C object or block pointer}1 types; type here is %2">, InGroup; +def warn_attribute_on_void_param: Warning< + "attribute %0 cannot be applied to a 'void' parameter">, + InGroup; def err_type_attribute_wrong_type : Error< warn_type_attribute_wrong_type.Summary>; def warn_incomplete_encoded_type : Warning< @@ -3864,6 +3876,9 @@ def err_sme_definition_using_za_in_non_sme_target : Error< "function using ZA state requires 'sme'">; def err_sme_definition_using_zt0_in_non_sme2_target : Error< "function using ZT0 state requires 'sme2'">; +def err_sme_openmp_captured_region : Error< + "OpenMP captured regions are not yet supported in " + "%select{streaming functions|functions with ZA state|functions with ZT0 state}0">; def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning< "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" " streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime">, @@ -5936,6 +5951,9 @@ def warn_cxx23_pack_indexing : Warning< "pack indexing is incompatible with C++ standards before C++2c">, DefaultIgnore, InGroup; +def err_pack_outside_template : Error< + "pack declaration outside of template">; + def err_fold_expression_packs_both_sides : Error< "binary fold expression has unexpanded parameter packs in both operands">; def err_fold_expression_empty : Error< @@ -6099,6 +6117,8 @@ def note_deleted_special_member_class_subobject : Note< "destructor}5" "%select{||s||}4" "|is an ObjC pointer}6">; +def note_default_constructed_field + : Note<"default constructed field %0 declared here">; def note_deleted_default_ctor_uninit_field : Note< "%select{default constructor of|constructor inherited by}0 " "%1 is implicitly deleted because field %2 of " @@ -6153,6 +6173,15 @@ def warn_static_local_in_extern_inline : Warning< def note_convert_inline_to_static : Note< "use 'static' to give inline function %0 internal linkage">; +def warn_possible_object_duplication_mutable : Warning< + "%0 may be duplicated when built into a shared library: " + "it is mutable, has hidden visibility, and external linkage">, + InGroup, DefaultIgnore; +def warn_possible_object_duplication_init : Warning< + "initializeation of %0 may run twice when built into a shared library: " + "it has hidden visibility and external linkage">, + InGroup, DefaultIgnore; + def ext_redefinition_of_typedef : ExtWarn< "redefinition of typedef %0 is a C11 feature">, InGroup >; @@ -9168,6 +9197,8 @@ def err_cuda_device_exceptions : Error< def err_dynamic_var_init : Error< "dynamic initialization is not supported for " "__device__, __constant__, __shared__, and __managed__ variables">; +def err_cuda_ctor_dtor_attrs + : Error<"CUDA does not support global %0 for __device__ functions">; def err_shared_var_init : Error< "initialization is not supported for __shared__ variables">; def err_cuda_vla : Error< @@ -10624,6 +10655,8 @@ def err_second_argument_to_cwsc_not_pointer : Error< def err_vector_incorrect_num_elements : Error< "%select{too many|too few}0 elements in vector %select{initialization|operand}3 (expected %1 elements, have %2)">; +def err_invalid_even_odd_vector_element_count : Error< + "invalid element count of %0 in vector %select{initialization|operand}4 (expected an %select{even|odd}3 element count in the range of %1 and %2)">; def err_altivec_empty_initializer : Error<"expected initializer">; def err_invalid_neon_type_code : Error< @@ -12889,6 +12922,48 @@ def err_acc_update_as_body : Error<"OpenACC 'update' construct may not appear in place of the " "statement following a%select{n if statement| while statement| do " "statement| switch statement| label statement}0">; +def err_acc_invalid_atomic + : Error<"statement associated with OpenACC 'atomic%select{| " + "%1}0' directive is invalid">; +def note_acc_atomic_expr_must_be + : Note<"expected " + "%enum_select{%Assign{assignment}|%UnaryCompAssign{" + "assignment, compound assignment, increment, or decrement}}0 " + "expression">; +def note_acc_atomic_unsupported_unary_operator + : Note<"unary operator not supported, only increment and decrement " + "operations permitted">; +def note_acc_atomic_unsupported_binary_operator + : Note<"binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> " + "are permitted">; +def note_acc_atomic_unsupported_compound_binary_operator + : Note<"compound binary operator not supported, only +=, *=, -=, /=, &=, " + "^=, |=, <<=, or >>= are permitted">; + +def note_acc_atomic_operand_lvalue_scalar + : Note<"%select{left |right |}0operand to " + "%enum_select{%Assign{assignment}|%CompoundAssign{" + "compound assignment}|%Inc{increment}|" + "%Dec{decrement}}1 " + "expression must be " + "%enum_select{%LVal{an l-value}|%Scalar{of scalar " + "type (was %3)}}2">; +def note_acc_atomic_too_many_stmts + : Note<"'atomic capture' with a compound statement only supports two " + "statements">; +def note_acc_atomic_expected_binop : Note<"expected binary operation on right " + "hand side of assignment operator">; +def note_acc_atomic_mismatch_operand + : Note<"left hand side of assignment operation('%0') must match one side " + "of the sub-operation on the right hand side('%1' and '%2')">; +def note_acc_atomic_mismatch_compound_operand + : Note<"variable %select{|in unary expression|on right hand side of " + "assignment|on left hand side of assignment|on left hand side of " + "compound assignment|on left hand side of assignment}2('%3') must " + "match variable used %select{|in unary expression|on right hand " + "side of assignment||on left hand side of compound " + "assignment|on left hand side of assignment}0('%1') from the first " + "statement">; // AMDGCN builtins diagnostics def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">; diff --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def index 79f04c89c9fed..90428c3c73c8b 100644 --- a/clang/include/clang/Basic/FPOptions.def +++ b/clang/include/clang/Basic/FPOptions.def @@ -28,5 +28,5 @@ OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc) OPTION(Float16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, FPEvalMethod) OPTION(BFloat16ExcessPrecision, LangOptions::ExcessPrecisionKind, 2, Float16ExcessPrecision) OPTION(MathErrno, bool, 1, BFloat16ExcessPrecision) -OPTION(ComplexRange, LangOptions::ComplexRangeKind, 2, MathErrno) +OPTION(ComplexRange, LangOptions::ComplexRangeKind, 3, MathErrno) #undef OPTION diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index c82b6d9b5f6c1..e736b46411ed1 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -254,6 +254,7 @@ FEATURE(is_trivially_constructible, LangOpts.CPlusPlus) FEATURE(is_trivially_copyable, LangOpts.CPlusPlus) FEATURE(is_union, LangOpts.CPlusPlus) FEATURE(kcfi, LangOpts.Sanitize.has(SanitizerKind::KCFI)) +FEATURE(kcfi_arity, LangOpts.Sanitize.has(SanitizerKind::KCFI)) FEATURE(modules, LangOpts.Modules) FEATURE(safe_stack, LangOpts.Sanitize.has(SanitizerKind::SafeStack)) FEATURE(shadow_call_stack, diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index 33d1cdb46f108..0347880244a40 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -101,8 +101,9 @@ enum class InterestingIdentifier { NUM_OBJC_KEYWORDS_AND_NOTABLE_IDENTIFIERS, NotBuiltin, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_ENUMERATORS FirstTSBuiltin, NotInterestingIdentifier = 65534 @@ -1008,7 +1009,7 @@ class Selector { } const IdentifierInfo *getAsIdentifierInfo() const { - return InfoPtr.getPointer().dyn_cast(); + return dyn_cast_if_present(InfoPtr.getPointer()); } MultiKeywordSelector *getMultiKeywordSelector() const { diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index a980be853d53e..bfab0baa089cf 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -160,7 +160,6 @@ LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly") LANGOPT(Coroutines , 1, 0, "C++20 coroutines") LANGOPT(CoroAlignedAllocation, 1, 0, "prefer Aligned Allocation according to P2014 Option 2") LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods") -LANGOPT(RelaxedTemplateTemplateArgs, 1, 1, "C++17 relaxed matching of template template arguments") LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features") LANGOPT(RetainSubstTemplateTypeParmTypeAstNodes, 1, 0, "retain SubstTemplateTypeParmType nodes in the AST's representation of alias template specializations") @@ -239,7 +238,7 @@ BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization wit BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal") BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation") -ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 2, CX_None, "Enable use of range reduction for complex arithmetics.") +ENUM_LANGOPT(ComplexRange, ComplexRangeKind, 3, CX_None, "Enable use of range reduction for complex arithmetics.") BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") @@ -407,6 +406,7 @@ VALUE_LANGOPT(TrivialAutoVarInitMaxSize, 32, 0, "stop trivial automatic variable initialization if var size exceeds the specified size (in bytes). Must be greater than 0.") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling") +LANGOPT(PointerOverflowDefined, 1, 0, "make pointer overflow defined") ENUM_LANGOPT(ThreadModel , ThreadModelKind, 2, ThreadModelKind::POSIX, "Thread Model") BENIGN_LANGOPT(ArrowDepth, 32, 256, diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 949c8f5d448bc..651b3b67b1058 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -144,6 +144,7 @@ class LangOptionsBase { MSVC2019_5 = 1925, MSVC2019_8 = 1928, MSVC2022_3 = 1933, + MSVC2022_9 = 1939, }; enum SYCLMajorVersion { @@ -245,8 +246,15 @@ class LangOptionsBase { /// construction vtable because it hasn't added 'type' as a substitution. /// - Skip mangling enclosing class templates of member-like friend /// function templates. + /// - Ignore empty struct arguments in C++ mode for ARM, instead of + /// passing them as if they had a size of 1 byte. Ver19, + /// Attempt to be ABI-compatible with code generated by Clang 20.0.x. + /// This causes clang to: + /// - Incorrectly return C++ records in AVX registers on x86_64. + Ver20, + /// Conform to the underlying platform's C and C++ ABIs as closely /// as we can. Latest @@ -640,9 +648,12 @@ class LangOptions : public LangOptionsBase { // Define accessors/mutators for language options of enumeration type. #define LANGOPT(Name, Bits, Default, Description) -#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ - Type get##Name() const { return static_cast(Name); } \ - void set##Name(Type Value) { Name = static_cast(Value); } +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + Type get##Name() const { return static_cast(Name); } \ + void set##Name(Type Value) { \ + assert(static_cast(Value) < (1u << Bits)); \ + Name = static_cast(Value); \ + } #include "clang/Basic/LangOptions.def" /// Are we compiling a module? @@ -951,11 +962,14 @@ class FPOptions { void applyChanges(FPOptionsOverride FPO); // We can define most of the accessors automatically: + // TODO: consider enforcing the assertion that value fits within bits + // statically. #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ TYPE get##NAME() const { \ return static_cast((Value & NAME##Mask) >> NAME##Shift); \ } \ void set##NAME(TYPE value) { \ + assert(storage_type(value) < (1u << WIDTH)); \ Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ } #include "clang/Basic/FPOptions.def" diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h index 7fb76271826a6..c2d7732123ef2 100644 --- a/clang/include/clang/Basic/OpenACCKinds.h +++ b/clang/include/clang/Basic/OpenACCKinds.h @@ -171,9 +171,34 @@ enum class OpenACCAtomicKind : uint8_t { Write, Update, Capture, - Invalid, + None, }; +template +inline StreamTy &printOpenACCAtomicKind(StreamTy &Out, OpenACCAtomicKind AK) { + switch (AK) { + case OpenACCAtomicKind::Read: + return Out << "read"; + case OpenACCAtomicKind::Write: + return Out << "write"; + case OpenACCAtomicKind::Update: + return Out << "update"; + case OpenACCAtomicKind::Capture: + return Out << "capture"; + case OpenACCAtomicKind::None: + return Out << ""; + } + llvm_unreachable("unknown atomic kind"); +} +inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &Out, + OpenACCAtomicKind AK) { + return printOpenACCAtomicKind(Out, AK); +} +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &Out, + OpenACCAtomicKind AK) { + return printOpenACCAtomicKind(Out, AK); +} + /// Represents the kind of an OpenACC clause. enum class OpenACCClauseKind : uint8_t { /// 'finalize' clause, allowed on 'exit data' directive. diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 3e5da2a6abc01..e80bce34a97e0 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -399,6 +399,14 @@ bool isOpenMPInformationalDirective(OpenMPDirectiveKind DKind); /// \return true - if the above condition is met for this directive /// otherwise - false. bool isOpenMPCapturingDirective(OpenMPDirectiveKind DKind); + +/// Checks if the specified directive is an order concurrent nestable +/// directive that can be nested within region corresponding to construct +/// on which order clause was specified with concurrent as ordering argument. +/// \param DKind Specified directive. +/// \return true - if the above condition is met for this directive +/// otherwise - false. +bool isOpenMPOrderConcurrentNestableDirective(OpenMPDirectiveKind DKind); } template <> diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h index fc0576d452b17..3782deb5962bc 100644 --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -162,6 +162,11 @@ class SanitizerMaskCutoffs { void set(SanitizerMask K, double V); void clear(SanitizerMask K = SanitizerKind::All); + + // Returns nullopt if all the values are zero. + // Otherwise, return value contains a vector of all the scaled values. + std::optional> + getAllScaled(unsigned ScalingFactor) const; }; struct SanitizerSet { diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 53fc77bbbcecc..d47e0a8157fc6 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -163,6 +163,7 @@ def MaterializeTemporaryExpr : StmtNode; def LambdaExpr : StmtNode; def CXXFoldExpr : StmtNode; def CXXParenListInitExpr: StmtNode; +def ResolvedUnexpandedPackExpr : StmtNode; // C++ Coroutines expressions def CoroutineSuspendExpr : StmtNode; @@ -318,6 +319,7 @@ def OpenACCInitConstruct : StmtNode; def OpenACCShutdownConstruct : StmtNode; def OpenACCSetConstruct : StmtNode; def OpenACCUpdateConstruct : StmtNode; +def OpenACCAtomicConstruct : StmtNode; // OpenACC Additional Expressions. def OpenACCAsteriskSizeExpr : StmtNode; diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 4dc8b24ed8ae6..4781054240b5b 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -26,30 +26,50 @@ namespace clang { namespace NEON { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, -#include "clang/Basic/BuiltinsNEON.def" +#define GET_NEON_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_neon.inc" + FirstFp16Builtin, + LastNeonBuiltin = FirstFp16Builtin - 1, +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_ENUMERATORS FirstTSBuiltin }; } /// ARM builtins namespace ARM { - enum { - LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, - LastNEONBuiltin = NEON::FirstTSBuiltin - 1, + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, + LastNEONBuiltin = NEON::FirstTSBuiltin - 1, +#define GET_MVE_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_mve_builtins.inc" +#undef GET_MVE_BUILTIN_ENUMERATORS + FirstCDEBuiltin, + LastMVEBuiltin = FirstCDEBuiltin - 1, +#define GET_CDE_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_cde_builtins.inc" +#undef GET_CDE_BUILTIN_ENUMERATORS + FirstARMBuiltin, + LastCDEBuiltin = FirstARMBuiltin - 1, #define BUILTIN(ID, TYPE, ATTRS) BI##ID, #include "clang/Basic/BuiltinsARM.def" - LastTSBuiltin - }; + LastTSBuiltin + }; } namespace SVE { enum { LastNEONBuiltin = NEON::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_SVE_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_sve_builtins.inc" +#undef GET_SVE_BUILTIN_ENUMERATORS + FirstNeonBridgeBuiltin, + LastSveBuiltin = FirstNeonBridgeBuiltin - 1, +#define GET_SVE_BUILTINS #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, -#include "clang/Basic/BuiltinsSVE.def" +#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def" +#undef TARGET_BUILTIN +#undef GET_SVE_BUILTINS FirstTSBuiltin, }; } @@ -57,9 +77,9 @@ namespace clang { namespace SME { enum { LastSVEBuiltin = SVE::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, -#include "clang/Basic/BuiltinsSME.def" +#define GET_SME_BUILTIN_ENUMERATORS +#include "clang/Basic/arm_sme_builtins.inc" +#undef GET_SME_BUILTIN_ENUMERATORS FirstTSBuiltin, }; } @@ -83,8 +103,9 @@ namespace clang { namespace BPF { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, - #define BUILTIN(ID, TYPE, ATTRS) BI##ID, - #include "clang/Basic/BuiltinsBPF.inc" +#define GET_BUILTIN_ENUMERATORS +#include "clang/Basic/BuiltinsBPF.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } @@ -101,12 +122,13 @@ namespace clang { /// NVPTX builtins namespace NVPTX { - enum { - LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#include "clang/Basic/BuiltinsNVPTX.def" - LastTSBuiltin - }; + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define GET_BUILTIN_ENUMERATORS +#include "clang/Basic/BuiltinsNVPTX.inc" +#undef GET_BUILTIN_ENUMERATORS + LastTSBuiltin + }; } /// AMDGPU builtins @@ -123,8 +145,9 @@ namespace clang { namespace SPIRV { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsSPIRV.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } // namespace SPIRV @@ -133,12 +156,14 @@ namespace clang { namespace X86 { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_ENUMERATORS FirstX86_64Builtin, LastX86CommonBuiltin = FirstX86_64Builtin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } @@ -156,8 +181,12 @@ namespace clang { namespace RISCVVector { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#include "clang/Basic/BuiltinsRISCVVector.def" +#define GET_RISCVV_BUILTIN_ENUMERATORS +#include "clang/Basic/riscv_vector_builtins.inc" + FirstSiFiveBuiltin, + LastRVVBuiltin = FirstSiFiveBuiltin - 1, +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_ENUMERATORS FirstTSBuiltin, }; } @@ -168,8 +197,9 @@ namespace clang { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, FirstRVVBuiltin = clang::Builtin::FirstTSBuiltin, LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#define GET_BUILTIN_ENUMERATORS #include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_ENUMERATORS LastTSBuiltin }; } // namespace RISCV @@ -178,8 +208,16 @@ namespace clang { namespace LoongArch { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#include "clang/Basic/BuiltinsLoongArch.def" +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, +#include "clang/Basic/BuiltinsLoongArchBase.def" + FirstLSXBuiltin, + LastBaseBuiltin = FirstLSXBuiltin - 1, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, +#include "clang/Basic/BuiltinsLoongArchLSX.def" + FirstLASXBuiltin, + LastLSXBuiltin = FirstLASXBuiltin - 1, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID, +#include "clang/Basic/BuiltinsLoongArchLASX.def" LastTSBuiltin }; } // namespace LoongArch @@ -208,7 +246,8 @@ namespace clang { Float16, Float32, Float64, - BFloat16 + BFloat16, + MFloat8 }; NeonTypeFlags(unsigned F) : Flags(F) {} @@ -230,6 +269,7 @@ namespace clang { switch (getEltType()) { case Int8: case Poly8: + case MFloat8: return 8; case Int16: case Float16: @@ -352,12 +392,13 @@ namespace clang { /// Hexagon builtins namespace Hexagon { - enum { - LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, -#define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#include "clang/Basic/BuiltinsHexagon.def" - LastTSBuiltin - }; + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define GET_BUILTIN_ENUMERATORS +#include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_ENUMERATORS + LastTSBuiltin + }; } /// MIPS builtins diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 43c09cf1f973e..070cc792ca7db 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -16,6 +16,7 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/BitmaskEnum.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/CFProtectionOptions.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/LLVM.h" @@ -32,6 +33,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/StringTable.h" #include "llvm/Frontend/OpenMP/OMPGridValues.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/DataTypes.h" @@ -1016,14 +1018,15 @@ class TargetInfo : public TransferrableTargetInfo, virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; - /// Return information about target-specific builtins for - /// the current primary target, and info about which builtins are non-portable - /// across the current set of primary and secondary targets. - virtual ArrayRef getTargetBuiltins() const = 0; + /// Return information about target-specific builtins for the current primary + /// target, and info about which builtins are non-portable across the current + /// set of primary and secondary targets. + virtual llvm::SmallVector getTargetBuiltins() const = 0; /// Returns target-specific min and max values VScale_Range. virtual std::optional> - getVScaleRange(const LangOptions &LangOpts) const { + getVScaleRange(const LangOptions &LangOpts, + bool IsArmStreamingFunction) const { return std::nullopt; } /// The __builtin_clz* and __builtin_ctz* built-in @@ -1468,6 +1471,7 @@ class TargetInfo : public TransferrableTargetInfo, /// specification virtual bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, + const LangOptions &LO, StringRef &Err) const { Err = ""; return false; @@ -1658,7 +1662,7 @@ class TargetInfo : public TransferrableTargetInfo, // access target-specific GPU grid values that must be consistent between // host RTL (plugin), deviceRTL and clang. virtual const llvm::omp::GV &getGridValue() const { - llvm_unreachable("getGridValue not implemented on this target"); + return llvm::omp::SPIRVGridValues; } /// Retrieve the name of the platform as it is used in the diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 2c692c999bdff..397a5d95709fb 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -546,7 +546,6 @@ TYPE_TRAIT_1(__is_trivially_equality_comparable, IsTriviallyEqualityComparable, TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX) TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX) TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX) -TYPE_TRAIT_1(__is_referenceable, IsReferenceable, KEYCXX) TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) TYPE_TRAIT_2(__reference_constructs_from_temporary, ReferenceConstructsFromTemporary, KEYCXX) @@ -707,7 +706,7 @@ ALIAS("__decltype" , decltype , KEYCXX) ALIAS("__imag__" , __imag , KEYALL) ALIAS("__inline" , inline , KEYALL) ALIAS("__inline__" , inline , KEYALL) -ALIAS("__nullptr" , nullptr , KEYCXX) +ALIAS("__nullptr" , nullptr , KEYALL) ALIAS("__real__" , __real , KEYALL) ALIAS("__restrict" , restrict , KEYALL) ALIAS("__restrict__" , restrict , KEYALL) diff --git a/clang/include/clang/Basic/Version.inc.in b/clang/include/clang/Basic/Version.inc.in index 370da8506d142..69c79d03861cd 100644 --- a/clang/include/clang/Basic/Version.inc.in +++ b/clang/include/clang/Basic/Version.inc.in @@ -4,3 +4,4 @@ #define CLANG_VERSION_MAJOR_STRING "@CLANG_VERSION_MAJOR@" #define CLANG_VERSION_MINOR @CLANG_VERSION_MINOR@ #define CLANG_VERSION_PATCHLEVEL @CLANG_VERSION_PATCHLEVEL@ +#define MAX_CLANG_ABI_COMPAT_VERSION @MAX_CLANG_ABI_COMPAT_VERSION@ diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td index ddc5391eb3fa2..3e73dd054933f 100644 --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -1299,7 +1299,7 @@ def VQTBX4_A64 : WInst<"vqtbx4", "..(4Q)U", "UccPcQUcQcQPc">; // NeonEmitter implicitly takes the cartesian product of the type string with // itself during generation so, unlike all other intrinsics, this one should // include *all* types, not just additional ones. -def VVREINTERPRET : REINTERPRET_CROSS_SELF<"csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk"> { +def VVREINTERPRET : REINTERPRET_CROSS_SELF<"csilUcUsUiUlmhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQmQhQfQdQPcQPsQPlQPk"> { let ArchGuard = "defined(__aarch64__) || defined(__arm64ec__)"; let BigEndianSafe = 1; } @@ -2119,6 +2119,72 @@ let ArchGuard = "defined(__aarch64__)", TargetGuard = "lut" in { } } +let ArchGuard = "defined(__aarch64__)", TargetGuard = "fp8,neon" in { + def VBF1CVT_BF16_MF8 : VInst<"vcvt1_bf16_mf8_fpm", "(QB).V", "m">; + def VBF1CVT_LOW_BF16_MF8 : VInst<"vcvt1_low_bf16_mf8_fpm", "B.V", "Hm">; + def VBF2CVTL_BF16_MF8 : VInst<"vcvt2_bf16_mf8_fpm", "(QB).V", "m">; + def VBF2CVTL_LOW_BF16_MF8 : VInst<"vcvt2_low_bf16_mf8_fpm", "B.V", "Hm">; + def VBF1CVTL2_HIGH_BF16_MF8 : VInst<"vcvt1_high_bf16_mf8_fpm", "B.V", "Hm">; + def VBF2CVTL2_HIGH_BF16_MF8 : VInst<"vcvt2_high_bf16_mf8_fpm", "B.V", "Hm">; +} + +let ArchGuard = "defined(__aarch64__)", TargetGuard = "fp8,neon" in { + def VF1CVT_F16_MF8 : VInst<"vcvt1_f16_mf8_fpm", "(>QF).V", "m">; + def VF1CVT_LOW_F16_MF8 : VInst<"vcvt1_low_f16_mf8_fpm", "(>F).V", "Hm">; + def VF2CVTL_F16_MF8 : VInst<"vcvt2_f16_mf8_fpm", "(>QF).V", "m">; + def VF2CVTL_LOW_F16_MF8 : VInst<"vcvt2_low_f16_mf8_fpm", "(>F).V", "Hm">; + def VF1CVTL2_HIGH_F16_MF8 : VInst<"vcvt1_high_f16_mf8_fpm", "(>F).V", "Hm">; + def VF2CVTL2_HIGH_F16_MF8 : VInst<"vcvt2_high_f16_mf8_fpm", "(>F).V", "Hm">; + + def VCVTN_LOW_F8_F32 : VInst<"vcvt_mf8_f32_fpm", ".(>>QF)(>>QF)V", "m">; + def VCVTN_HIGH_F8_F32 : VInst<"vcvt_high_mf8_f32_fpm", ".(q)(>>F)(>>F)V", "Hm">; + def VCVTN_F8_F16 : VInst<"vcvt_mf8_f16_fpm", ".(>F)(>F)V", "mQm">; +} + +let ArchGuard = "defined(__aarch64__)", TargetGuard = "fp8dot2,neon" in { + def VDOT_F16_MF8 : VInst<"vdot_f16_mf8_fpm", "(>F)(>F)..V", "mQm">; + + def VDOT_LANE_F16_MF8 : VInst<"vdot_lane_f16_mf8_fpm", "(>F)(>F)..IV", "m", [ImmCheck<3, ImmCheck0_3, 0>]>; + def VDOT_LANEQ_F16_MF8 : VInst<"vdot_laneq_f16_mf8_fpm", "(>F)(>F).QIV", "m", [ImmCheck<3, ImmCheck0_7, 0>]>; + + def VDOTQ_LANE_F16_MF8 : VInst<"vdot_lane_f16_mf8_fpm", "(>F)(>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_3, 0>]>; + def VDOTQ_LANEQ_F16_MF8 : VInst<"vdot_laneq_f16_mf8_fpm", "(>F)(>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_7, 0>]>; +} + +let ArchGuard = "defined(__aarch64__)", TargetGuard = "fp8dot4,neon" in { + def VDOT_F32_MF8 : VInst<"vdot_f32_mf8_fpm", "(>>F)(>>F)..V", "mQm">; + + def VDOT_LANE_F32_MF8 : VInst<"vdot_lane_f32_mf8_fpm", "(>>F)(>>F)..IV", "m", [ImmCheck<3, ImmCheck0_1, 0>]>; + def VDOT_LANEQ_F32_MF8 : VInst<"vdot_laneq_f32_mf8_fpm", "(>>F)(>>F).QIV", "m", [ImmCheck<3, ImmCheck0_3, 0>]>; + + def VDOTQ_LANE_F32_MF8 : VInst<"vdot_lane_f32_mf8_fpm", "(>>F)(>>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_1, 0>]>; + def VDOTQ_LANEQ_F32_MF8 : VInst<"vdot_laneq_f32_mf8_fpm", "(>>F)(>>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_3, 0>]>; +} + +let ArchGuard = "defined(__aarch64__)", TargetGuard = "fp8fma,neon" in { + def VMLALB_F16_F8 : VInst<"vmlalb_f16_mf8_fpm", "(>F)(>F)..V", "Qm">; + def VMLALT_F16_F8 : VInst<"vmlalt_f16_mf8_fpm", "(>F)(>F)..V", "Qm">; + + def VMLALLBB_F32_F8 : VInst<"vmlallbb_f32_mf8_fpm", "(>>F)(>>F)..V", "Qm">; + def VMLALLBT_F32_F8 : VInst<"vmlallbt_f32_mf8_fpm", "(>>F)(>>F)..V", "Qm">; + def VMLALLTB_F32_F8 : VInst<"vmlalltb_f32_mf8_fpm", "(>>F)(>>F)..V", "Qm">; + def VMLALLTT_F32_F8 : VInst<"vmlalltt_f32_mf8_fpm", "(>>F)(>>F)..V", "Qm">; + + def VMLALB_F16_F8_LANE : VInst<"vmlalb_lane_f16_mf8_fpm", "(>F)(>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_7, 0>]>; + def VMLALB_F16_F8_LANEQ : VInst<"vmlalb_laneq_f16_mf8_fpm", "(>F)(>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_15, 0>]>; + def VMLALT_F16_F8_LANE : VInst<"vmlalt_lane_f16_mf8_fpm", "(>F)(>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_7, 0>]>; + def VMLALT_F16_F8_LANEQ : VInst<"vmlalt_laneq_f16_mf8_fpm", "(>F)(>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_15, 0>]>; + + def VMLALLBB_F32_F8_LANE : VInst<"vmlallbb_lane_f32_mf8_fpm", "(>>F)(>>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_7, 0>]>; + def VMLALLBB_F32_F8_LANEQ : VInst<"vmlallbb_laneq_f32_mf8_fpm", "(>>F)(>>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_15, 0>]>; + def VMLALLBT_F32_F8_LANE : VInst<"vmlallbt_lane_f32_mf8_fpm", "(>>F)(>>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_7, 0>]>; + def VMLALLBT_F32_F8_LANEQ : VInst<"vmlallbt_laneq_f32_mf8_fpm", "(>>F)(>>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_15, 0>]>; + def VMLALLTB_F32_F8_LANE : VInst<"vmlalltb_lane_f32_mf8_fpm", "(>>F)(>>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_7, 0>]>; + def VMLALLTB_F32_F8_LANEQ : VInst<"vmlalltb_laneq_f32_mf8_fpm", "(>>F)(>>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_15, 0>]>; + def VMLALLTT_F32_F8_LANE : VInst<"vmlalltt_lane_f32_mf8_fpm", "(>>F)(>>F).qIV", "Qm", [ImmCheck<3, ImmCheck0_7, 0>]>; + def VMLALLTT_F32_F8_LANEQ : VInst<"vmlalltt_laneq_f32_mf8_fpm", "(>>F)(>>F)..IV", "Qm", [ImmCheck<3, ImmCheck0_15, 0>]>; +} + let ArchGuard = "defined(__aarch64__)", TargetGuard = "neon,faminmax" in { def FAMIN : WInst<"vamin", "...", "fhQdQfQh">; def FAMAX : WInst<"vamax", "...", "fhQdQfQh">; diff --git a/clang/include/clang/Basic/arm_neon_incl.td b/clang/include/clang/Basic/arm_neon_incl.td index fd800e5a6278e..b9b9d509c2251 100644 --- a/clang/include/clang/Basic/arm_neon_incl.td +++ b/clang/include/clang/Basic/arm_neon_incl.td @@ -243,6 +243,7 @@ def OP_UNAVAILABLE : Operation { // B: change to BFloat16 // P: change to polynomial category. // p: change polynomial to equivalent integer category. Otherwise nop. +// V: change to fpm_t // // >: double element width (vector size unchanged). // <: half element width (vector size unchanged). @@ -301,6 +302,7 @@ class Inst ch = []>{ class SInst ch = []> : Inst {} class IInst ch = []> : Inst {} class WInst ch = []> : Inst {} +class VInst ch = []> : Inst {} // The following instruction classes are implemented via operators // instead of builtins. As such these declarations are only used for diff --git a/clang/include/clang/Basic/arm_sme.td b/clang/include/clang/Basic/arm_sme.td index 891ed9874bb3d..288a8c04c217f 100644 --- a/clang/include/clang/Basic/arm_sme.td +++ b/clang/include/clang/Basic/arm_sme.td @@ -110,11 +110,11 @@ multiclass ZARead ch> } } -defm SVREAD_ZA8 : ZARead<"za8", "cUc", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_0>]>; +defm SVREAD_ZA8 : ZARead<"za8", "cUcm", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_0>]>; defm SVREAD_ZA16 : ZARead<"za16", "sUshb", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_1>]>; defm SVREAD_ZA32 : ZARead<"za32", "iUif", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_3>]>; defm SVREAD_ZA64 : ZARead<"za64", "lUld", "aarch64_sme_read", [ImmCheck<2, ImmCheck0_7>]>; -defm SVREAD_ZA128 : ZARead<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_readq", [ImmCheck<2, ImmCheck0_15>]>; +defm SVREAD_ZA128 : ZARead<"za128", "csilUcUsUiUlmhbfd", "aarch64_sme_readq", [ImmCheck<2, ImmCheck0_15>]>; //////////////////////////////////////////////////////////////////////////////// // Write horizontal/vertical ZA slices @@ -131,11 +131,11 @@ multiclass ZAWrite ch } } -defm SVWRITE_ZA8 : ZAWrite<"za8", "cUc", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>]>; +defm SVWRITE_ZA8 : ZAWrite<"za8", "cUcm", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>]>; defm SVWRITE_ZA16 : ZAWrite<"za16", "sUshb", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_1>]>; defm SVWRITE_ZA32 : ZAWrite<"za32", "iUif", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_3>]>; defm SVWRITE_ZA64 : ZAWrite<"za64", "lUld", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_7>]>; -defm SVWRITE_ZA128 : ZAWrite<"za128", "csilUcUsUiUlhbfd", "aarch64_sme_writeq", [ImmCheck<0, ImmCheck0_15>]>; +defm SVWRITE_ZA128 : ZAWrite<"za128", "csilUcUsUiUlmhbfd", "aarch64_sme_writeq", [ImmCheck<0, ImmCheck0_15>]>; //////////////////////////////////////////////////////////////////////////////// // SME - Zero @@ -350,7 +350,7 @@ multiclass ZAWrite_VG checks> { } let SMETargetGuard = "sme2" in { - defm SVWRITE_ZA8 : ZAWrite_VG<"za8", "cUc", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>]>; + defm SVWRITE_ZA8 : ZAWrite_VG<"za8", "cUcm", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_0>]>; defm SVWRITE_ZA16 : ZAWrite_VG<"za16", "sUshb", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_1>]>; defm SVWRITE_ZA32 : ZAWrite_VG<"za32", "iUif", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_3>]>; defm SVWRITE_ZA64 : ZAWrite_VG<"za64", "lUld", "aarch64_sme_write", [ImmCheck<0, ImmCheck0_7>]>; @@ -366,7 +366,7 @@ multiclass ZARead_VG checks> { } let SMETargetGuard = "sme2" in { - defm SVREAD_ZA8 : ZARead_VG<"za8", "cUc", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_0>]>; + defm SVREAD_ZA8 : ZARead_VG<"za8", "cUcm", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_0>]>; defm SVREAD_ZA16 : ZARead_VG<"za16", "sUshb", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_1>]>; defm SVREAD_ZA32 : ZARead_VG<"za32", "iUif", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_3>]>; defm SVREAD_ZA64 : ZARead_VG<"za64", "lUld", "aarch64_sme_read", [ImmCheck<0, ImmCheck0_7>]>; @@ -722,7 +722,7 @@ def IN_STREAMING_MODE : Inst<"__arm_in_streaming_mode", "sv", "Pc", MergeNone, // lookup table expand four contiguous registers // let SMETargetGuard = "sme2" in { - def SVLUTI2_LANE_ZT_X4 : Inst<"svluti2_lane_zt_{d}_x4", "4.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>; + def SVLUTI2_LANE_ZT_X4 : Inst<"svluti2_lane_zt_{d}_x4", "4.di[i", "cUcsUsiUimbhf", MergeNone, "aarch64_sme_luti2_lane_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>; def SVLUTI4_LANE_ZT_X4 : Inst<"svluti4_lane_zt_{d}_x4", "4.di[i", "sUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_1>]>; } @@ -730,16 +730,16 @@ let SMETargetGuard = "sme2" in { // lookup table expand one register // let SMETargetGuard = "sme2" in { - def SVLUTI2_LANE_ZT : Inst<"svluti2_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>; - def SVLUTI4_LANE_ZT : Inst<"svluti4_lane_zt_{d}", "di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>; + def SVLUTI2_LANE_ZT : Inst<"svluti2_lane_zt_{d}", "di[i", "cUcsUsiUimbhf", MergeNone, "aarch64_sme_luti2_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_15>]>; + def SVLUTI4_LANE_ZT : Inst<"svluti4_lane_zt_{d}", "di[i", "cUcsUsiUimbhf", MergeNone, "aarch64_sme_luti4_lane_zt", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>; } // // lookup table expand two contiguous registers // let SMETargetGuard = "sme2" in { - def SVLUTI2_LANE_ZT_X2 : Inst<"svluti2_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti2_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>; - def SVLUTI4_LANE_ZT_X2 : Inst<"svluti4_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>; + def SVLUTI2_LANE_ZT_X2 : Inst<"svluti2_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUimbhf", MergeNone, "aarch64_sme_luti2_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_7>]>; + def SVLUTI4_LANE_ZT_X2 : Inst<"svluti4_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUimbhf", MergeNone, "aarch64_sme_luti4_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>; } // @@ -748,30 +748,30 @@ let SMETargetGuard = "sme2" in { // FDOT let SMETargetGuard = "sme-f8f32" in { - def SVDOT_LANE_FP8_ZA32_VG1x2 : Inst<"svdot_lane_za32[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; - def SVDOT_LANE_FP8_ZA32_VG1x4 : Inst<"svdot_lane_za32[_mf8]_vg1x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; + def SVDOT_LANE_FP8_ZA32_VG1x2 : Inst<"svdot_lane_za32[_mf8]_vg1x2", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; + def SVDOT_LANE_FP8_ZA32_VG1x4 : Inst<"svdot_lane_za32[_mf8]_vg1x4", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; - def SVVDOTB_LANE_FP8_ZA32_VG1x4 : Inst<"svvdotb_lane_za32[_mf8]_vg1x4_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdotb_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>; - def SVVDOTT_LANE_FP8_ZA32_VG1x4 : Inst<"svvdott_lane_za32[_mf8]_vg1x4_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdott_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>; + def SVVDOTB_LANE_FP8_ZA32_VG1x4 : Inst<"svvdotb_lane_za32[_mf8]_vg1x4", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdotb_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>; + def SVVDOTT_LANE_FP8_ZA32_VG1x4 : Inst<"svvdott_lane_za32[_mf8]_vg1x4", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdott_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_3>]>; - def SVDOT_SINGLE_FP8_ZA32_VG1x2 : Inst<"svdot[_single]_za32[_mf8]_vg1x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVDOT_SINGLE_FP8_ZA32_VG1x4 : Inst<"svdot[_single]_za32[_mf8]_vg1x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_SINGLE_FP8_ZA32_VG1x2 : Inst<"svdot[_single]_za32[_mf8]_vg1x2", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x2", [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVDOT_SINGLE_FP8_ZA32_VG1x4 : Inst<"svdot[_single]_za32[_mf8]_vg1x4", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x4", [IsStreaming, IsInOutZA, IsOverloadNone], []>; - def SVDOT_MULTI_FP8_ZA32_VG1x2 : Inst<"svdot_za32[_mf8]_vg1x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVDOT_MULTI_FP8_ZA32_VG1x4 : Inst<"svdot_za32[_mf8]_vg1x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_MULTI_FP8_ZA32_VG1x2 : Inst<"svdot_za32[_mf8]_vg1x2", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x2", [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVDOT_MULTI_FP8_ZA32_VG1x4 : Inst<"svdot_za32[_mf8]_vg1x4", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x4", [IsStreaming, IsInOutZA, IsOverloadNone], []>; } let SMETargetGuard = "sme-f8f16" in { - def SVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svdot_lane_za16[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; - def SVDOT_LANE_FP8_ZA16_VG1x4 : Inst<"svdot_lane_za16[_mf8]_vg1x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; + def SVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svdot_lane_za16[_mf8]_vg1x2", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x2", [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; + def SVDOT_LANE_FP8_ZA16_VG1x4 : Inst<"svdot_lane_za16[_mf8]_vg1x4", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x4", [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; - def SVVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svvdot_lane_za16[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdot_lane_za16_vg1x2", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; + def SVVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svvdot_lane_za16[_mf8]_vg1x2", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdot_lane_za16_vg1x2", [IsOverloadNone, IsStreaming, IsInOutZA], [ImmCheck<3, ImmCheck0_7>]>; - def SVDOT_SINGLE_FP8_ZA16_VG1x2 : Inst<"svdot[_single]_za16[_mf8]_vg1x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVDOT_SINGLE_FP8_ZA16_VG1x4 : Inst<"svdot[_single]_za16[_mf8]_vg1x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_SINGLE_FP8_ZA16_VG1x2 : Inst<"svdot[_single]_za16[_mf8]_vg1x2", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x2", [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVDOT_SINGLE_FP8_ZA16_VG1x4 : Inst<"svdot[_single]_za16[_mf8]_vg1x4", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x4", [IsStreaming, IsInOutZA, IsOverloadNone], []>; - def SVDOT_MULTI_FP8_ZA16_VG1x2 : Inst<"svdot_za16[_mf8]_vg1x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVDOT_MULTI_FP8_ZA16_VG1x4 : Inst<"svdot_za16[_mf8]_vg1x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_MULTI_FP8_ZA16_VG1x2 : Inst<"svdot_za16[_mf8]_vg1x2", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x2", [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVDOT_MULTI_FP8_ZA16_VG1x4 : Inst<"svdot_za16[_mf8]_vg1x4", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x4", [IsStreaming, IsInOutZA, IsOverloadNone], []>; } //////////////////////////////////////////////////////////////////////////////// @@ -811,12 +811,12 @@ multiclass ZAReadz]>; +defm SVREADZ_ZA8_X2 : ZAReadz<"za8", "2", "cUcm", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_0>]>; defm SVREADZ_ZA16_X2 : ZAReadz<"za16", "2", "sUshb", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_1>]>; defm SVREADZ_ZA32_X2 : ZAReadz<"za32", "2", "iUif", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_3>]>; defm SVREADZ_ZA64_X2 : ZAReadz<"za64", "2", "lUld", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_7>]>; -defm SVREADZ_ZA8_X4 : ZAReadz<"za8", "4", "cUc", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_0>]>; +defm SVREADZ_ZA8_X4 : ZAReadz<"za8", "4", "cUcm", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_0>]>; defm SVREADZ_ZA16_X4 : ZAReadz<"za16", "4", "sUshb", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_1>]>; defm SVREADZ_ZA32_X4 : ZAReadz<"za32", "4", "iUif", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_3>]>; defm SVREADZ_ZA64_X4 : ZAReadz<"za64", "4", "lUld", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_7>]>; @@ -834,15 +834,15 @@ multiclass ZAReadzSingle]>; +defm SVREADZ_ZA8 : ZAReadzSingle<"za8", "cUcm", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_0>]>; defm SVREADZ_ZA16 : ZAReadzSingle<"za16", "sUshb", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_1>]>; defm SVREADZ_ZA32 : ZAReadzSingle<"za32", "iUif", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_3>]>; defm SVREADZ_ZA64 : ZAReadzSingle<"za64", "lUld", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_7>]>; -defm SVREADZ_ZA128 : ZAReadzSingle<"za128", "csilUcUiUsUlbhfd", "aarch64_sme_readz_q", [ImmCheck<0, ImmCheck0_15>]>; +defm SVREADZ_ZA128 : ZAReadzSingle<"za128", "csilUcUiUsUlmbhfd", "aarch64_sme_readz_q", [ImmCheck<0, ImmCheck0_15>]>; multiclass ZAReadzArray{ let SMETargetGuard = "sme2p1" in { - def NAME # _B : SInst<"svreadz_za8_{d}_vg1x" # vg_num, vg_num # "m", "cUc", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>; + def NAME # _B : SInst<"svreadz_za8_{d}_vg1x" # vg_num, vg_num # "m", "cUcm", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>; def NAME # _H : SInst<"svreadz_za16_{d}_vg1x" # vg_num, vg_num # "m", "sUsbh", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>; def NAME # _S : SInst<"svreadz_za32_{d}_vg1x" # vg_num, vg_num # "m", "iUif", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>; def NAME # _D : SInst<"svreadz_za64_{d}_vg1x" # vg_num, vg_num # "m", "lUld", MergeNone, "aarch64_sme_readz_x" # vg_num, [IsStreaming, IsInOutZA]>; @@ -859,51 +859,51 @@ let SMETargetGuard = "sme-lutv2" in { } let SMETargetGuard = "sme-f8f32" in { - def SVMOPA_FP8_ZA32 : Inst<"svmopa_za32[_mf8]_m_fpm", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za32", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<0, ImmCheck0_3>]>; + def SVMOPA_FP8_ZA32 : Inst<"svmopa_za32[_mf8]_m", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za32", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<0, ImmCheck0_3>]>; // FMLALL (indexed) - def SVMLA_FP8_LANE_ZA32_VG4x1 : Inst<"svmla_lane_za32[_mf8]_vg4x1_fpm", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x1", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; - def SVMLA_FP8_LANE_ZA32_VG4x2 : Inst<"svmla_lane_za32[_mf8]_vg4x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x2", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; - def SVMLA_FP8_LANE_ZA16_VG4x4 : Inst<"svmla_lane_za32[_mf8]_vg4x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x4", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_LANE_ZA32_VG4x1 : Inst<"svmla_lane_za32[_mf8]_vg4x1", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x1", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_LANE_ZA32_VG4x2 : Inst<"svmla_lane_za32[_mf8]_vg4x2", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x2", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_LANE_ZA16_VG4x4 : Inst<"svmla_lane_za32[_mf8]_vg4x4", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x4", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; // FMLALL (single) - def SVMLA_FP8_SINGLE_ZA32_VG4x1 : Inst<"svmla[_single]_za32[_mf8]_vg4x1_fpm", "vmdd>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x1", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVMLA_FP8_SINGLE_ZA32_VG4x2 : Inst<"svmla[_single]_za32[_mf8]_vg4x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x2", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVMLA_FP8_SINGLE_ZA32_VG4x4 : Inst<"svmla[_single]_za32[_mf8]_vg4x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x4", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVMLA_FP8_SINGLE_ZA32_VG4x1 : Inst<"svmla[_single]_za32[_mf8]_vg4x1", "vmdd>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x1", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVMLA_FP8_SINGLE_ZA32_VG4x2 : Inst<"svmla[_single]_za32[_mf8]_vg4x2", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x2", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVMLA_FP8_SINGLE_ZA32_VG4x4 : Inst<"svmla[_single]_za32[_mf8]_vg4x4", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fmlall_single_za32_vg4x4", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; // FMLALL (multiple) - def SVMLA_FP8_MULTI_ZA32_VG4x2 : Inst<"svmla_za32[_mf8]_vg4x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fmlall_multi_za32_vg4x2", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVMLA_FP8_MULTI_ZA32_VG4x4 : Inst<"svmla_za32[_mf8]_vg4x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fmlall_multi_za32_vg4x4", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVMLA_FP8_MULTI_ZA32_VG4x2 : Inst<"svmla_za32[_mf8]_vg4x2", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fmlall_multi_za32_vg4x2", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVMLA_FP8_MULTI_ZA32_VG4x4 : Inst<"svmla_za32[_mf8]_vg4x4", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fmlall_multi_za32_vg4x4", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; } let SMETargetGuard = "sme-f8f16" in { - def SVMOPA_FP8_ZA16 : Inst<"svmopa_za16[_mf8]_m_fpm", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za16", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<0, ImmCheck0_1>]>; + def SVMOPA_FP8_ZA16 : Inst<"svmopa_za16[_mf8]_m", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za16", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<0, ImmCheck0_1>]>; // FMLAL (indexed) - def SVMLA_FP8_LANE_ZA16_VG2x1 : Inst<"svmla_lane_za16[_mf8]_vg2x1_fpm", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x1", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; - def SVMLA_FP8_LANE_ZA16_VG2x2 : Inst<"svmla_lane_za16[_mf8]_vg2x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x2", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; - def SVMLA_FP8_LANE_ZA16_VG2x4 : Inst<"svmla_lane_za16[_mf8]_vg2x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x4", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_LANE_ZA16_VG2x1 : Inst<"svmla_lane_za16[_mf8]_vg2x1", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x1", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_LANE_ZA16_VG2x2 : Inst<"svmla_lane_za16[_mf8]_vg2x2", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x2", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_LANE_ZA16_VG2x4 : Inst<"svmla_lane_za16[_mf8]_vg2x4", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x4", + [IsStreaming, IsInOutZA, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; // FMLAL (single) - def SVMLA_FP8_SINGLE_ZA16_VG2x1 : Inst<"svmla[_single]_za16[_mf8]_vg2x1_fpm", "vmdd>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x1", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVMLA_FP8_SINGLE_ZA16_VG2x2 : Inst<"svmla[_single]_za16[_mf8]_vg2x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x2", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVMLA_FP8_SINGLE_ZA16_VG2x4 : Inst<"svmla[_single]_za16[_mf8]_vg2x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x4", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVMLA_FP8_SINGLE_ZA16_VG2x1 : Inst<"svmla[_single]_za16[_mf8]_vg2x1", "vmdd>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x1", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVMLA_FP8_SINGLE_ZA16_VG2x2 : Inst<"svmla[_single]_za16[_mf8]_vg2x2", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x2", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVMLA_FP8_SINGLE_ZA16_VG2x4 : Inst<"svmla[_single]_za16[_mf8]_vg2x4", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fmlal_single_za16_vg2x4", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; // FMLAL (multiple) - def SVMLA_FP8_MULTI_ZA16_VG2x2 : Inst<"svmla_za16[_mf8]_vg2x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fmlal_multi_za16_vg2x2", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; - def SVMLA_FP8_MULTI_ZA16_VG2x4 : Inst<"svmla_za16[_mf8]_vg2x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fmlal_multi_za16_vg2x4", - [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVMLA_FP8_MULTI_ZA16_VG2x2 : Inst<"svmla_za16[_mf8]_vg2x2", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fmlal_multi_za16_vg2x2", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; + def SVMLA_FP8_MULTI_ZA16_VG2x4 : Inst<"svmla_za16[_mf8]_vg2x4", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fmlal_multi_za16_vg2x4", + [IsStreaming, IsInOutZA, IsOverloadNone], []>; } } // let SVETargetGuard = InvalidMode diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index e7001bac450e8..b20383e72e66a 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -2104,7 +2104,7 @@ let SVETargetGuard = "sve2p1", SMETargetGuard = "sme" in { def SVSCLAMP : SInst<"svclamp[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sclamp", [VerifyRuntimeMode], []>; def SVUCLAMP : SInst<"svclamp[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp", [VerifyRuntimeMode], []>; -defm SVREVD : SInstZPZ<"svrevd", "csilUcUsUiUlbhfd", "aarch64_sve_revd">; +defm SVREVD : SInstZPZ<"svrevd", "csilUcUsUiUlmbhfd", "aarch64_sve_revd">; } let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in { @@ -2223,8 +2223,8 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in { def SVADD_SINGLE_X4 : SInst<"svadd[_single_{d}_x4]", "44d", "cUcsUsiUilUl", MergeNone, "aarch64_sve_add_single_x4", [IsStreaming], []>; // 2-way and 4-way selects - def SVSEL_X2 : SInst<"svsel[_{d}_x2]", "2}22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_sel_x2", [IsStreaming], []>; - def SVSEL_X4 : SInst<"svsel[_{d}_x4]", "4}44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_sel_x4", [IsStreaming], []>; + def SVSEL_X2 : SInst<"svsel[_{d}_x2]", "2}22", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_sel_x2", [IsStreaming], []>; + def SVSEL_X4 : SInst<"svsel[_{d}_x4]", "4}44", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_sel_x4", [IsStreaming], []>; // SRSHL / URSHL def SVSRSHL_SINGLE_X2 : SInst<"svrshl[_single_{d}_x2]", "22d", "csil", MergeNone, "aarch64_sve_srshl_single_x2", [IsStreaming], []>; @@ -2402,15 +2402,15 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in { // let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2" in { - def SVZIP_X2 : SInst<"svzip[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zip_x2", [IsStreaming], []>; - def SVZIPQ_X2 : SInst<"svzipq[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq_x2", [IsStreaming], []>; - def SVZIP_X4 : SInst<"svzip[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zip_x4", [IsStreaming], []>; - def SVZIPQ_X4 : SInst<"svzipq[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_zipq_x4", [IsStreaming], []>; + def SVZIP_X2 : SInst<"svzip[_{d}_x2]", "22", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_zip_x2", [IsStreaming], []>; + def SVZIPQ_X2 : SInst<"svzipq[_{d}_x2]", "22", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_zipq_x2", [IsStreaming], []>; + def SVZIP_X4 : SInst<"svzip[_{d}_x4]", "44", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_zip_x4", [IsStreaming], []>; + def SVZIPQ_X4 : SInst<"svzipq[_{d}_x4]", "44", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_zipq_x4", [IsStreaming], []>; - def SVUZP_X2 : SInst<"svuzp[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzp_x2", [IsStreaming], []>; - def SVUZPQ_X2 : SInst<"svuzpq[_{d}_x2]", "22", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq_x2", [IsStreaming], []>; - def SVUZP_X4 : SInst<"svuzp[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzp_x4", [IsStreaming], []>; - def SVUZPQ_X4 : SInst<"svuzpq[_{d}_x4]", "44", "cUcsUsiUilUlbhfd", MergeNone, "aarch64_sve_uzpq_x4", [IsStreaming], []>; + def SVUZP_X2 : SInst<"svuzp[_{d}_x2]", "22", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_uzp_x2", [IsStreaming], []>; + def SVUZPQ_X2 : SInst<"svuzpq[_{d}_x2]", "22", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_uzpq_x2", [IsStreaming], []>; + def SVUZP_X4 : SInst<"svuzp[_{d}_x4]", "44", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_uzp_x4", [IsStreaming], []>; + def SVUZPQ_X4 : SInst<"svuzpq[_{d}_x4]", "44", "cUcsUsiUilUlmbhfd", MergeNone, "aarch64_sve_uzpq_x4", [IsStreaming], []>; } // @@ -2432,18 +2432,18 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,fp8" in { def FSCALE_X4 : Inst<"svscale[_{d}_x4]", "444.x", "fhd", MergeNone, "aarch64_sme_fp8_scale_x4", [IsStreaming],[]>; // Convert from FP8 to half-precision/BFloat16 multi-vector - def SVF1CVT_X2 : Inst<"svcvt1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1_x2", [IsStreaming, SetsFPMR], []>; - def SVF2CVT_X2 : Inst<"svcvt2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2_x2", [IsStreaming, SetsFPMR], []>; + def SVF1CVT_X2 : Inst<"svcvt1_{d}[_mf8]_x2", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1_x2", [IsStreaming], []>; + def SVF2CVT_X2 : Inst<"svcvt2_{d}[_mf8]_x2", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2_x2", [IsStreaming], []>; // Convert from FP8 to deinterleaved half-precision/BFloat16 multi-vector - def SVF1CVTL_X2 : Inst<"svcvtl1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl1_x2", [IsStreaming, SetsFPMR], []>; - def SVF2CVTL_X2 : Inst<"svcvtl2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl2_x2", [IsStreaming, SetsFPMR], []>; + def SVF1CVTL_X2 : Inst<"svcvtl1_{d}[_mf8]_x2", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl1_x2", [IsStreaming], []>; + def SVF2CVTL_X2 : Inst<"svcvtl2_{d}[_mf8]_x2", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl2_x2", [IsStreaming], []>; // Convert from single/half/bfloat multivector to FP8 - def SVFCVT_X2 : Inst<"svcvt_mf8[_{d}_x2]_fpm", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvt_x2", [IsStreaming, SetsFPMR], []>; - def SVFCVT_X4 : Inst<"svcvt_mf8[_{d}_x4]_fpm", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvt_x4", [IsOverloadNone, IsStreaming, SetsFPMR], []>; + def SVFCVT_X2 : Inst<"svcvt_mf8[_{d}_x2]", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvt_x2", [IsStreaming], []>; + def SVFCVT_X4 : Inst<"svcvt_mf8[_{d}_x4]", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvt_x4", [IsOverloadNone, IsStreaming], []>; // interleaved - def SVFCVTN_X4 : Inst<"svcvtn_mf8[_{d}_x4]_fpm", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvtn_x4", [IsOverloadNone, IsStreaming, SetsFPMR], []>; + def SVFCVTN_X4 : Inst<"svcvtn_mf8[_{d}_x4]", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvtn_x4", [IsOverloadNone, IsStreaming], []>; } let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in { @@ -2464,67 +2464,67 @@ let SVETargetGuard = "sve2,fp8", SMETargetGuard = "sme2,fp8" in { // SVE FP8 widening conversions // 8-bit floating-point convert to BFloat16/Float16 - def SVF1CVT : SInst<"svcvt1_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1", [VerifyRuntimeMode, SetsFPMR]>; - def SVF2CVT : SInst<"svcvt2_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2", [VerifyRuntimeMode, SetsFPMR]>; + def SVF1CVT : SInst<"svcvt1_{d}[_mf8]", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1", [VerifyRuntimeMode]>; + def SVF2CVT : SInst<"svcvt2_{d}[_mf8]", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2", [VerifyRuntimeMode]>; // 8-bit floating-point convert to BFloat16/Float16 (top) - def SVF1CVTLT : SInst<"svcvtlt1_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt1", [VerifyRuntimeMode, SetsFPMR]>; - def SVF2CVTLT : SInst<"svcvtlt2_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt2", [VerifyRuntimeMode, SetsFPMR]>; + def SVF1CVTLT : SInst<"svcvtlt1_{d}[_mf8]", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt1", [VerifyRuntimeMode]>; + def SVF2CVTLT : SInst<"svcvtlt2_{d}[_mf8]", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt2", [VerifyRuntimeMode]>; // BFloat16/Float16 convert, narrow and interleave to 8-bit floating-point - def SVFCVTN : SInst<"svcvtn_mf8[_{d}_x2]_fpm", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvtn", [VerifyRuntimeMode, SetsFPMR]>; + def SVFCVTN : SInst<"svcvtn_mf8[_{d}_x2]", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvtn", [VerifyRuntimeMode]>; // Single-precision convert, narrow and interleave to 8-bit floating-point (top and bottom) - def SVFCVTNB : SInst<"svcvtnb_mf8[_f32_x2]_fpm", "~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnb", [VerifyRuntimeMode, SetsFPMR]>; - def SVFCVTNT : SInst<"svcvtnt_mf8[_f32_x2]_fpm", "~~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnt", [VerifyRuntimeMode, SetsFPMR]>; + def SVFCVTNB : SInst<"svcvtnb_mf8[_f32_x2]", "~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnb", [VerifyRuntimeMode]>; + def SVFCVTNT : SInst<"svcvtnt_mf8[_f32_x2]", "~~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnt", [VerifyRuntimeMode]>; } let SVETargetGuard = "sve2,fp8dot2", SMETargetGuard ="sme,ssve-fp8dot2" in { // 8-bit floating-point dot product to half-precision (vectors) - def SVFDOT_2WAY : SInst<"svdot[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; - def SVFDOT_N_2WAY : SInst<"svdot[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; + def SVFDOT_2WAY : SInst<"svdot[_f16_mf8]", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode]>; + def SVFDOT_N_2WAY : SInst<"svdot[_n_f16_mf8]", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode]>; // 8-bit floating-point dot product to half-precision (indexed) - def SVFDOT_LANE_2WAY : SInst<"svdot_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; + def SVFDOT_LANE_2WAY : SInst<"svdot_lane[_f16_mf8]", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; } let SVETargetGuard = "sve2,fp8dot4", SMETargetGuard ="sme,ssve-fp8dot4" in { // 8-bit floating-point dot product to single-precision (vectors) - def SVFDOT_4WAY : SInst<"svdot[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; - def SVFDOT_N_4WAY : SInst<"svdot[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; + def SVFDOT_4WAY : SInst<"svdot[_f32_mf8]", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode]>; + def SVFDOT_N_4WAY : SInst<"svdot[_n_f32_mf8]", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode]>; // 8-bit floating-point dot product to single-precision (indexed) - def SVFDOT_LANE_4WAY : SInst<"svdot_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>; + def SVFDOT_LANE_4WAY : SInst<"svdot_lane[_f32_mf8]", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_3>]>; } let SVETargetGuard = "sve2,fp8fma", SMETargetGuard = "sme,ssve-fp8fma" in { // 8-bit floating-point multiply-add long to half-precision (bottom) - def SVFMLALB : SInst<"svmlalb[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALB_N : SInst<"svmlalb[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALB : SInst<"svmlalb[_f16_mf8]", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode]>; + def SVFMLALB_N : SInst<"svmlalb[_n_f16_mf8]", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode]>; - // 8-bit floating-point multiply-add long to ha_fpmlf-precision (bottom, indexed) - def SVFMLALB_LANE : SInst<"svmlalb_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_15>]>; + // 8-bit floating-point multiply-add long to half-precision (bottom, indexed) + def SVFMLALB_LANE : SInst<"svmlalb_lane[_f16_mf8]", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalb_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_15>]>; // 8-bit floating-point multiply-add long to half-precision (top) - def SVFMLALT : SInst<"svmlalt[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALT_N : SInst<"svmlalt[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALT : SInst<"svmlalt[_f16_mf8]", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode]>; + def SVFMLALT_N : SInst<"svmlalt[_n_f16_mf8]", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode]>; // 8-bit floating-point multiply-add long to half-precision (top, indexed) - def SVFMLALT_LANE : SInst<"svmlalt_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_15>]>; + def SVFMLALT_LANE : SInst<"svmlalt_lane[_f16_mf8]", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalt_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_15>]>; // 8-bit floating-point multiply-add long long to single-precision (all top/bottom variants) - def SVFMLALLBB : SInst<"svmlallbb[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALLBB_N : SInst<"svmlallbb[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALLBT : SInst<"svmlallbt[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALLBT_N : SInst<"svmlallbt[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALLTB : SInst<"svmlalltb[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALLTB_N : SInst<"svmlalltb[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALLTT : SInst<"svmlalltt[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode, SetsFPMR]>; - def SVFMLALLTT_N : SInst<"svmlalltt[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLBB : SInst<"svmlallbb[_f32_mf8]", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode]>; + def SVFMLALLBB_N : SInst<"svmlallbb[_n_f32_mf8]", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode]>; + def SVFMLALLBT : SInst<"svmlallbt[_f32_mf8]", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode]>; + def SVFMLALLBT_N : SInst<"svmlallbt[_n_f32_mf8]", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode]>; + def SVFMLALLTB : SInst<"svmlalltb[_f32_mf8]", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode]>; + def SVFMLALLTB_N : SInst<"svmlalltb[_n_f32_mf8]", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode]>; + def SVFMLALLTT : SInst<"svmlalltt[_f32_mf8]", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode]>; + def SVFMLALLTT_N : SInst<"svmlalltt[_n_f32_mf8]", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode]>; // 8-bit floating-point multiply-add long long to single-precision (indexed, all top/bottom variants) - def SVFMLALLBB_LANE : SInst<"svmlallbb_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; - def SVFMLALLBT_LANE : SInst<"svmlallbt_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; - def SVFMLALLTB_LANE : SInst<"svmlalltb_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; - def SVFMLALLTT_LANE : SInst<"svmlalltt_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; + def SVFMLALLBB_LANE : SInst<"svmlallbb_lane[_f32_mf8]", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; + def SVFMLALLBT_LANE : SInst<"svmlallbt_lane[_f32_mf8]", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; + def SVFMLALLTB_LANE : SInst<"svmlalltb_lane[_f32_mf8]", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; + def SVFMLALLTT_LANE : SInst<"svmlalltt_lane[_f32_mf8]", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt_lane", [VerifyRuntimeMode], [ImmCheck<3, ImmCheck0_7>]>; } diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrVisitor.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrVisitor.h new file mode 100644 index 0000000000000..bbba89cb7e3fd --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrVisitor.h @@ -0,0 +1,52 @@ +//===- CIRAttrVisitor.h - Visitor for CIR attributes ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the CirAttrVisitor interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRATTRVISITOR_H +#define LLVM_CLANG_CIR_DIALECT_IR_CIRATTRVISITOR_H + +#include "clang/CIR/Dialect/IR/CIRAttrs.h" + +namespace cir { + +template class CirAttrVisitor { +public: + // FIXME: Create a TableGen list to automatically handle new attributes + RetTy visit(mlir::Attribute attr) { + if (const auto intAttr = mlir::dyn_cast(attr)) + return getImpl().visitCirIntAttr(intAttr); + if (const auto fltAttr = mlir::dyn_cast(attr)) + return getImpl().visitCirFPAttr(fltAttr); + if (const auto ptrAttr = mlir::dyn_cast(attr)) + return getImpl().visitCirConstPtrAttr(ptrAttr); + llvm_unreachable("unhandled attribute type"); + } + + // If the implementation chooses not to implement a certain visit + // method, fall back to the parent. + RetTy visitCirIntAttr(cir::IntAttr attr) { + return getImpl().visitCirAttr(attr); + } + RetTy visitCirFPAttr(cir::FPAttr attr) { + return getImpl().visitCirAttr(attr); + } + RetTy visitCirConstPtrAttr(cir::ConstPtrAttr attr) { + return getImpl().visitCirAttr(attr); + } + + RetTy visitCirAttr(mlir::Attribute attr) { return RetTy(); } + + ImplClass &getImpl() { return *static_cast(this); } +}; + +} // namespace cir + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRATTRVISITOR_H diff --git a/clang/include/clang/CIR/FrontendAction/.clang-tidy b/clang/include/clang/CIR/FrontendAction/.clang-tidy new file mode 100644 index 0000000000000..1a5dfe1418063 --- /dev/null +++ b/clang/include/clang/CIR/FrontendAction/.clang-tidy @@ -0,0 +1,68 @@ +InheritParentConfig: true +Checks: > + -misc-const-correctness, + -llvm-header-guard, + bugprone-argument-comment, + bugprone-assert-side-effect, + bugprone-branch-clone, + bugprone-copy-constructor-init, + bugprone-dangling-handle, + bugprone-dynamic-static-initializers, + bugprone-macro-parentheses, + bugprone-macro-repeated-side-effects, + bugprone-misplaced-widening-cast, + bugprone-move-forwarding-reference, + bugprone-multiple-statement-macro, + bugprone-suspicious-semicolon, + bugprone-swapped-arguments, + bugprone-terminating-continue, + bugprone-unused-raii, + bugprone-unused-return-value, + misc-redundant-expression, + misc-static-assert, + misc-unused-using-decls, + modernize-use-bool-literals, + modernize-loop-convert, + modernize-make-unique, + modernize-raw-string-literal, + modernize-use-equals-default, + modernize-use-default-member-init, + modernize-use-emplace, + modernize-use-nullptr, + modernize-use-override, + modernize-use-using, + performance-for-range-copy, + performance-implicit-conversion-in-loop, + performance-inefficient-algorithm, + performance-inefficient-vector-operation, + performance-move-const-arg, + performance-no-automatic-move, + performance-trivially-destructible, + performance-unnecessary-copy-initialization, + performance-unnecessary-value-param, + readability-avoid-const-params-in-decls, + readability-const-return-type, + readability-container-size-empty, + readability-identifier-naming, + readability-inconsistent-declaration-parameter-name, + readability-misleading-indentation, + readability-redundant-control-flow, + readability-redundant-smartptr-get, + readability-simplify-boolean-expr, + readability-simplify-subscript-expr, + readability-use-anyofallof +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: camelBack + - key: readability-identifier-naming.MemberCase + value: CamelCase + - key: readability-identifier-naming.ParameterCase + value: CamelCase + - key: readability-identifier-naming.UnionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: CamelCase diff --git a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h index 2ab612613b73d..5f9110bc83b89 100644 --- a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h +++ b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h @@ -26,6 +26,7 @@ class CIRGenAction : public clang::ASTFrontendAction { public: enum class OutputType { EmitCIR, + EmitLLVM, }; private: @@ -55,6 +56,13 @@ class EmitCIRAction : public CIRGenAction { EmitCIRAction(mlir::MLIRContext *MLIRCtx = nullptr); }; +class EmitLLVMAction : public CIRGenAction { + virtual void anchor(); + +public: + EmitLLVMAction(mlir::MLIRContext *MLIRCtx = nullptr); +}; + } // namespace cir #endif diff --git a/clang/include/clang/CIR/LowerToLLVM.h b/clang/include/clang/CIR/LowerToLLVM.h new file mode 100644 index 0000000000000..6e1b0270fcd2b --- /dev/null +++ b/clang/include/clang/CIR/LowerToLLVM.h @@ -0,0 +1,35 @@ +//====- LowerToLLVM.h- Lowering from CIR to LLVM --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares an interface for converting CIR modules to LLVM IR. +// +//===----------------------------------------------------------------------===// +#ifndef CLANG_CIR_LOWERTOLLVM_H +#define CLANG_CIR_LOWERTOLLVM_H + +#include + +namespace llvm { +class LLVMContext; +class Module; +} // namespace llvm + +namespace mlir { +class ModuleOp; +} // namespace mlir + +namespace cir { + +namespace direct { +std::unique_ptr +lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, + llvm::LLVMContext &llvmCtx); +} // namespace direct +} // namespace cir + +#endif // CLANG_CIR_LOWERTOLLVM_H diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h new file mode 100644 index 0000000000000..d4fcd52e7e6e3 --- /dev/null +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -0,0 +1,43 @@ +//===---- MissingFeatures.h - Checks for unimplemented features -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file introduces some helper classes to guard against features that +// CIR dialect supports that we do not have and also do not have great ways to +// assert against. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_CIR_MISSINGFEATURES_H +#define CLANG_CIR_MISSINGFEATURES_H + +namespace cir { + +// As a way to track features that haven't yet been implemented this class +// explicitly contains a list of static fns that will return false that you +// can guard against. If and when a feature becomes implemented simply changing +// this return to true will cause compilation to fail at all the points in which +// we noted that we needed to address. This is a much more explicit way to +// handle "TODO"s. +struct MissingFeatures { + // Address space related + static bool addressSpace() { return false; } + + // This isn't needed until we add support for bools. + static bool convertTypeForMemory() { return false; } + + // Unhandled global/linkage information. + static bool opGlobalDSOLocal() { return false; } + static bool opGlobalThreadLocal() { return false; } + static bool opGlobalConstant() { return false; } + static bool opGlobalAlignment() { return false; } + static bool opGlobalLinkage() { return false; } +}; + +} // namespace cir + +#endif // CLANG_CIR_MISSINGFEATURES_H diff --git a/clang/include/clang/CIRFrontendAction/.clang-tidy b/clang/include/clang/CIRFrontendAction/.clang-tidy deleted file mode 100644 index ef88dbcec488c..0000000000000 --- a/clang/include/clang/CIRFrontendAction/.clang-tidy +++ /dev/null @@ -1,53 +0,0 @@ -InheritParentConfig: true -Checks: > - -misc-const-correctness, - -llvm-header-guard, - bugprone-argument-comment, - bugprone-assert-side-effect, - bugprone-branch-clone, - bugprone-copy-constructor-init, - bugprone-dangling-handle, - bugprone-dynamic-static-initializers, - bugprone-macro-parentheses, - bugprone-macro-repeated-side-effects, - bugprone-misplaced-widening-cast, - bugprone-move-forwarding-reference, - bugprone-multiple-statement-macro, - bugprone-suspicious-semicolon, - bugprone-swapped-arguments, - bugprone-terminating-continue, - bugprone-unused-raii, - bugprone-unused-return-value, - misc-redundant-expression, - misc-static-assert, - misc-unused-using-decls, - modernize-use-bool-literals, - modernize-loop-convert, - modernize-make-unique, - modernize-raw-string-literal, - modernize-use-equals-default, - modernize-use-default-member-init, - modernize-use-emplace, - modernize-use-nullptr, - modernize-use-override, - modernize-use-using, - performance-for-range-copy, - performance-implicit-conversion-in-loop, - performance-inefficient-algorithm, - performance-inefficient-vector-operation, - performance-move-const-arg, - performance-no-automatic-move, - performance-trivially-destructible, - performance-unnecessary-copy-initialization, - performance-unnecessary-value-param, - readability-avoid-const-params-in-decls, - readability-const-return-type, - readability-container-size-empty, - readability-identifier-naming, - readability-inconsistent-declaration-parameter-name, - readability-misleading-indentation, - readability-redundant-control-flow, - readability-redundant-smartptr-get, - readability-simplify-boolean-expr, - readability-simplify-subscript-expr, - readability-use-anyofallof diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake index 27ed69e21562b..00c352b458c34 100644 --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -76,7 +76,6 @@ #cmakedefine01 PPC_LINUX_DEFAULT_IEEELONGDOUBLE /* Enable each functionality of modules */ -#cmakedefine01 CLANG_ENABLE_ARCMT #cmakedefine01 CLANG_ENABLE_OBJC_REWRITER #cmakedefine01 CLANG_ENABLE_STATIC_ANALYZER diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index feeabae89d6b1..e5307b0fcedd5 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -60,7 +60,6 @@ class Action { PrecompileJobClass, ExtractAPIJobClass, AnalyzeJobClass, - MigrateJobClass, CompileJobClass, BackendJobClass, AssembleJobClass, @@ -460,17 +459,6 @@ class AnalyzeJobAction : public JobAction { } }; -class MigrateJobAction : public JobAction { - void anchor() override; - -public: - MigrateJobAction(Action *Input, types::ID OutputType); - - static bool classof(const Action *A) { - return A->getKind() == MigrateJobClass; - } -}; - class CompileJobAction : public JobAction { void anchor() override; diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index f4a52cc529b79..b463dc2a93550 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -797,22 +797,14 @@ class Driver { const ToolChain &getToolChain(const llvm::opt::ArgList &Args, const llvm::Triple &Target) const; - /// @} - - /// Retrieves a ToolChain for a particular device \p Target triple - /// - /// \param[in] HostTC is the host ToolChain paired with the device - /// - /// \param[in] TargetDeviceOffloadKind (e.g. OFK_Cuda/OFK_OpenMP/OFK_SYCL) is - /// an Offloading action that is optionally passed to a ToolChain (used by - /// CUDA, to specify if it's used in conjunction with OpenMP) + /// Retrieves a ToolChain for a particular \p Target triple for offloading. /// /// Will cache ToolChains for the life of the driver object, and create them /// on-demand. - const ToolChain &getOffloadingDeviceToolChain( - const llvm::opt::ArgList &Args, const llvm::Triple &Target, - const ToolChain &HostTC, - const Action::OffloadKind &TargetDeviceOffloadKind) const; + const ToolChain &getOffloadToolChain(const llvm::opt::ArgList &Args, + const Action::OffloadKind Kind, + const llvm::Triple &Target, + const llvm::Triple &AuxTarget) const; /// Get bitmasks for which option flags to include and exclude based on /// the driver mode. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c5b7fcb7c7f09..1cf62ab466134 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -694,20 +694,6 @@ def ccc_print_phases : Flag<["-"], "ccc-print-phases">, def ccc_print_bindings : Flag<["-"], "ccc-print-bindings">, InternalDebugOpt, HelpText<"Show bindings of tools to actions">; -def ccc_arcmt_check : Flag<["-"], "ccc-arcmt-check">, InternalDriverOpt, - HelpText<"Check for ARC migration issues that need manual handling">; -def ccc_arcmt_modify : Flag<["-"], "ccc-arcmt-modify">, InternalDriverOpt, - HelpText<"Apply modifications to files to conform to ARC">; -def ccc_arcmt_migrate : Separate<["-"], "ccc-arcmt-migrate">, InternalDriverOpt, - HelpText<"Apply modifications and produces temporary files that conform to ARC">; -def arcmt_migrate_report_output : Separate<["-"], "arcmt-migrate-report-output">, - HelpText<"Output path for the plist report">, - Visibility<[ClangOption, CC1Option]>, - MarshallingInfoString>; -def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">, - HelpText<"Emit ARC errors even if the migrator can fix them">, - Visibility<[ClangOption, CC1Option]>, - MarshallingInfoFlag>; def gen_reproducer_eq: Joined<["-"], "gen-reproducer=">, Flags<[NoArgumentUnused]>, Visibility<[ClangOption, CLOption, DXCOption]>, HelpText<"Emit reproducer on (option: off, crash (default), error, always)">; @@ -723,87 +709,6 @@ def no_round_trip_args : Flag<["-"], "no-round-trip-args">, Visibility<[CC1Option]>, HelpText<"Disable command line arguments round-trip.">; -def _migrate : Flag<["--"], "migrate">, Flags<[NoXarchOption]>, - HelpText<"Run the migrator">; -def ccc_objcmt_migrate : Separate<["-"], "ccc-objcmt-migrate">, - InternalDriverOpt, - HelpText<"Apply modifications and produces temporary files to migrate to " - "modern ObjC syntax">; - -def objcmt_migrate_literals : Flag<["-"], "objcmt-migrate-literals">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC literals">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Literals">; -def objcmt_migrate_subscripting : Flag<["-"], "objcmt-migrate-subscripting">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC subscripting">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Subscripting">; -def objcmt_migrate_property : Flag<["-"], "objcmt-migrate-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC property">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Property">; -def objcmt_migrate_all : Flag<["-"], "objcmt-migrate-all">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_MigrateDecls">; -def objcmt_migrate_readonly_property : Flag<["-"], "objcmt-migrate-readonly-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC readonly property">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ReadonlyProperty">; -def objcmt_migrate_readwrite_property : Flag<["-"], "objcmt-migrate-readwrite-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to modern ObjC readwrite property">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ReadwriteProperty">; -def objcmt_migrate_property_dot_syntax : Flag<["-"], "objcmt-migrate-property-dot-syntax">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration of setter/getter messages to property-dot syntax">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_PropertyDotSyntax">; -def objcmt_migrate_annotation : Flag<["-"], "objcmt-migrate-annotation">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to property and method annotations">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Annotation">; -def objcmt_migrate_instancetype : Flag<["-"], "objcmt-migrate-instancetype">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to infer instancetype for method result type">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_Instancetype">; -def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_NsMacros">; -def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to add protocol conformance on classes">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ProtocolConformance">; -def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Make migration to 'atomic' properties">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_AtomicProperty">; -def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_ReturnsInnerPointerProperty">; -def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty">; -def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">, - MarshallingInfoBitfieldFlag, "FrontendOptions::ObjCMT_DesignatedInitializer">; - -def objcmt_allowlist_dir_path: Joined<["-"], "objcmt-allowlist-dir-path=">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Only modify files with a filename contained in the provided directory path">, - MarshallingInfoString>; -def : Joined<["-"], "objcmt-whitelist-dir-path=">, - Visibility<[ClangOption, CC1Option]>, - HelpText<"Alias for -objcmt-allowlist-dir-path">, - Alias; -// The misspelt "white-list" [sic] alias is due for removal. -def : Joined<["-"], "objcmt-white-list-dir-path=">, - Visibility<[ClangOption, CC1Option]>, - Alias; - // Make sure all other -ccc- options are rejected. def ccc_ : Joined<["-"], "ccc-">, Group, Flags<[Unsupported]>; @@ -1027,7 +932,9 @@ def W_Joined : Joined<["-"], "W">, Group, def Xanalyzer : Separate<["-"], "Xanalyzer">, HelpText<"Pass to the static analyzer">, MetaVarName<"">, Group; -def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[NoXarchOption]>; +def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[NoXarchOption]>, + HelpText<"Pass to the compiliation if the target matches ">, + MetaVarName<" ">; def Xarch_host : Separate<["-"], "Xarch_host">, Flags<[NoXarchOption]>, HelpText<"Pass to the CUDA/HIP host compilation">, MetaVarName<"">; def Xarch_device : Separate<["-"], "Xarch_device">, Flags<[NoXarchOption]>, @@ -1210,8 +1117,8 @@ def fno_convergent_functions : Flag<["-"], "fno-convergent-functions">, // Common offloading options let Group = offload_Group in { -def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[NoXarchOption]>, - Visibility<[ClangOption, FlangOption]>, +def offload_arch_EQ : Joined<["--"], "offload-arch=">, + Visibility<[ClangOption, FlangOption]>, Flags<[NoXarchOption]>, HelpText<"Specify an offloading device architecture for CUDA, HIP, or OpenMP. (e.g. sm_35). " "If 'native' is used the compiler will detect locally installed architectures. " "For HIP offloading, the device architecture can be followed by target ID features " @@ -1888,6 +1795,11 @@ def fprofile_update_EQ : Joined<["-"], "fprofile-update=">, Values<"atomic,prefer-atomic,single">, MetaVarName<"">, HelpText<"Set update method of profile counters">, MarshallingInfoFlag>; +def fprofile_continuous : Flag<["-"], "fprofile-continuous">, + Group, Visibility<[ClangOption, CC1Option]>, + HelpText<"Enable continuous instrumentation profiling mode">, + MarshallingInfoFlag>; + defm pseudo_probe_for_profiling : BoolFOption<"pseudo-probe-for-profiling", CodeGenOpts<"PseudoProbeForProfiling">, DefaultFalse, PosFlag, @@ -2619,6 +2531,10 @@ defm sanitize_cfi_canonical_jump_tables : BoolOption<"f", "sanitize-cfi-canonica "Do not make">, BothFlags<[], [ClangOption], " the jump table addresses canonical in the symbol table">>, Group; +def fsanitize_kcfi_arity : Flag<["-"], "fsanitize-kcfi-arity">, + Group, + HelpText<"Embed function arity information into the KCFI patchable function prefix">, + MarshallingInfoFlag>; defm sanitize_stats : BoolOption<"f", "sanitize-stats", CodeGenOpts<"SanitizeStats">, DefaultFalse, PosFlag, @@ -3505,8 +3421,6 @@ def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group, def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group; def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group; def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group; -def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group, - Visibility<[ClangOption, FlangOption]>; defm init_global_zero : BoolOptionWithoutMarshalling<"f", "init-global-zero", PosFlag, @@ -3557,11 +3471,6 @@ defm application_extension : BoolFOption<"application-extension", PosFlag, NegFlag>; -defm relaxed_template_template_args : BoolFOption<"relaxed-template-template-args", - LangOpts<"RelaxedTemplateTemplateArgs">, DefaultTrue, - PosFlag, - NegFlag, - BothFlags<[], [ClangOption], " C++17 relaxed template template argument matching">>; defm retain_subst_template_type_parm_type_ast_nodes : BoolFOption<"retain-subst-template-type-parm-type-ast-nodes", LangOpts<"RetainSubstTemplateTypeParmTypeAstNodes">, DefaultFalse, PosFlag, @@ -4023,7 +3932,9 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers", " overwriting polymorphic C++ objects">, NegFlag>; def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group, - Visibility<[ClangOption, FlangOption]>; + Visibility<[ClangOption, CLOption, FlangOption]>; +def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group, + Visibility<[ClangOption, CLOption, FlangOption]>; def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group; def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>, @@ -4163,6 +4074,10 @@ def ftrap_function_EQ : Joined<["-"], "ftrap-function=">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"Issue call to specified function rather than a trap instruction">, MarshallingInfoString>; +def floop_interchange : Flag<["-"], "floop-interchange">, Group, + HelpText<"Enable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>; +def fno_loop_interchange: Flag<["-"], "fno-loop-interchange">, Group, + HelpText<"Disable the loop interchange pass">, Visibility<[ClangOption, CC1Option]>; def funroll_loops : Flag<["-"], "funroll-loops">, Group, HelpText<"Turn on loop unroller">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>; def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group, @@ -4301,6 +4216,11 @@ def fwrapv : Flag<["-"], "fwrapv">, Group, HelpText<"Treat signed integer overflow as two's complement">; def fno_wrapv : Flag<["-"], "fno-wrapv">, Group, Visibility<[ClangOption, CLOption, FlangOption]>; +def fwrapv_pointer : Flag<["-"], "fwrapv-pointer">, Group, + Visibility<[ClangOption, CLOption, CC1Option, FlangOption, FC1Option]>, + HelpText<"Treat pointer overflow as two's complement">; +def fno_wrapv_pointer : Flag<["-"], "fno-wrapv-pointer">, Group, + Visibility<[ClangOption, CLOption, FlangOption]>; def fwritable_strings : Flag<["-"], "fwritable-strings">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"Store string literals as writable data">, @@ -4344,6 +4264,18 @@ def stack_usage_file : Separate<["-"], "stack-usage-file">, Visibility<[CC1Option]>, HelpText<"Filename (or -) to write stack usage output to">, MarshallingInfoString>; +def fextend_variable_liveness_EQ : Joined<["-"], "fextend-variable-liveness=">, + Group, Visibility<[ClangOption, CC1Option]>, + HelpText<"Extend the liveness of user variables through optimizations to " + "prevent stale or optimized-out variable values when debugging.">, + Values<"all,this,none">, + NormalizedValues<["All", "This", "None"]>, + NormalizedValuesScope<"CodeGenOptions::ExtendVariableLivenessKind">, + MarshallingInfoEnum, "None">; +def fextend_variable_liveness : Flag<["-"], "fextend-variable-liveness">, + Visibility<[ClangOption, CC1Option]>, + Alias, AliasArgs<["all"]>, + HelpText<"Alias for -fextend-variable-liveness=all.">; defm unique_basic_block_section_names : BoolFOption<"unique-basic-block-section-names", CodeGenOpts<"UniqueBasicBlockSectionNames">, DefaultFalse, @@ -5908,6 +5840,9 @@ def start_no_unused_arguments : Flag<["--"], "start-no-unused-arguments">, HelpText<"Don't emit warnings about unused arguments for the following arguments">; def static_libgcc : Flag<["-"], "static-libgcc">; def static_libstdcxx : Flag<["-"], "static-libstdc++">; +def static_libclosure : Flag<["-"], "static-libclosure">, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Generate code for statically linking libclosure (BlocksRuntime)">; def static : Flag<["-", "--"], "static">, Group, Visibility<[ClangOption, FlangOption]>, Flags<[NoArgumentUnused]>; @@ -6424,15 +6359,13 @@ def mno_avx : Flag<["-"], "mno-avx">, Group; def mavx10_1_256 : Flag<["-"], "mavx10.1-256">, Group; def mno_avx10_1_256 : Flag<["-"], "mno-avx10.1-256">, Group; def mavx10_1_512 : Flag<["-"], "mavx10.1-512">, Group; -def mno_avx10_1_512 : Flag<["-"], "mno-avx10.1-512">, Group; -def mavx10_1 : Flag<["-"], "mavx10.1">, Alias; -def mno_avx10_1 : Flag<["-"], "mno-avx10.1">, Alias; +def mno_avx10_1_512 : Flag<["-"], "mno-avx10.1-512">, Alias; +def mavx10_1 : Flag<["-"], "mavx10.1">, Flags<[Unsupported]>; +def mno_avx10_1 : Flag<["-"], "mno-avx10.1">, Flags<[Unsupported]>; def mavx10_2_256 : Flag<["-"], "mavx10.2-256">, Group; -def mno_avx10_2_256 : Flag<["-"], "mno-avx10.2-256">, Group; def mavx10_2_512 : Flag<["-"], "mavx10.2-512">, Group; -def mno_avx10_2_512 : Flag<["-"], "mno-avx10.2-512">, Group; -def mavx10_2 : Flag<["-"], "mavx10.2">, Alias; -def mno_avx10_2 : Flag<["-"], "mno-avx10.2">, Alias; +def mavx10_2 : Flag<["-"], "mavx10.2">, Alias; +def mno_avx10_2 : Flag<["-"], "mno-avx10.2">, Group; def mavx2 : Flag<["-"], "mavx2">, Group; def mno_avx2 : Flag<["-"], "mno-avx2">, Group; def mavx512f : Flag<["-"], "mavx512f">, Group; @@ -6961,6 +6894,7 @@ defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string in defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">; defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">; defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed unless overridden by IMPLICIT statements">; +defm implicit_none_ext : OptInFC1FFlag<"implicit-none-ext", "No implicit externals allowed">; defm underscoring : OptInFC1FFlag<"underscoring", "Appends one trailing underscore to external names">; defm ppc_native_vec_elem_order: BoolOptionWithoutMarshalling<"f", "ppc-native-vector-element-order", PosFlag, @@ -6970,8 +6904,11 @@ defm unsigned : OptInFC1FFlag<"unsigned", "Enables UNSIGNED type">; def fno_automatic : Flag<["-"], "fno-automatic">, Group, HelpText<"Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE">; -def fsave_main_program : Flag<["-"], "fsave-main-program">, Group, - HelpText<"Place all variables from the main program in static memory (otherwise scalars may be placed on the stack)">; +defm save_main_program : BoolOptionWithoutMarshalling<"f", "save-main-program", + PosFlag, + NegFlag>; defm stack_arrays : BoolOptionWithoutMarshalling<"f", "stack-arrays", PosFlag, @@ -7384,6 +7321,9 @@ let Visibility = [CC1Option, FC1Option] in { def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">, HelpText<"Link and internalize needed symbols from the given bitcode file " "before performing optimizations.">; +def mlink_bitcode_file + : Separate<["-"], "mlink-bitcode-file">, + HelpText<"Link the given bitcode file before performing optimizations.">; } // let Visibility = [CC1Option, FC1Option] let Visibility = [CC1Option] in { @@ -7487,14 +7427,13 @@ def msmall_data_limit : Separate<["-"], "msmall-data-limit">, def funwind_tables_EQ : Joined<["-"], "funwind-tables=">, HelpText<"Generate unwinding tables for all functions">, MarshallingInfoInt>; -defm constructor_aliases : BoolMOption<"constructor-aliases", - CodeGenOpts<"CXXCtorDtorAliases">, DefaultFalse, - PosFlag, - NegFlag, - BothFlags<[], [ClangOption, CC1Option], - " emitting complete constructors and destructors as aliases when possible">>; -def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, - HelpText<"Link the given bitcode file before performing optimizations.">; +defm constructor_aliases + : BoolMOption<"constructor-aliases", CodeGenOpts<"CXXCtorDtorAliases">, + DefaultFalse, PosFlag, + NegFlag, + BothFlags<[], [ClangOption, CC1Option], + " emitting complete constructors and destructors " + "as aliases when possible">>; defm link_builtin_bitcode_postopt: BoolMOption<"link-builtin-bitcode-postopt", CodeGenOpts<"LinkBitcodePostopt">, DefaultFalse, PosFlag, MarshallingInfoFlag>; +def import_call_optimization : Flag<["-"], "import-call-optimization">, + HelpText<"Emit Import Call sections on supported targets that can be used " + "by the Windows kernel to enable import call optimization">, + MarshallingInfoFlag>; + } // let Visibility = [CC1Option] //===----------------------------------------------------------------------===// @@ -7960,8 +7904,6 @@ def rewrite_test : Flag<["-"], "rewrite-test">, HelpText<"Rewriter playground">; def rewrite_macros : Flag<["-"], "rewrite-macros">, HelpText<"Expand macros without full preprocessing">; -def migrate : Flag<["-"], "migrate">, - HelpText<"Migrate source code">; def compiler_options_dump : Flag<["-"], "compiler-options-dump">, HelpText<"Dump the compiler configuration options">; def print_dependency_directives_minimized_source : Flag<["-"], @@ -7975,17 +7917,6 @@ defm emit_llvm_uselists : BoolOption<"", "emit-llvm-uselists", NegFlag, BothFlags<[], [ClangOption], " order of LLVM use-lists when serializing">>; -def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">, - HelpText<"Directory for temporary files produced during ARC or ObjC migration">, - MarshallingInfoString>; - -def arcmt_action_EQ : Joined<["-"], "arcmt-action=">, Visibility<[CC1Option]>, - HelpText<"The ARC migration action to take">, - Values<"check,modify,migrate">, - NormalizedValuesScope<"FrontendOptions">, - NormalizedValues<["ARCMT_Check", "ARCMT_Modify", "ARCMT_Migrate"]>, - MarshallingInfoEnum, "ARCMT_None">; - def print_stats : Flag<["-"], "print-stats">, HelpText<"Print performance metrics and statistics">, MarshallingInfoFlag>; diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index a54995e2b153b..6a866ded0e75c 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -43,6 +43,7 @@ class SanitizerArgs { bool CfiICallGeneralizePointers = false; bool CfiICallNormalizeIntegers = false; bool CfiCanonicalJumpTables = false; + bool KcfiArity = false; int AsanFieldPadding = 0; bool SharedRuntime = false; bool StableABI = false; diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index b09b8b44d9aba..e60440e14a9fe 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -252,6 +252,11 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { if (!NewRecordContext) return; auto *Tag = D.getType()->getAsTagDecl(); + if (!Tag) { + if (const auto *AT = D.getASTContext().getAsArrayType(D.getType())) { + Tag = AT->getElementType()->getAsTagDecl(); + } + } SmallString<128> TagUSR; clang::index::generateUSRForDecl(Tag, TagUSR); if (auto *Record = llvm::dyn_cast_if_present( @@ -1141,11 +1146,29 @@ bool ExtractAPIVisitorBase::VisitTypedefNameDecl( StringRef Name = Decl->getName(); + auto nameMatches = [&Name](TagDecl *TagDecl) { + StringRef TagName = TagDecl->getName(); + + if (TagName == Name) + return true; + + // Also check whether the tag decl's name is the same as the typedef name + // with prefixed underscores + if (TagName.starts_with('_')) { + StringRef StrippedName = TagName.ltrim('_'); + + if (StrippedName == Name) + return true; + } + + return false; + }; + // If the underlying type was defined as part of the typedef modify it's // fragments directly and pretend the typedef doesn't exist. if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) { if (TagDecl->isEmbeddedInDeclarator() && TagDecl->isCompleteDefinition() && - Decl->getName() == TagDecl->getName()) { + nameMatches(TagDecl)) { SmallString<128> TagUSR; index::generateUSRForDecl(TagDecl, TagUSR); if (auto *Record = API.findRecordForUSR(TagUSR)) { @@ -1159,6 +1182,11 @@ bool ExtractAPIVisitorBase::VisitTypedefNameDecl( .append(Name, DeclarationFragments::FragmentKind::Identifier) .appendSemicolon(); + // Replace the name and subheading in case it's underscored so we can + // use the non-underscored version + Record->Name = Name; + Record->SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl); + return true; } } diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index fd526f189ec83..16956b4e0fbd4 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1212,6 +1212,22 @@ struct FormatStyle { /// \version 3.7 bool BinPackArguments; + /// If ``BinPackLongBracedList`` is ``true`` it overrides + /// ``BinPackArguments`` if there are 20 or more items in a braced + /// initializer list. + /// \code + /// BinPackLongBracedList: false vs. BinPackLongBracedList: true + /// vector x{ vector x{1, 2, ..., + /// 20, 21}; + /// 1, + /// 2, + /// ..., + /// 20, + /// 21}; + /// \endcode + /// \version 21 + bool BinPackLongBracedList; + /// Different way to try to fit all parameters on a line. enum BinPackParametersStyle : int8_t { /// Bin-pack parameters. @@ -2252,6 +2268,33 @@ struct FormatStyle { /// \version 16 BreakBeforeInlineASMColonStyle BreakBeforeInlineASMColon; + /// If ``true``, break before a template closing bracket (``>``) when there is + /// a line break after the matching opening bracket (``<``). + /// \code + /// true: + /// template + /// + /// template + /// + /// template < + /// typename Foo, + /// typename Bar + /// > + /// + /// false: + /// template + /// + /// template + /// + /// template < + /// typename Foo, + /// typename Bar> + /// \endcode + /// \version 21 + bool BreakBeforeTemplateCloser; + /// If ``true``, ternary operators will be placed after line breaks. /// \code /// true: @@ -3639,6 +3682,10 @@ struct FormatStyle { /// \version 3.7 unsigned PenaltyBreakBeforeFirstCallParameter; + /// The penalty for breaking before a member access operator (``.``, ``->``). + /// \version 20 + unsigned PenaltyBreakBeforeMemberAccess; + /// The penalty for each line break introduced inside a comment. /// \version 3.7 unsigned PenaltyBreakComment; @@ -5235,6 +5282,7 @@ struct FormatStyle { R.AlwaysBreakBeforeMultilineStrings && AttributeMacros == R.AttributeMacros && BinPackArguments == R.BinPackArguments && + BinPackLongBracedList == R.BinPackLongBracedList && BinPackParameters == R.BinPackParameters && BitFieldColonSpacing == R.BitFieldColonSpacing && BracedInitializerIndentWidth == R.BracedInitializerIndentWidth && @@ -5247,6 +5295,7 @@ struct FormatStyle { BreakBeforeBraces == R.BreakBeforeBraces && BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations && BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon && + BreakBeforeTemplateCloser == R.BreakBeforeTemplateCloser && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBinaryOperations == R.BreakBinaryOperations && BreakConstructorInitializers == R.BreakConstructorInitializers && @@ -5311,6 +5360,7 @@ struct FormatStyle { PenaltyBreakAssignment == R.PenaltyBreakAssignment && PenaltyBreakBeforeFirstCallParameter == R.PenaltyBreakBeforeFirstCallParameter && + PenaltyBreakBeforeMemberAccess == R.PenaltyBreakBeforeMemberAccess && PenaltyBreakComment == R.PenaltyBreakComment && PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess && PenaltyBreakOpenParenthesis == R.PenaltyBreakOpenParenthesis && diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 8241925c98476..99b2d9a98ed1f 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -141,9 +141,6 @@ enum ActionKind { /// Dump template instantiations TemplightDump, - /// Run migrator. - MigrateSource, - /// Just lex, no output. RunPreprocessorOnly, @@ -330,10 +327,6 @@ class FrontendOptions { LLVM_PREFERRED_TYPE(bool) unsigned FixToTemporaries : 1; - /// Emit ARC errors even if the migrator can fix them. - LLVM_PREFERRED_TYPE(bool) - unsigned ARCMTMigrateEmitARCErrors : 1; - /// Skip over function bodies to speed up parsing in cases you do not need /// them (e.g. with code completion). LLVM_PREFERRED_TYPE(bool) @@ -424,72 +417,6 @@ class FrontendOptions { /// Specifies the output format of the AST. ASTDumpOutputFormat ASTDumpFormat = ADOF_Default; - enum { - ARCMT_None, - ARCMT_Check, - ARCMT_Modify, - ARCMT_Migrate - } ARCMTAction = ARCMT_None; - - enum { - ObjCMT_None = 0, - - /// Enable migration to modern ObjC literals. - ObjCMT_Literals = 0x1, - - /// Enable migration to modern ObjC subscripting. - ObjCMT_Subscripting = 0x2, - - /// Enable migration to modern ObjC readonly property. - ObjCMT_ReadonlyProperty = 0x4, - - /// Enable migration to modern ObjC readwrite property. - ObjCMT_ReadwriteProperty = 0x8, - - /// Enable migration to modern ObjC property. - ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty), - - /// Enable annotation of ObjCMethods of all kinds. - ObjCMT_Annotation = 0x10, - - /// Enable migration of ObjC methods to 'instancetype'. - ObjCMT_Instancetype = 0x20, - - /// Enable migration to NS_ENUM/NS_OPTIONS macros. - ObjCMT_NsMacros = 0x40, - - /// Enable migration to add conforming protocols. - ObjCMT_ProtocolConformance = 0x80, - - /// prefer 'atomic' property over 'nonatomic'. - ObjCMT_AtomicProperty = 0x100, - - /// annotate property with NS_RETURNS_INNER_POINTER - ObjCMT_ReturnsInnerPointerProperty = 0x200, - - /// use NS_NONATOMIC_IOSONLY for property 'atomic' attribute - ObjCMT_NsAtomicIOSOnlyProperty = 0x400, - - /// Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods. - ObjCMT_DesignatedInitializer = 0x800, - - /// Enable converting setter/getter expressions to property-dot syntx. - ObjCMT_PropertyDotSyntax = 0x1000, - - ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty | - ObjCMT_Annotation | ObjCMT_Instancetype | - ObjCMT_NsMacros | ObjCMT_ProtocolConformance | - ObjCMT_NsAtomicIOSOnlyProperty | - ObjCMT_DesignatedInitializer), - ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | - ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax) - }; - unsigned ObjCMTAction = ObjCMT_None; - std::string ObjCMTAllowListPath; - - std::string MTMigrateDir; - std::string ARCMTMigrateReportOut; - /// The input kind, either specified via -x argument or deduced from the input /// file name. InputKind DashX; @@ -596,14 +523,14 @@ class FrontendOptions { : DisableFree(false), RelocatablePCH(false), ShowHelp(false), ShowStats(false), AppendStats(false), ShowVersion(false), FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), - FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), - SkipFunctionBodies(false), UseGlobalModuleIndex(true), - GenerateGlobalModuleIndex(true), ASTDumpDecls(false), - ASTDumpLookups(false), BuildingImplicitModule(false), - BuildingImplicitModuleUsesLock(true), ModulesEmbedAllFiles(false), - IncludeTimestamps(true), UseTemporary(true), - AllowPCMWithCompilerErrors(false), ModulesShareFileManager(true), - EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false), + FixToTemporaries(false), SkipFunctionBodies(false), + UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), + ASTDumpDecls(false), ASTDumpLookups(false), + BuildingImplicitModule(false), BuildingImplicitModuleUsesLock(true), + ModulesEmbedAllFiles(false), IncludeTimestamps(true), + UseTemporary(true), AllowPCMWithCompilerErrors(false), + ModulesShareFileManager(true), EmitSymbolGraph(false), + EmitExtensionSymbolGraphs(false), EmitSymbolGraphSymbolLabelsForTesting(false), EmitPrettySymbolGraphs(false), GenReducedBMI(false), UseClangIRPipeline(false), TimeTraceGranularity(500), diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 8ddc5b56eedbd..2bf4d1a166994 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -856,7 +856,7 @@ class Preprocessor { !PP.CurSubmoduleState->VisibleModules.getGeneration()) return nullptr; - auto *Info = State.dyn_cast(); + auto *Info = dyn_cast_if_present(State); if (!Info) { Info = new (PP.getPreprocessorAllocator()) ModuleMacroInfo(cast(State)); @@ -885,18 +885,18 @@ class Preprocessor { } ~MacroState() { - if (auto *Info = State.dyn_cast()) + if (auto *Info = dyn_cast_if_present(State)) Info->~ModuleMacroInfo(); } MacroDirective *getLatest() const { - if (auto *Info = State.dyn_cast()) + if (auto *Info = dyn_cast_if_present(State)) return Info->MD; return cast(State); } void setLatest(MacroDirective *MD) { - if (auto *Info = State.dyn_cast()) + if (auto *Info = dyn_cast_if_present(State)) Info->MD = MD; else State = MD; @@ -933,14 +933,14 @@ class Preprocessor { } ArrayRef getOverriddenMacros() const { - if (auto *Info = State.dyn_cast()) + if (auto *Info = dyn_cast_if_present(State)) return Info->OverriddenMacros; return {}; } void setOverriddenMacros(Preprocessor &PP, ArrayRef Overrides) { - auto *Info = State.dyn_cast(); + auto *Info = dyn_cast_if_present(State); if (!Info) { if (Overrides.empty()) return; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index e99d2cf2eaa40..335258d597028 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3710,6 +3710,7 @@ class Parser : public CodeCompletionHandler { SourceLocation RParenLoc; SourceLocation EndLoc; SourceLocation MiscLoc; + OpenACCAtomicKind AtomicKind; SmallVector Exprs; SmallVector Clauses; // TODO OpenACC: As we implement support for the Atomic, Routine, and Cache diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 06243f2624876..5f5df3a45d41d 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -1795,6 +1795,7 @@ class DecompositionDeclarator { IdentifierInfo *Name; SourceLocation NameLoc; std::optional Attrs; + SourceLocation EllipsisLoc; }; private: diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index c7f2422b542dd..c03ec00d03dc5 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -933,7 +933,7 @@ class Sema; /// Have we matched any packs on the parameter side, versus any non-packs on /// the argument side, in a context where the opposite matching is also /// allowed? - bool HasMatchedPackOnParmToNonPackOnArg : 1; + bool StrictPackMatch : 1; /// True if the candidate was found using ADL. LLVM_PREFERRED_TYPE(CallExpr::ADLCallKind) @@ -1010,8 +1010,7 @@ class Sema; friend class OverloadCandidateSet; OverloadCandidate() : IsSurrogate(false), IgnoreObjectArgument(false), - TookAddressOfOverload(false), - HasMatchedPackOnParmToNonPackOnArg(false), + TookAddressOfOverload(false), StrictPackMatch(false), IsADLCandidate(llvm::to_underlying(CallExpr::NotADL)), RewriteKind(CRK_None) {} }; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4d6e02fe2956e..1870d1271c556 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -16,6 +16,7 @@ #include "clang/APINotes/APINotesManager.h" #include "clang/AST/ASTFwd.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/Attr.h" #include "clang/AST/AttrIterator.h" #include "clang/AST/CharUnits.h" @@ -231,7 +232,8 @@ void threadSafetyCleanup(BeforeSet *Cache); // FIXME: No way to easily map from TemplateTypeParmTypes to // TemplateTypeParmDecls, so we have this horrible PointerUnion. -typedef std::pair, +typedef std::pair, SourceLocation> UnexpandedParameterPack; @@ -2330,7 +2332,8 @@ class Sema final : public SemaBase { const FunctionProtoType *Proto); /// \param FPOnly restricts the arguments to floating-point types. - bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly = false); + std::optional BuiltinVectorMath(CallExpr *TheCall, + bool FPOnly = false); bool BuiltinVectorToScalarMath(CallExpr *TheCall); void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, @@ -3661,6 +3664,12 @@ class Sema final : public SemaBase { NonTrivialCUnionContext UseContext, unsigned NonTrivialKind); + /// Certain globally-unique variables might be accidentally duplicated if + /// built into multiple shared libraries with hidden visibility. This can + /// cause problems if the variable is mutable, its initialization is + /// effectful, or its address is taken. + bool GloballyUniqueObjectMightBeAccidentallyDuplicated(const VarDecl *Dcl); + /// AddInitializerToDecl - Adds the initializer Init to the /// declaration dcl. If DirectInit is true, this is C++ direct /// initialization rather than copy initialization. @@ -6019,6 +6028,7 @@ class Sema final : public SemaBase { RecordDecl *ClassDecl, const IdentifierInfo *Name); + unsigned GetDecompositionElementCount(QualType DecompType); void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); /// Stack containing information needed when in C++2a an 'auto' is encountered @@ -7498,10 +7508,15 @@ class Sema final : public SemaBase { return K == ConditionKind::Switch ? Context.IntTy : Context.BoolTy; } - // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts - // functions and arrays to their respective pointers (C99 6.3.2.1). + // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2), converts + // functions and arrays to their respective pointers (C99 6.3.2.1), and + // promotes floating-piont types according to the language semantics. ExprResult UsualUnaryConversions(Expr *E); + // UsualUnaryFPConversions - promotes floating-point types according to the + // current language semantics. + ExprResult UsualUnaryFPConversions(Expr *E); + /// CallExprUnaryConversions - a special case of an unary conversion /// performed on a function designator of a call expression. ExprResult CallExprUnaryConversions(Expr *E); @@ -7564,6 +7579,11 @@ class Sema final : public SemaBase { ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl); + // Check that the usual arithmetic conversions can be performed on this pair + // of expressions that might be of enumeration type. + void checkEnumArithmeticConversions(Expr *LHS, Expr *RHS, SourceLocation Loc, + Sema::ArithConvKind ACK); + // UsualArithmeticConversions - performs the UsualUnaryConversions on it's // operands and then handles various conversions that are common to binary // operators (C99 6.3.1.8). If both operands aren't arithmetic, this @@ -9999,6 +10019,7 @@ class Sema final : public SemaBase { CCEK_CaseValue, ///< Expression in a case label. CCEK_Enumerator, ///< Enumerator value with fixed underlying type. CCEK_TemplateArg, ///< Value of a non-type template parameter. + CCEK_InjectedTTP, ///< Injected parameter of a template template parameter. CCEK_ArrayBound, ///< Array bound in array declarator or new-expression. CCEK_ExplicitBool, ///< Condition in an explicit(bool) specifier. CCEK_Noexcept, ///< Condition in a noexcept(bool) specifier. @@ -10159,18 +10180,15 @@ class Sema final : public SemaBase { /// \param PartialOverloading true if we are performing "partial" overloading /// based on an incomplete set of function arguments. This feature is used by /// code completion. - void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, - ArrayRef Args, - OverloadCandidateSet &CandidateSet, - bool SuppressUserConversions = false, - bool PartialOverloading = false, - bool AllowExplicit = true, - bool AllowExplicitConversion = false, - ADLCallKind IsADLCandidate = ADLCallKind::NotADL, - ConversionSequenceList EarlyConversions = {}, - OverloadCandidateParamOrder PO = {}, - bool AggregateCandidateDeduction = false, - bool HasMatchedPackOnParmToNonPackOnArg = false); + void AddOverloadCandidate( + FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef Args, + OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false, + bool PartialOverloading = false, bool AllowExplicit = true, + bool AllowExplicitConversion = false, + ADLCallKind IsADLCandidate = ADLCallKind::NotADL, + ConversionSequenceList EarlyConversions = {}, + OverloadCandidateParamOrder PO = {}, + bool AggregateCandidateDeduction = false, bool StrictPackMatch = false); /// Add all of the function declarations in the given function set to /// the overload candidate set. @@ -10206,7 +10224,7 @@ class Sema final : public SemaBase { bool PartialOverloading = false, ConversionSequenceList EarlyConversions = {}, OverloadCandidateParamOrder PO = {}, - bool HasMatchedPackOnParmToNonPackOnArg = false); + bool StrictPackMatch = false); /// Add a C++ member function template as a candidate to the candidate /// set, using template argument deduction to produce an appropriate member @@ -10253,7 +10271,7 @@ class Sema final : public SemaBase { CXXRecordDecl *ActingContext, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, bool AllowExplicit, bool AllowResultConversion = true, - bool HasMatchedPackOnParmToNonPackOnArg = false); + bool StrictPackMatch = false); /// Adds a conversion function template specialization /// candidate to the overload set, using template argument deduction @@ -11649,6 +11667,33 @@ class Sema final : public SemaBase { CTAK_DeducedFromArrayBound }; + struct CheckTemplateArgumentInfo { + explicit CheckTemplateArgumentInfo(bool PartialOrdering = false, + bool MatchingTTP = false) + : PartialOrdering(PartialOrdering), MatchingTTP(MatchingTTP) {} + CheckTemplateArgumentInfo(const CheckTemplateArgumentInfo &) = delete; + CheckTemplateArgumentInfo & + operator=(const CheckTemplateArgumentInfo &) = delete; + + /// The checked, converted argument will be added to the + /// end of these vectors. + SmallVector SugaredConverted, CanonicalConverted; + + /// The check is being performed in the context of partial ordering. + bool PartialOrdering; + + /// If true, assume these template arguments are + /// the injected template arguments for a template template parameter. + /// This will relax the requirement that all its possible uses are valid: + /// TTP checking is loose, and assumes that invalid uses will be diagnosed + /// during instantiation. + bool MatchingTTP; + + /// Is set to true when, in the context of TTP matching, a pack parameter + /// matches non-pack arguments. + bool StrictPackMatch = false; + }; + /// Check that the given template argument corresponds to the given /// template parameter. /// @@ -11668,21 +11713,16 @@ class Sema final : public SemaBase { /// \param ArgumentPackIndex The index into the argument pack where this /// argument will be placed. Only valid if the parameter is a parameter pack. /// - /// \param Converted The checked, converted argument will be added to the - /// end of this small vector. - /// /// \param CTAK Describes how we arrived at this particular template argument: /// explicitly written, deduced, etc. /// /// \returns true on error, false otherwise. - bool - CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, - NamedDecl *Template, SourceLocation TemplateLoc, - SourceLocation RAngleLoc, unsigned ArgumentPackIndex, - SmallVectorImpl &SugaredConverted, - SmallVectorImpl &CanonicalConverted, - CheckTemplateArgumentKind CTAK, bool PartialOrdering, - bool *MatchedPackOnParmToNonPackOnArg); + bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg, + NamedDecl *Template, SourceLocation TemplateLoc, + SourceLocation RAngleLoc, + unsigned ArgumentPackIndex, + CheckTemplateArgumentInfo &CTAI, + CheckTemplateArgumentKind CTAK); /// Check that the given template arguments can be provided to /// the given template, converting the arguments along the way. @@ -11715,22 +11755,15 @@ class Sema final : public SemaBase { /// \param DefaultArgs any default arguments from template specialization /// deduction. /// - /// \param PartialOrderingTTP If true, assume these template arguments are - /// the injected template arguments for a template template parameter. - /// This will relax the requirement that all its possible uses are valid: - /// TTP checking is loose, and assumes that invalid uses will be diagnosed - /// during instantiation. - /// /// \returns true if an error occurred, false otherwise. - bool CheckTemplateArgumentList( - TemplateDecl *Template, SourceLocation TemplateLoc, - TemplateArgumentListInfo &TemplateArgs, - const DefaultArguments &DefaultArgs, bool PartialTemplateArgs, - SmallVectorImpl &SugaredConverted, - SmallVectorImpl &CanonicalConverted, - bool UpdateArgsWithConversions = true, - bool *ConstraintsNotSatisfied = nullptr, bool PartialOrderingTTP = false, - bool *MatchedPackOnParmToNonPackOnArg = nullptr); + bool CheckTemplateArgumentList(TemplateDecl *Template, + SourceLocation TemplateLoc, + TemplateArgumentListInfo &TemplateArgs, + const DefaultArguments &DefaultArgs, + bool PartialTemplateArgs, + CheckTemplateArgumentInfo &CTAI, + bool UpdateArgsWithConversions = true, + bool *ConstraintsNotSatisfied = nullptr); bool CheckTemplateTypeArgument( TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg, @@ -11755,6 +11788,7 @@ class Sema final : public SemaBase { QualType InstantiatedParamType, Expr *Arg, TemplateArgument &SugaredConverted, TemplateArgument &CanonicalConverted, + bool MatchingTTP, CheckTemplateArgumentKind CTAK); /// Check a template argument against its corresponding @@ -11766,7 +11800,7 @@ class Sema final : public SemaBase { TemplateParameterList *Params, TemplateArgumentLoc &Arg, bool PartialOrdering, - bool *MatchedPackOnParmToNonPackOnArg); + bool *StrictPackMatch); void NoteTemplateLocation(const NamedDecl &Decl, std::optional ParamRange = {}); @@ -11776,6 +11810,9 @@ class Sema final : public SemaBase { /// declaration and the type of its corresponding non-type template /// parameter, produce an expression that properly refers to that /// declaration. + /// FIXME: This is used in some contexts where the resulting expression + /// doesn't need to live too long. It would be useful if this function + /// could return a temporary expression. ExprResult BuildExpressionFromDeclTemplateArgument( const TemplateArgument &Arg, QualType ParamType, SourceLocation Loc, NamedDecl *TemplateParam = nullptr); @@ -11805,17 +11842,6 @@ class Sema final : public SemaBase { /// \endcode TPL_TemplateTemplateParmMatch, - /// We are matching the template parameter lists of a template - /// template argument against the template parameter lists of a template - /// template parameter. - /// - /// \code - /// template class Metafun> struct X; - /// template struct integer_c; - /// X xic; - /// \endcode - TPL_TemplateTemplateArgumentMatch, - /// We are determining whether the template-parameters are equivalent /// according to C++ [temp.over.link]/6. This comparison does not consider /// constraints. @@ -12468,7 +12494,7 @@ class Sema final : public SemaBase { bool isTemplateTemplateParameterAtLeastAsSpecializedAs( TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg, const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, - bool PartialOrdering, bool *MatchedPackOnParmToNonPackOnArg); + bool PartialOrdering, bool *StrictPackMatch); /// Mark which template parameters are used in a given expression. /// @@ -13108,14 +13134,16 @@ class Sema final : public SemaBase { ? ExpressionEvaluationContext::ImmediateFunctionContext : ExpressionEvaluationContext::PotentiallyEvaluated); if (FD) { + auto &Current = S.currentEvaluationContext(); + const auto &Parent = S.parentEvaluationContext(); + FD->setWillHaveBody(true); - S.ExprEvalContexts.back().InImmediateFunctionContext = + Current.InImmediateFunctionContext = FD->isImmediateFunction() || - S.ExprEvalContexts[S.ExprEvalContexts.size() - 2] - .isConstantEvaluated() || - S.ExprEvalContexts[S.ExprEvalContexts.size() - 2] - .isImmediateFunctionContext(); - S.ExprEvalContexts.back().InImmediateEscalatingFunctionContext = + (isLambdaMethod(FD) && (Parent.isConstantEvaluated() || + Parent.isImmediateFunctionContext())); + + Current.InImmediateEscalatingFunctionContext = S.getLangOpts().CPlusPlus20 && FD->isImmediateEscalating(); } else assert(isa(DC)); @@ -13468,8 +13496,8 @@ class Sema final : public SemaBase { bool InstantiateClassTemplateSpecialization( SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, bool Complain = true, - bool PrimaryHasMatchedPackOnParmToNonPackOnArg = false); + TemplateSpecializationKind TSK, bool Complain, + bool PrimaryStrictPackMatch); /// Instantiates the definitions of all of the member /// of the given class, which is an instantiation of a class template diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index f4cd11f423a84..6e8ca2e4710de 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -141,6 +141,9 @@ class SemaHLSL : public SemaBase { // Diagnose whether the input ID is uint/unit2/uint3 type. bool diagnoseInputIDType(QualType T, const ParsedAttr &AL); + bool CanPerformScalarCast(QualType SrcTy, QualType DestTy); + bool ContainsBitField(QualType BaseTy); + bool CanPerformElementwiseCast(Expr *Src, QualType DestType); ExprResult ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg); QualType getInoutParameterType(QualType Ty); @@ -160,9 +163,9 @@ class SemaHLSL : public SemaBase { ResourceBindings Bindings; private: - void collectResourcesOnVarDecl(VarDecl *D); - void collectResourcesOnUserRecordDecl(const VarDecl *VD, - const RecordType *RT); + void collectResourceBindingsOnVarDecl(VarDecl *D); + void collectResourceBindingsOnUserRecordDecl(const VarDecl *VD, + const RecordType *RT); void processExplicitBindingsOnDecl(VarDecl *D); }; diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index 2e5a0ea0aaac6..3004b98760a98 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -695,24 +695,53 @@ class SemaOpenACC : public SemaBase { /// should check legality of the statement as it appertains to this Construct. StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, OpenACCDirectiveKind K, + OpenACCAtomicKind AtKind, ArrayRef Clauses, StmtResult AssocStmt); + StmtResult ActOnAssociatedStmt(SourceLocation DirectiveLoc, + OpenACCDirectiveKind K, + ArrayRef Clauses, + StmtResult AssocStmt) { + return ActOnAssociatedStmt(DirectiveLoc, K, OpenACCAtomicKind::None, + Clauses, AssocStmt); + } + /// Called to check the form of the `atomic` construct which has some fairly + /// sizable restrictions. + StmtResult CheckAtomicAssociatedStmt(SourceLocation AtomicDirLoc, + OpenACCAtomicKind AtKind, + StmtResult AssocStmt); + /// Called after the directive has been completely parsed, including the /// declaration group or associated statement. + /// DirLoc: Location of the actual directive keyword. /// LParenLoc: Location of the left paren, if it exists (not on all /// constructs). /// MiscLoc: First misc location, if necessary (not all constructs). /// Exprs: List of expressions on the construct itself, if necessary (not all /// constructs). + /// AK: The atomic kind of the directive, if necessary (atomic only) /// RParenLoc: Location of the right paren, if it exists (not on all /// constructs). + /// EndLoc: The last source location of the driective. + /// Clauses: The list of clauses for the directive, if present. + /// AssocStmt: The associated statement for this construct, if necessary. StmtResult ActOnEndStmtDirective( OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef Exprs, - SourceLocation RParenLoc, SourceLocation EndLoc, + OpenACCAtomicKind AK, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef Clauses, StmtResult AssocStmt); + StmtResult ActOnEndStmtDirective( + OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, + SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef Exprs, + SourceLocation RParenLoc, SourceLocation EndLoc, + ArrayRef Clauses, StmtResult AssocStmt) { + return ActOnEndStmtDirective(K, StartLoc, DirLoc, LParenLoc, MiscLoc, Exprs, + OpenACCAtomicKind::None, RParenLoc, EndLoc, + Clauses, AssocStmt); + } + /// Called after the directive has been completely parsed, including the /// declaration group or associated statement. DeclGroupRef ActOnEndDeclDirective(); diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index a056a96f50233..fa244da36a322 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -849,6 +849,9 @@ class SemaOpenMP : public SemaBase { ArrayRef AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR); + /// Called on device_num selector in context selectors. + void ActOnOpenMPDeviceNum(Expr *DeviceNumExpr); + OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -1410,6 +1413,13 @@ class SemaOpenMP : public SemaBase { void handleOMPAssumeAttr(Decl *D, const ParsedAttr &AL); + /// Setter and getter functions for device_num. + void setOpenMPDeviceNum(int Num); + + int getOpenMPDeviceNum() const; + + void setOpenMPDeviceNumID(StringRef ID); + private: void *VarDataSharingAttributesStack; @@ -1480,6 +1490,12 @@ class SemaOpenMP : public SemaBase { /// All `omp assumes` we encountered so far. SmallVector OMPAssumeGlobal; + + /// Device number specified by the context selector. + int DeviceNum = -1; + + /// Device number identifier specified by the context selector. + StringRef DeviceNumID; }; } // namespace clang diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h index 9c12eef5c42a0..020e19bc7a608 100644 --- a/clang/include/clang/Sema/TemplateDeduction.h +++ b/clang/include/clang/Sema/TemplateDeduction.h @@ -54,7 +54,7 @@ class TemplateDeductionInfo { /// Have we matched any packs on the parameter side, versus any non-packs on /// the argument side, in a context where the opposite matching is also /// allowed? - bool MatchedPackOnParmToNonPackOnArg = false; + bool StrictPackMatch = false; /// The template parameter depth for which we're performing deduction. unsigned DeducedDepth; @@ -92,13 +92,9 @@ class TemplateDeductionInfo { return DeducedDepth; } - bool hasMatchedPackOnParmToNonPackOnArg() const { - return MatchedPackOnParmToNonPackOnArg; - } + bool hasStrictPackMatch() const { return StrictPackMatch; } - void setMatchedPackOnParmToNonPackOnArg() { - MatchedPackOnParmToNonPackOnArg = true; - } + void setStrictPackMatch() { StrictPackMatch = true; } /// Get the number of explicitly-specified arguments. unsigned getNumExplicitArgs() const { diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 1b56ed2c9776b..3c184db5b2adf 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1908,6 +1908,7 @@ enum StmtCode { EXPR_PACK_EXPANSION, // PackExpansionExpr EXPR_PACK_INDEXING, // PackIndexingExpr EXPR_SIZEOF_PACK, // SizeOfPackExpr + EXPR_RESOLVED_UNEXPANDED_PACK, // ResolvedUnexpandedPackExpr EXPR_SUBST_NON_TYPE_TEMPLATE_PARM, // SubstNonTypeTemplateParmExpr EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK, // SubstNonTypeTemplateParmPackExpr EXPR_FUNCTION_PARM_PACK, // FunctionParmPackExpr @@ -2044,6 +2045,7 @@ enum StmtCode { STMT_OPENACC_SHUTDOWN_CONSTRUCT, STMT_OPENACC_SET_CONSTRUCT, STMT_OPENACC_UPDATE_CONSTRUCT, + STMT_OPENACC_ATOMIC_CONSTRUCT, // HLSL Constructs EXPR_HLSL_OUT_ARG, diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 1361da46c3c81..9bf491eac1e0e 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -989,30 +989,41 @@ def decodeValueOfObjCType : Checker<"decodeValueOfObjCType">, let ParentPackage = Security in { -def FloatLoopCounter : Checker<"FloatLoopCounter">, - HelpText<"Warn on using a floating point value as a loop counter (CERT: " - "FLP30-C, FLP30-CPP)">, - Dependencies<[SecuritySyntaxChecker]>, - Documentation; - -def MmapWriteExecChecker : Checker<"MmapWriteExec">, - HelpText<"Warn on mmap() calls with both writable and executable access">, - Documentation; - -def PointerSubChecker : Checker<"PointerSub">, - HelpText<"Check for pointer subtractions on two pointers pointing to " - "different memory chunks">, - Documentation; - -def PutenvStackArray : Checker<"PutenvStackArray">, - HelpText<"Finds calls to the function 'putenv' which pass a pointer to " - "an automatic (stack-allocated) array as the argument.">, - Documentation; - -def SetgidSetuidOrderChecker : Checker<"SetgidSetuidOrder">, - HelpText<"Warn on possible reversed order of 'setgid(getgid()))' and " - "'setuid(getuid())' (CERT: POS36-C)">, - Documentation; + def ArrayBoundChecker : Checker<"ArrayBound">, + HelpText<"Warn about out of bounds access to memory">, + Documentation; + + def FloatLoopCounter + : Checker<"FloatLoopCounter">, + HelpText< + "Warn on using a floating point value as a loop counter (CERT: " + "FLP30-C, FLP30-CPP)">, + Dependencies<[SecuritySyntaxChecker]>, + Documentation; + + def MmapWriteExecChecker + : Checker<"MmapWriteExec">, + HelpText< + "Warn on mmap() calls with both writable and executable access">, + Documentation; + + def PointerSubChecker + : Checker<"PointerSub">, + HelpText<"Check for pointer subtractions on two pointers pointing to " + "different memory chunks">, + Documentation; + + def PutenvStackArray + : Checker<"PutenvStackArray">, + HelpText<"Finds calls to the function 'putenv' which pass a pointer to " + "an automatic (stack-allocated) array as the argument.">, + Documentation; + + def SetgidSetuidOrderChecker + : Checker<"SetgidSetuidOrder">, + HelpText<"Warn on possible reversed order of 'setgid(getgid()))' and " + "'setuid(getuid())' (CERT: POS36-C)">, + Documentation; } // end "security" @@ -1035,14 +1046,6 @@ let ParentPackage = ENV in { let ParentPackage = SecurityAlpha in { -def ArrayBoundChecker : Checker<"ArrayBound">, - HelpText<"Warn about buffer overflows (older checker)">, - Documentation; - -def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">, - HelpText<"Warn about buffer overflows (newer checker)">, - Documentation; - def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, HelpText<"Check for an out-of-bound pointer being returned to callers">, Documentation; diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 8974342166fad..7563d8bbd1d27 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -748,8 +748,8 @@ class BugReporterContext { /// It can be valuable to produce tags with some bits of information and later /// reuse them for a better diagnostic. /// -/// Please make sure that derived class' constuctor is private and that the user -/// can only create objects using DataTag::Factory. This also means that +/// Please make sure that derived class' constructor is private and that the +/// user can only create objects using DataTag::Factory. This also means that /// DataTag::Factory should be friend for every derived class. class DataTag : public ProgramPointTag { public: diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h index a99c11766f110..3c242898ef6cd 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h @@ -35,7 +35,7 @@ class CallDescription { /// Match calls to functions from the C standard library. This also /// recognizes builtin variants whose name is derived by adding /// "__builtin", "__inline" or similar prefixes or suffixes; but only - /// matches functions than are externally visible and are declared either + /// matches functions that are externally visible and are declared either /// directly within a TU or in the namespace 'std'. /// For the exact heuristics, see CheckerContext::isCLibraryFunction(). CLibrary, @@ -152,7 +152,7 @@ class CallDescription { /// exists only when that is not available, for example, when _only_ /// syntactic check is done on a piece of code. /// - /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade + /// Also, StdLibraryFunctionsChecker::Signature is likely a better candidate /// for syntactic only matching if you are writing a new checker. This is /// handy if a CallDescriptionMap is already there. /// @@ -233,7 +233,7 @@ template class CallDescriptionMap { /// exists only when that is not available, for example, when _only_ /// syntactic check is done on a piece of code. /// - /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade + /// Also, StdLibraryFunctionsChecker::Signature is likely a better candidate /// for syntactic only matching if you are writing a new checker. This is /// handy if a CallDescriptionMap is already there. /// @@ -274,7 +274,7 @@ class CallDescriptionSet { /// exists only when that is not available, for example, when _only_ /// syntactic check is done on a piece of code. /// - /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade + /// Also, StdLibraryFunctionsChecker::Signature is likely a better candidate /// for syntactic only matching if you are writing a new checker. This is /// handy if a CallDescriptionMap is already there. /// diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index f88bf70d72398..796fb43a2fc66 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -344,7 +344,7 @@ class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { }; /// The region containing globals which can be modified by calls to -/// "internally" defined functions - (for now just) functions other then system +/// "internally" defined functions - (for now just) functions other than system /// calls. class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { friend class MemRegionManager; @@ -1021,7 +1021,7 @@ class NonParamVarRegion : public VarRegion { } }; -/// ParamVarRegion - Represents a region for paremters. Only parameters of the +/// ParamVarRegion - Represents a region for parameters. Only parameters of the /// function in the current stack frame are represented as `ParamVarRegion`s. /// Parameters of top-level analyzed functions as well as captured paremeters /// by lambdas and blocks are repesented as `VarRegion`s. diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h index 7cfb24e5e649d..e084a13995306 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h @@ -353,12 +353,7 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager { addStateConstraints(NewState); std::optional res = Solver->check(); - if (!res) - Cached[hash] = ConditionTruthVal(); - else - Cached[hash] = ConditionTruthVal(*res); - - return Cached[hash]; + return Cached[hash] = res ? ConditionTruthVal(*res) : ConditionTruthVal(); } // Cache the result of an SMT query (true, false, unknown). The key is the diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h index 4a343f2872d8d..f002f8645d3f6 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h @@ -55,15 +55,18 @@ enum class ScanningOptimizations { HeaderSearch = 1, /// Remove warnings from system modules. - SystemWarnings = 2, + SystemWarnings = (1 << 1), /// Remove unused -ivfsoverlay arguments. - VFS = 4, + VFS = (1 << 2), /// Canonicalize -D and -U options. - Macros = 8, + Macros = (1 << 3), - DSS_LAST_BITMASK_ENUM(Macros), + /// Ignore the compiler's working directory if it is safe. + IgnoreCWD = (1 << 4), + + DSS_LAST_BITMASK_ENUM(IgnoreCWD), Default = All }; diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index ddb078dc16e3c..bcc9ea17e2588 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -128,14 +128,17 @@ class DependencyScanningTool { /// \param LookupModuleOutput This function is called to fill in /// "-fmodule-file=", "-o" and other output /// arguments for dependencies. + /// \param TUBuffer Optional memory buffer for translation unit input. If + /// TUBuffer is nullopt, the input should be included in the + /// Commandline already. /// /// \returns a \c StringError with the diagnostic output if clang errors /// occurred, \c TranslationUnitDeps otherwise. - llvm::Expected - getTranslationUnitDependencies(const std::vector &CommandLine, - StringRef CWD, - const llvm::DenseSet &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput); + llvm::Expected getTranslationUnitDependencies( + const std::vector &CommandLine, StringRef CWD, + const llvm::DenseSet &AlreadySeen, + LookupModuleOutputCallback LookupModuleOutput, + std::optional TUBuffer = std::nullopt); /// Given a compilation context specified via the Clang driver command-line, /// gather modular dependencies of module with the given name, and return the diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h index da6e0401411a3..ee7582b851020 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -17,6 +17,7 @@ #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBufferRef.h" #include #include @@ -83,9 +84,21 @@ class DependencyScanningWorker { llvm::IntrusiveRefCntPtr FS); /// Run the dependency scanning tool for a given clang driver command-line, - /// and report the discovered dependencies to the provided consumer. If \p - /// ModuleName isn't empty, this function reports the dependencies of module - /// \p ModuleName. + /// and report the discovered dependencies to the provided consumer. If + /// TUBuffer is not nullopt, it is used as TU input for the dependency + /// scanning. Otherwise, the input should be included as part of the + /// command-line. + /// + /// \returns false if clang errors occurred (with diagnostics reported to + /// \c DiagConsumer), true otherwise. + bool computeDependencies( + StringRef WorkingDirectory, const std::vector &CommandLine, + DependencyConsumer &DepConsumer, DependencyActionController &Controller, + DiagnosticConsumer &DiagConsumer, + std::optional TUBuffer = std::nullopt); + + /// Run the dependency scanning tool for a given clang driver command-line + /// for a specific module. /// /// \returns false if clang errors occurred (with diagnostics reported to /// \c DiagConsumer), true otherwise. @@ -94,13 +107,28 @@ class DependencyScanningWorker { DependencyConsumer &DepConsumer, DependencyActionController &Controller, DiagnosticConsumer &DiagConsumer, - std::optional ModuleName = std::nullopt); + StringRef ModuleName); + + /// Run the dependency scanning tool for a given clang driver command-line + /// for a specific translation unit via file system or memory buffer. + /// /// \returns A \c StringError with the diagnostic output if clang errors /// occurred, success otherwise. llvm::Error computeDependencies( StringRef WorkingDirectory, const std::vector &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, - std::optional ModuleName = std::nullopt); + std::optional TUBuffer = std::nullopt); + + /// Run the dependency scanning tool for a given clang driver command-line + /// for a specific module. + /// + /// \returns A \c StringError with the diagnostic output if clang errors + /// occurred, success otherwise. + llvm::Error computeDependencies(StringRef WorkingDirectory, + const std::vector &CommandLine, + DependencyConsumer &Consumer, + DependencyActionController &Controller, + StringRef ModuleName); bool shouldEagerLoadModules() const { return EagerLoadModules; } @@ -121,6 +149,15 @@ class DependencyScanningWorker { ScanningOptimizations OptimizeArgs; /// Whether to set up command-lines to load PCM files eagerly. bool EagerLoadModules; + + /// Private helper functions. + bool scanDependencies(StringRef WorkingDirectory, + const std::vector &CommandLine, + DependencyConsumer &Consumer, + DependencyActionController &Controller, + DiagnosticConsumer &DC, + llvm::IntrusiveRefCntPtr FS, + std::optional ModuleName); }; } // end namespace dependencies diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap index f00dede7fd526..fb8e445cb4b72 100644 --- a/clang/include/module.modulemap +++ b/clang/include/module.modulemap @@ -44,20 +44,12 @@ module Clang_Basic { textual header "clang/Basic/BuiltinsAArch64NeonSVEBridge_cg.def" textual header "clang/Basic/BuiltinsAMDGPU.def" textual header "clang/Basic/BuiltinsARM.def" - textual header "clang/Basic/BuiltinsHexagon.def" - textual header "clang/Basic/BuiltinsHexagonDep.def" textual header "clang/Basic/BuiltinsHexagonMapCustomDep.def" - textual header "clang/Basic/BuiltinsLoongArch.def" textual header "clang/Basic/BuiltinsLoongArchBase.def" textual header "clang/Basic/BuiltinsLoongArchLASX.def" textual header "clang/Basic/BuiltinsLoongArchLSX.def" textual header "clang/Basic/BuiltinsMips.def" - textual header "clang/Basic/BuiltinsNEON.def" - textual header "clang/Basic/BuiltinsNVPTX.def" textual header "clang/Basic/BuiltinsPPC.def" - textual header "clang/Basic/BuiltinsRISCVVector.def" - textual header "clang/Basic/BuiltinsSME.def" - textual header "clang/Basic/BuiltinsSVE.def" textual header "clang/Basic/BuiltinsSystemZ.def" textual header "clang/Basic/BuiltinsVE.def" textual header "clang/Basic/BuiltinsVEVL.gen.def" @@ -116,6 +108,8 @@ module Clang_Diagnostics { module Parse { header "clang/Basic/DiagnosticParse.h" export * } module Serialization { header "clang/Serialization/SerializationDiagnostic.h" export * } module Refactoring { header "clang/Tooling/Refactoring/RefactoringDiagnostic.h" export * } + + textual header "clang/Basic/AllDiagnosticKinds.inc" } module Clang_Driver { diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index 70d96c735503f..7f8a126ffaa03 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -56,7 +56,7 @@ APINotesManager::APINotesManager(SourceManager &SM, const LangOptions &LangOpts) APINotesManager::~APINotesManager() { // Free the API notes readers. for (const auto &Entry : Readers) { - if (auto Reader = Entry.second.dyn_cast()) + if (auto Reader = dyn_cast_if_present(Entry.second)) delete Reader; } @@ -381,7 +381,7 @@ APINotesManager::findAPINotes(SourceLocation Loc) { } // We have the answer. - if (auto Reader = Known->second.dyn_cast()) + if (auto Reader = dyn_cast_if_present(Known->second)) Results.push_back(Reader); break; } diff --git a/clang/lib/ARCMigrate/ARCMT.cpp b/clang/lib/ARCMigrate/ARCMT.cpp deleted file mode 100644 index 1a8a200f2fc19..0000000000000 --- a/clang/lib/ARCMigrate/ARCMT.cpp +++ /dev/null @@ -1,616 +0,0 @@ -//===--- ARCMT.cpp - Migration to ARC mode --------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/ARCMigrate/ARCMT.h" -#include "Internals.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/Basic/DiagnosticCategories.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendAction.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/Utils.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "clang/Serialization/ASTReader.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/TargetParser/Triple.h" -#include -using namespace clang; -using namespace arcmt; - -bool CapturedDiagList::clearDiagnostic(ArrayRef IDs, - SourceRange range) { - if (range.isInvalid()) - return false; - - bool cleared = false; - ListTy::iterator I = List.begin(); - while (I != List.end()) { - FullSourceLoc diagLoc = I->getLocation(); - if ((IDs.empty() || // empty means clear all diagnostics in the range. - llvm::is_contained(IDs, I->getID())) && - !diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) && - (diagLoc == range.getEnd() || - diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) { - cleared = true; - ListTy::iterator eraseS = I++; - if (eraseS->getLevel() != DiagnosticsEngine::Note) - while (I != List.end() && I->getLevel() == DiagnosticsEngine::Note) - ++I; - // Clear the diagnostic and any notes following it. - I = List.erase(eraseS, I); - continue; - } - - ++I; - } - - return cleared; -} - -bool CapturedDiagList::hasDiagnostic(ArrayRef IDs, - SourceRange range) const { - if (range.isInvalid()) - return false; - - ListTy::const_iterator I = List.begin(); - while (I != List.end()) { - FullSourceLoc diagLoc = I->getLocation(); - if ((IDs.empty() || // empty means any diagnostic in the range. - llvm::is_contained(IDs, I->getID())) && - !diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) && - (diagLoc == range.getEnd() || - diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) { - return true; - } - - ++I; - } - - return false; -} - -void CapturedDiagList::reportDiagnostics(DiagnosticsEngine &Diags) const { - for (ListTy::const_iterator I = List.begin(), E = List.end(); I != E; ++I) - Diags.Report(*I); -} - -bool CapturedDiagList::hasErrors() const { - for (ListTy::const_iterator I = List.begin(), E = List.end(); I != E; ++I) - if (I->getLevel() >= DiagnosticsEngine::Error) - return true; - - return false; -} - -namespace { - -class CaptureDiagnosticConsumer : public DiagnosticConsumer { - DiagnosticsEngine &Diags; - DiagnosticConsumer &DiagClient; - CapturedDiagList &CapturedDiags; - bool HasBegunSourceFile; -public: - CaptureDiagnosticConsumer(DiagnosticsEngine &diags, - DiagnosticConsumer &client, - CapturedDiagList &capturedDiags) - : Diags(diags), DiagClient(client), CapturedDiags(capturedDiags), - HasBegunSourceFile(false) { } - - void BeginSourceFile(const LangOptions &Opts, - const Preprocessor *PP) override { - // Pass BeginSourceFile message onto DiagClient on first call. - // The corresponding EndSourceFile call will be made from an - // explicit call to FinishCapture. - if (!HasBegunSourceFile) { - DiagClient.BeginSourceFile(Opts, PP); - HasBegunSourceFile = true; - } - } - - void FinishCapture() { - // Call EndSourceFile on DiagClient on completion of capture to - // enable VerifyDiagnosticConsumer to check diagnostics *after* - // it has received the diagnostic list. - if (HasBegunSourceFile) { - DiagClient.EndSourceFile(); - HasBegunSourceFile = false; - } - } - - ~CaptureDiagnosticConsumer() override { - assert(!HasBegunSourceFile && "FinishCapture not called!"); - } - - void HandleDiagnostic(DiagnosticsEngine::Level level, - const Diagnostic &Info) override { - if (DiagnosticIDs::isARCDiagnostic(Info.getID()) || - level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) { - if (Info.getLocation().isValid()) - CapturedDiags.push_back(StoredDiagnostic(level, Info)); - return; - } - - // Non-ARC warnings are ignored. - Diags.setLastDiagnosticIgnored(true); - } -}; - -} // end anonymous namespace - -static bool HasARCRuntime(CompilerInvocation &origCI) { - // This duplicates some functionality from Darwin::AddDeploymentTarget - // but this function is well defined, so keep it decoupled from the driver - // and avoid unrelated complications. - llvm::Triple triple(origCI.getTargetOpts().Triple); - - if (triple.isiOS()) - return triple.getOSMajorVersion() >= 5; - - if (triple.isWatchOS()) - return true; - - if (triple.getOS() == llvm::Triple::Darwin) - return triple.getOSMajorVersion() >= 11; - - if (triple.getOS() == llvm::Triple::MacOSX) { - return triple.getOSVersion() >= VersionTuple(10, 7); - } - - return false; -} - -static CompilerInvocation * -createInvocationForMigration(CompilerInvocation &origCI, - const PCHContainerReader &PCHContainerRdr) { - std::unique_ptr CInvok; - CInvok.reset(new CompilerInvocation(origCI)); - PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts(); - if (!PPOpts.ImplicitPCHInclude.empty()) { - // We can't use a PCH because it was likely built in non-ARC mode and we - // want to parse in ARC. Include the original header. - FileManager FileMgr(origCI.getFileSystemOpts()); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), - new IgnoringDiagConsumer())); - std::string OriginalFile = ASTReader::getOriginalSourceFile( - PPOpts.ImplicitPCHInclude, FileMgr, PCHContainerRdr, *Diags); - if (!OriginalFile.empty()) - PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile); - PPOpts.ImplicitPCHInclude.clear(); - } - std::string define = std::string(getARCMTMacroName()); - define += '='; - CInvok->getPreprocessorOpts().addMacroDef(define); - CInvok->getLangOpts().ObjCAutoRefCount = true; - CInvok->getLangOpts().setGC(LangOptions::NonGC); - CInvok->getDiagnosticOpts().ErrorLimit = 0; - CInvok->getDiagnosticOpts().PedanticErrors = 0; - - // Ignore -Werror flags when migrating. - std::vector WarnOpts; - for (std::vector::iterator - I = CInvok->getDiagnosticOpts().Warnings.begin(), - E = CInvok->getDiagnosticOpts().Warnings.end(); I != E; ++I) { - if (!StringRef(*I).starts_with("error")) - WarnOpts.push_back(*I); - } - WarnOpts.push_back("error=arc-unsafe-retained-assign"); - CInvok->getDiagnosticOpts().Warnings = std::move(WarnOpts); - - CInvok->getLangOpts().ObjCWeakRuntime = HasARCRuntime(origCI); - CInvok->getLangOpts().ObjCWeak = CInvok->getLangOpts().ObjCWeakRuntime; - - return CInvok.release(); -} - -static void emitPremigrationErrors(const CapturedDiagList &arcDiags, - DiagnosticOptions *diagOpts, - Preprocessor &PP) { - TextDiagnosticPrinter printer(llvm::errs(), diagOpts); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, diagOpts, &printer, - /*ShouldOwnClient=*/false)); - Diags->setSourceManager(&PP.getSourceManager()); - - printer.BeginSourceFile(PP.getLangOpts(), &PP); - arcDiags.reportDiagnostics(*Diags); - printer.EndSourceFile(); -} - -//===----------------------------------------------------------------------===// -// checkForManualIssues. -//===----------------------------------------------------------------------===// - -bool arcmt::checkForManualIssues( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, bool emitPremigrationARCErrors, - StringRef plistOut) { - if (!origCI.getLangOpts().ObjC) - return false; - - LangOptions::GCMode OrigGCMode = origCI.getLangOpts().getGC(); - bool NoNSAllocReallocError = origCI.getMigratorOpts().NoNSAllocReallocError; - bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval; - - std::vector transforms = arcmt::getAllTransformations(OrigGCMode, - NoFinalizeRemoval); - assert(!transforms.empty()); - - std::unique_ptr CInvok; - CInvok.reset( - createInvocationForMigration(origCI, PCHContainerOps->getRawReader())); - CInvok->getFrontendOpts().Inputs.clear(); - CInvok->getFrontendOpts().Inputs.push_back(Input); - - CapturedDiagList capturedDiags; - - assert(DiagClient); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), - DiagClient, /*ShouldOwnClient=*/false)); - - // Filter of all diagnostics. - CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags); - Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - - std::unique_ptr Unit(ASTUnit::LoadFromCompilerInvocationAction( - std::move(CInvok), PCHContainerOps, Diags)); - if (!Unit) { - errRec.FinishCapture(); - return true; - } - - // Don't filter diagnostics anymore. - Diags->setClient(DiagClient, /*ShouldOwnClient=*/false); - - ASTContext &Ctx = Unit->getASTContext(); - - if (Diags->hasFatalErrorOccurred()) { - Diags->Reset(); - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - capturedDiags.reportDiagnostics(*Diags); - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - return true; - } - - if (emitPremigrationARCErrors) - emitPremigrationErrors(capturedDiags, &origCI.getDiagnosticOpts(), - Unit->getPreprocessor()); - if (!plistOut.empty()) { - SmallVector arcDiags; - for (CapturedDiagList::iterator - I = capturedDiags.begin(), E = capturedDiags.end(); I != E; ++I) - arcDiags.push_back(*I); - writeARCDiagsToPlist(std::string(plistOut), arcDiags, - Ctx.getSourceManager(), Ctx.getLangOpts()); - } - - // After parsing of source files ended, we want to reuse the - // diagnostics objects to emit further diagnostics. - // We call BeginSourceFile because DiagnosticConsumer requires that - // diagnostics with source range information are emitted only in between - // BeginSourceFile() and EndSourceFile(). - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - - // No macros will be added since we are just checking and we won't modify - // source code. - std::vector ARCMTMacroLocs; - - TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); - MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, capturedDiags, - ARCMTMacroLocs); - pass.setNoFinalizeRemoval(NoFinalizeRemoval); - if (!NoNSAllocReallocError) - Diags->setSeverity(diag::warn_arcmt_nsalloc_realloc, diag::Severity::Error, - SourceLocation()); - - for (unsigned i=0, e = transforms.size(); i != e; ++i) - transforms[i](pass); - - capturedDiags.reportDiagnostics(*Diags); - - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - - return capturedDiags.hasErrors() || testAct.hasReportedErrors(); -} - -//===----------------------------------------------------------------------===// -// applyTransformations. -//===----------------------------------------------------------------------===// - -static bool -applyTransforms(CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, StringRef outputDir, - bool emitPremigrationARCErrors, StringRef plistOut) { - if (!origCI.getLangOpts().ObjC) - return false; - - LangOptions::GCMode OrigGCMode = origCI.getLangOpts().getGC(); - - // Make sure checking is successful first. - CompilerInvocation CInvokForCheck(origCI); - if (arcmt::checkForManualIssues(CInvokForCheck, Input, PCHContainerOps, - DiagClient, emitPremigrationARCErrors, - plistOut)) - return true; - - CompilerInvocation CInvok(origCI); - CInvok.getFrontendOpts().Inputs.clear(); - CInvok.getFrontendOpts().Inputs.push_back(Input); - - MigrationProcess migration(CInvok, PCHContainerOps, DiagClient, outputDir); - bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval; - - std::vector transforms = arcmt::getAllTransformations(OrigGCMode, - NoFinalizeRemoval); - assert(!transforms.empty()); - - for (unsigned i=0, e = transforms.size(); i != e; ++i) { - bool err = migration.applyTransform(transforms[i]); - if (err) return true; - } - - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(), - DiagClient, /*ShouldOwnClient=*/false)); - - if (outputDir.empty()) { - origCI.getLangOpts().ObjCAutoRefCount = true; - return migration.getRemapper().overwriteOriginal(*Diags); - } else { - return migration.getRemapper().flushToDisk(outputDir, *Diags); - } -} - -bool arcmt::applyTransformations( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient) { - return applyTransforms(origCI, Input, PCHContainerOps, DiagClient, - StringRef(), false, StringRef()); -} - -bool arcmt::migrateWithTemporaryFiles( - CompilerInvocation &origCI, const FrontendInputFile &Input, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *DiagClient, StringRef outputDir, - bool emitPremigrationARCErrors, StringRef plistOut) { - assert(!outputDir.empty() && "Expected output directory path"); - return applyTransforms(origCI, Input, PCHContainerOps, DiagClient, outputDir, - emitPremigrationARCErrors, plistOut); -} - -bool arcmt::getFileRemappings(std::vector > & - remap, - StringRef outputDir, - DiagnosticConsumer *DiagClient) { - assert(!outputDir.empty()); - - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, new DiagnosticOptions, - DiagClient, /*ShouldOwnClient=*/false)); - - FileRemapper remapper; - bool err = remapper.initFromDisk(outputDir, *Diags, - /*ignoreIfFilesChanged=*/true); - if (err) - return true; - - remapper.forEachMapping( - [&](StringRef From, StringRef To) { - remap.push_back(std::make_pair(From.str(), To.str())); - }, - [](StringRef, const llvm::MemoryBufferRef &) {}); - - return false; -} - - -//===----------------------------------------------------------------------===// -// CollectTransformActions. -//===----------------------------------------------------------------------===// - -namespace { - -class ARCMTMacroTrackerPPCallbacks : public PPCallbacks { - std::vector &ARCMTMacroLocs; - -public: - ARCMTMacroTrackerPPCallbacks(std::vector &ARCMTMacroLocs) - : ARCMTMacroLocs(ARCMTMacroLocs) { } - - void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, - SourceRange Range, const MacroArgs *Args) override { - if (MacroNameTok.getIdentifierInfo()->getName() == getARCMTMacroName()) - ARCMTMacroLocs.push_back(MacroNameTok.getLocation()); - } -}; - -class ARCMTMacroTrackerAction : public ASTFrontendAction { - std::vector &ARCMTMacroLocs; - -public: - ARCMTMacroTrackerAction(std::vector &ARCMTMacroLocs) - : ARCMTMacroLocs(ARCMTMacroLocs) { } - - std::unique_ptr CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) override { - CI.getPreprocessor().addPPCallbacks( - std::make_unique(ARCMTMacroLocs)); - return std::make_unique(); - } -}; - -class RewritesApplicator : public TransformActions::RewriteReceiver { - Rewriter &rewriter; - MigrationProcess::RewriteListener *Listener; - -public: - RewritesApplicator(Rewriter &rewriter, ASTContext &ctx, - MigrationProcess::RewriteListener *listener) - : rewriter(rewriter), Listener(listener) { - if (Listener) - Listener->start(ctx); - } - ~RewritesApplicator() override { - if (Listener) - Listener->finish(); - } - - void insert(SourceLocation loc, StringRef text) override { - bool err = rewriter.InsertText(loc, text, /*InsertAfter=*/true, - /*indentNewLines=*/true); - if (!err && Listener) - Listener->insert(loc, text); - } - - void remove(CharSourceRange range) override { - Rewriter::RewriteOptions removeOpts; - removeOpts.IncludeInsertsAtBeginOfRange = false; - removeOpts.IncludeInsertsAtEndOfRange = false; - removeOpts.RemoveLineIfEmpty = true; - - bool err = rewriter.RemoveText(range, removeOpts); - if (!err && Listener) - Listener->remove(range); - } - - void increaseIndentation(CharSourceRange range, - SourceLocation parentIndent) override { - rewriter.IncreaseIndentation(range, parentIndent); - } -}; - -} // end anonymous namespace. - -/// Anchor for VTable. -MigrationProcess::RewriteListener::~RewriteListener() { } - -MigrationProcess::MigrationProcess( - CompilerInvocation &CI, - std::shared_ptr PCHContainerOps, - DiagnosticConsumer *diagClient, StringRef outputDir) - : OrigCI(CI), PCHContainerOps(std::move(PCHContainerOps)), - DiagClient(diagClient), HadARCErrors(false) { - if (!outputDir.empty()) { - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), - DiagClient, /*ShouldOwnClient=*/false)); - Remapper.initFromDisk(outputDir, *Diags, /*ignoreIfFilesChanged=*/true); - } -} - -bool MigrationProcess::applyTransform(TransformFn trans, - RewriteListener *listener) { - std::unique_ptr CInvok; - CInvok.reset( - createInvocationForMigration(OrigCI, PCHContainerOps->getRawReader())); - CInvok->getDiagnosticOpts().IgnoreWarnings = true; - - Remapper.applyMappings(CInvok->getPreprocessorOpts()); - - CapturedDiagList capturedDiags; - std::vector ARCMTMacroLocs; - - assert(DiagClient); - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, new DiagnosticOptions, - DiagClient, /*ShouldOwnClient=*/false)); - - // Filter of all diagnostics. - CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags); - Diags->setClient(&errRec, /*ShouldOwnClient=*/false); - - std::unique_ptr ASTAction; - ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs)); - - std::unique_ptr Unit(ASTUnit::LoadFromCompilerInvocationAction( - std::move(CInvok), PCHContainerOps, Diags, ASTAction.get())); - if (!Unit) { - errRec.FinishCapture(); - return true; - } - Unit->setOwnsRemappedFileBuffers(false); // FileRemapper manages that. - - HadARCErrors = HadARCErrors || capturedDiags.hasErrors(); - - // Don't filter diagnostics anymore. - Diags->setClient(DiagClient, /*ShouldOwnClient=*/false); - - ASTContext &Ctx = Unit->getASTContext(); - - if (Diags->hasFatalErrorOccurred()) { - Diags->Reset(); - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - capturedDiags.reportDiagnostics(*Diags); - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - return true; - } - - // After parsing of source files ended, we want to reuse the - // diagnostics objects to emit further diagnostics. - // We call BeginSourceFile because DiagnosticConsumer requires that - // diagnostics with source range information are emitted only in between - // BeginSourceFile() and EndSourceFile(). - DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor()); - - Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); - TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor()); - MigrationPass pass(Ctx, OrigCI.getLangOpts().getGC(), - Unit->getSema(), TA, capturedDiags, ARCMTMacroLocs); - - trans(pass); - - { - RewritesApplicator applicator(rewriter, Ctx, listener); - TA.applyRewrites(applicator); - } - - DiagClient->EndSourceFile(); - errRec.FinishCapture(); - - if (DiagClient->getNumErrors()) - return true; - - for (Rewriter::buffer_iterator - I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { - FileID FID = I->first; - llvm::RewriteBuffer &buf = I->second; - OptionalFileEntryRef file = - Ctx.getSourceManager().getFileEntryRefForID(FID); - assert(file); - std::string newFname = std::string(file->getName()); - newFname += "-trans"; - SmallString<512> newText; - llvm::raw_svector_ostream vecOS(newText); - buf.write(vecOS); - std::unique_ptr memBuf( - llvm::MemoryBuffer::getMemBufferCopy(newText.str(), newFname)); - SmallString<64> filePath(file->getName()); - Unit->getFileManager().FixupRelativePath(filePath); - Remapper.remap(filePath.str(), std::move(memBuf)); - } - - return false; -} diff --git a/clang/lib/ARCMigrate/ARCMTActions.cpp b/clang/lib/ARCMigrate/ARCMTActions.cpp deleted file mode 100644 index 0805d90d25aa6..0000000000000 --- a/clang/lib/ARCMigrate/ARCMTActions.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//===--- ARCMTActions.cpp - ARC Migrate Tool Frontend Actions ---*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/ARCMigrate/ARCMTActions.h" -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/Frontend/CompilerInstance.h" - -using namespace clang; -using namespace arcmt; - -bool CheckAction::BeginInvocation(CompilerInstance &CI) { - if (arcmt::checkForManualIssues(CI.getInvocation(), getCurrentInput(), - CI.getPCHContainerOperations(), - CI.getDiagnostics().getClient())) - return false; // errors, stop the action. - - // We only want to see warnings reported from arcmt::checkForManualIssues. - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -CheckAction::CheckAction(std::unique_ptr WrappedAction) - : WrapperFrontendAction(std::move(WrappedAction)) {} - -bool ModifyAction::BeginInvocation(CompilerInstance &CI) { - return !arcmt::applyTransformations(CI.getInvocation(), getCurrentInput(), - CI.getPCHContainerOperations(), - CI.getDiagnostics().getClient()); -} - -ModifyAction::ModifyAction(std::unique_ptr WrappedAction) - : WrapperFrontendAction(std::move(WrappedAction)) {} - -bool MigrateAction::BeginInvocation(CompilerInstance &CI) { - if (arcmt::migrateWithTemporaryFiles( - CI.getInvocation(), getCurrentInput(), CI.getPCHContainerOperations(), - CI.getDiagnostics().getClient(), MigrateDir, EmitPremigrationARCErrors, - PlistOut)) - return false; // errors, stop the action. - - // We only want to see diagnostics emitted by migrateWithTemporaryFiles. - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -MigrateAction::MigrateAction(std::unique_ptr WrappedAction, - StringRef migrateDir, - StringRef plistOut, - bool emitPremigrationARCErrors) - : WrapperFrontendAction(std::move(WrappedAction)), MigrateDir(migrateDir), - PlistOut(plistOut), EmitPremigrationARCErrors(emitPremigrationARCErrors) { - if (MigrateDir.empty()) - MigrateDir = "."; // user current directory if none is given. -} diff --git a/clang/lib/ARCMigrate/CMakeLists.txt b/clang/lib/ARCMigrate/CMakeLists.txt deleted file mode 100644 index 515d0960920af..0000000000000 --- a/clang/lib/ARCMigrate/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -set(LLVM_LINK_COMPONENTS - Support - TargetParser - ) - -# By default MSVC has a 2^16 limit on the number of sections in an object -# file, and Transforms.cpp needs more than that. -if (MSVC) - set_source_files_properties(Transforms.cpp PROPERTIES COMPILE_FLAGS /bigobj) -endif() - -add_clang_library(clangARCMigrate - ARCMT.cpp - ARCMTActions.cpp - FileRemapper.cpp - ObjCMT.cpp - PlistReporter.cpp - TransAPIUses.cpp - TransARCAssign.cpp - TransAutoreleasePool.cpp - TransBlockObjCVariable.cpp - TransEmptyStatementsAndDealloc.cpp - TransGCAttrs.cpp - TransGCCalls.cpp - TransProperties.cpp - TransProtectedScope.cpp - TransRetainReleaseDealloc.cpp - TransUnbridgedCasts.cpp - TransUnusedInitDelegate.cpp - TransZeroOutPropsInDealloc.cpp - TransformActions.cpp - Transforms.cpp - - LINK_LIBS - clangAST - clangAnalysis - clangBasic - clangEdit - clangFrontend - clangLex - clangRewrite - clangSema - clangSerialization - - DEPENDS - omp_gen - ClangDriverOptions - ) diff --git a/clang/lib/ARCMigrate/FileRemapper.cpp b/clang/lib/ARCMigrate/FileRemapper.cpp deleted file mode 100644 index 84024c3bafdca..0000000000000 --- a/clang/lib/ARCMigrate/FileRemapper.cpp +++ /dev/null @@ -1,274 +0,0 @@ -//===--- FileRemapper.cpp - File Remapping Helper -------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "clang/ARCMigrate/FileRemapper.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Basic/FileManager.h" -#include "clang/Lex/PreprocessorOptions.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" -#include - -using namespace clang; -using namespace arcmt; - -FileRemapper::FileRemapper() { - FileMgr.reset(new FileManager(FileSystemOptions())); -} - -FileRemapper::~FileRemapper() { - clear(); -} - -void FileRemapper::clear(StringRef outputDir) { - for (MappingsTy::iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) - resetTarget(I->second); - FromToMappings.clear(); - assert(ToFromMappings.empty()); - if (!outputDir.empty()) { - std::string infoFile = getRemapInfoFile(outputDir); - llvm::sys::fs::remove(infoFile); - } -} - -std::string FileRemapper::getRemapInfoFile(StringRef outputDir) { - assert(!outputDir.empty()); - SmallString<128> InfoFile = outputDir; - llvm::sys::path::append(InfoFile, "remap"); - return std::string(InfoFile); -} - -bool FileRemapper::initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged) { - std::string infoFile = getRemapInfoFile(outputDir); - return initFromFile(infoFile, Diag, ignoreIfFilesChanged); -} - -bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag, - bool ignoreIfFilesChanged) { - assert(FromToMappings.empty() && - "initFromDisk should be called before any remap calls"); - std::string infoFile = std::string(filePath); - if (!llvm::sys::fs::exists(infoFile)) - return false; - - std::vector> pairs; - - llvm::ErrorOr> fileBuf = - llvm::MemoryBuffer::getFile(infoFile, /*IsText=*/true); - if (!fileBuf) - return report("Error opening file: " + infoFile, Diag); - - SmallVector lines; - fileBuf.get()->getBuffer().split(lines, "\n"); - - for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) { - StringRef fromFilename = lines[idx]; - unsigned long long timeModified; - if (lines[idx+1].getAsInteger(10, timeModified)) - return report("Invalid file data: '" + lines[idx+1] + "' not a number", - Diag); - StringRef toFilename = lines[idx+2]; - - auto origFE = FileMgr->getOptionalFileRef(fromFilename); - if (!origFE) { - if (ignoreIfFilesChanged) - continue; - return report("File does not exist: " + fromFilename, Diag); - } - auto newFE = FileMgr->getOptionalFileRef(toFilename); - if (!newFE) { - if (ignoreIfFilesChanged) - continue; - return report("File does not exist: " + toFilename, Diag); - } - - if ((uint64_t)origFE->getModificationTime() != timeModified) { - if (ignoreIfFilesChanged) - continue; - return report("File was modified: " + fromFilename, Diag); - } - - pairs.push_back(std::make_pair(*origFE, *newFE)); - } - - for (unsigned i = 0, e = pairs.size(); i != e; ++i) - remap(pairs[i].first, pairs[i].second); - - return false; -} - -bool FileRemapper::flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag) { - using namespace llvm::sys; - - if (fs::create_directory(outputDir)) - return report("Could not create directory: " + outputDir, Diag); - - std::string infoFile = getRemapInfoFile(outputDir); - return flushToFile(infoFile, Diag); -} - -bool FileRemapper::flushToFile(StringRef outputPath, DiagnosticsEngine &Diag) { - using namespace llvm::sys; - - std::error_code EC; - std::string infoFile = std::string(outputPath); - llvm::raw_fd_ostream infoOut(infoFile, EC, llvm::sys::fs::OF_Text); - if (EC) - return report(EC.message(), Diag); - - for (MappingsTy::iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) { - - FileEntryRef origFE = I->first; - SmallString<200> origPath = StringRef(origFE.getName()); - fs::make_absolute(origPath); - infoOut << origPath << '\n'; - infoOut << (uint64_t)origFE.getModificationTime() << '\n'; - - if (const auto *FE = std::get_if(&I->second)) { - SmallString<200> newPath = StringRef(FE->getName()); - fs::make_absolute(newPath); - infoOut << newPath << '\n'; - } else { - - SmallString<64> tempPath; - int fd; - if (fs::createTemporaryFile( - path::filename(origFE.getName()), - path::extension(origFE.getName()).drop_front(), fd, tempPath, - llvm::sys::fs::OF_Text)) - return report("Could not create file: " + tempPath.str(), Diag); - - llvm::raw_fd_ostream newOut(fd, /*shouldClose=*/true); - llvm::MemoryBuffer *mem = std::get(I->second); - newOut.write(mem->getBufferStart(), mem->getBufferSize()); - newOut.close(); - - auto newE = FileMgr->getOptionalFileRef(tempPath); - if (newE) { - remap(origFE, *newE); - infoOut << newE->getName() << '\n'; - } - } - } - - infoOut.close(); - return false; -} - -bool FileRemapper::overwriteOriginal(DiagnosticsEngine &Diag, - StringRef outputDir) { - using namespace llvm::sys; - - for (MappingsTy::iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) { - FileEntryRef origFE = I->first; - assert(std::holds_alternative(I->second)); - if (!fs::exists(origFE.getName())) - return report(StringRef("File does not exist: ") + origFE.getName(), - Diag); - - std::error_code EC; - llvm::raw_fd_ostream Out(origFE.getName(), EC, llvm::sys::fs::OF_None); - if (EC) - return report(EC.message(), Diag); - - llvm::MemoryBuffer *mem = std::get(I->second); - Out.write(mem->getBufferStart(), mem->getBufferSize()); - Out.close(); - } - - clear(outputDir); - return false; -} - -void FileRemapper::forEachMapping( - llvm::function_ref CaptureFile, - llvm::function_ref - CaptureBuffer) const { - for (auto &Mapping : FromToMappings) { - if (const auto *FE = std::get_if(&Mapping.second)) { - CaptureFile(Mapping.first.getName(), FE->getName()); - continue; - } - CaptureBuffer( - Mapping.first.getName(), - std::get(Mapping.second)->getMemBufferRef()); - } -} - -void FileRemapper::applyMappings(PreprocessorOptions &PPOpts) const { - for (MappingsTy::const_iterator - I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) { - if (const auto *FE = std::get_if(&I->second)) { - PPOpts.addRemappedFile(I->first.getName(), FE->getName()); - } else { - llvm::MemoryBuffer *mem = std::get(I->second); - PPOpts.addRemappedFile(I->first.getName(), mem); - } - } - - PPOpts.RetainRemappedFileBuffers = true; -} - -void FileRemapper::remap(StringRef filePath, - std::unique_ptr memBuf) { - OptionalFileEntryRef File = getOriginalFile(filePath); - assert(File); - remap(*File, std::move(memBuf)); -} - -void FileRemapper::remap(FileEntryRef File, - std::unique_ptr MemBuf) { - auto [It, New] = FromToMappings.insert({File, nullptr}); - if (!New) - resetTarget(It->second); - It->second = MemBuf.release(); -} - -void FileRemapper::remap(FileEntryRef File, FileEntryRef NewFile) { - auto [It, New] = FromToMappings.insert({File, nullptr}); - if (!New) - resetTarget(It->second); - It->second = NewFile; - ToFromMappings.insert({NewFile, File}); -} - -OptionalFileEntryRef FileRemapper::getOriginalFile(StringRef filePath) { - OptionalFileEntryRef File = FileMgr->getOptionalFileRef(filePath); - if (!File) - return std::nullopt; - // If we are updating a file that overridden an original file, - // actually update the original file. - auto I = ToFromMappings.find(*File); - if (I != ToFromMappings.end()) { - *File = I->second; - assert(FromToMappings.contains(*File) && "Original file not in mappings!"); - } - return File; -} - -void FileRemapper::resetTarget(Target &targ) { - if (std::holds_alternative(targ)) { - llvm::MemoryBuffer *oldmem = std::get(targ); - delete oldmem; - } else { - FileEntryRef toFE = std::get(targ); - ToFromMappings.erase(toFE); - } -} - -bool FileRemapper::report(const Twine &err, DiagnosticsEngine &Diag) { - Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")) - << err.str(); - return true; -} diff --git a/clang/lib/ARCMigrate/Internals.h b/clang/lib/ARCMigrate/Internals.h deleted file mode 100644 index de6ebdce1bea1..0000000000000 --- a/clang/lib/ARCMigrate/Internals.h +++ /dev/null @@ -1,180 +0,0 @@ -//===-- Internals.h - Implementation Details---------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H -#define LLVM_CLANG_LIB_ARCMIGRATE_INTERNALS_H - -#include "clang/Basic/LangOptions.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Frontend/MigratorOptions.h" -#include "llvm/ADT/ArrayRef.h" -#include -#include - -namespace clang { - class ASTContext; - class Sema; - class Stmt; - -namespace arcmt { - -class CapturedDiagList { - typedef std::list ListTy; - ListTy List; - -public: - void push_back(const StoredDiagnostic &diag) { List.push_back(diag); } - - bool clearDiagnostic(ArrayRef IDs, SourceRange range); - bool hasDiagnostic(ArrayRef IDs, SourceRange range) const; - - void reportDiagnostics(DiagnosticsEngine &diags) const; - - bool hasErrors() const; - - typedef ListTy::const_iterator iterator; - iterator begin() const { return List.begin(); } - iterator end() const { return List.end(); } -}; - -void writeARCDiagsToPlist(const std::string &outPath, - ArrayRef diags, - SourceManager &SM, const LangOptions &LangOpts); - -class TransformActions { - DiagnosticsEngine &Diags; - CapturedDiagList &CapturedDiags; - void *Impl; // TransformActionsImpl. - -public: - TransformActions(DiagnosticsEngine &diag, CapturedDiagList &capturedDiags, - ASTContext &ctx, Preprocessor &PP); - ~TransformActions(); - - void startTransaction(); - bool commitTransaction(); - void abortTransaction(); - - void insert(SourceLocation loc, StringRef text); - void insertAfterToken(SourceLocation loc, StringRef text); - void remove(SourceRange range); - void removeStmt(Stmt *S); - void replace(SourceRange range, StringRef text); - void replace(SourceRange range, SourceRange replacementRange); - void replaceStmt(Stmt *S, StringRef text); - void replaceText(SourceLocation loc, StringRef text, - StringRef replacementText); - void increaseIndentation(SourceRange range, - SourceLocation parentIndent); - - bool clearDiagnostic(ArrayRef IDs, SourceRange range); - bool clearAllDiagnostics(SourceRange range) { - return clearDiagnostic({}, range); - } - bool clearDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { - unsigned IDs[] = { ID1, ID2 }; - return clearDiagnostic(IDs, range); - } - bool clearDiagnostic(unsigned ID1, unsigned ID2, unsigned ID3, - SourceRange range) { - unsigned IDs[] = { ID1, ID2, ID3 }; - return clearDiagnostic(IDs, range); - } - - bool hasDiagnostic(unsigned ID, SourceRange range) { - return CapturedDiags.hasDiagnostic(ID, range); - } - - bool hasDiagnostic(unsigned ID1, unsigned ID2, SourceRange range) { - unsigned IDs[] = { ID1, ID2 }; - return CapturedDiags.hasDiagnostic(IDs, range); - } - - DiagnosticBuilder report(SourceLocation loc, unsigned diagId, - SourceRange range = SourceRange()); - void reportError(StringRef error, SourceLocation loc, - SourceRange range = SourceRange()); - void reportWarning(StringRef warning, SourceLocation loc, - SourceRange range = SourceRange()); - void reportNote(StringRef note, SourceLocation loc, - SourceRange range = SourceRange()); - - bool hasReportedErrors() const { - return Diags.hasUnrecoverableErrorOccurred(); - } - - class RewriteReceiver { - public: - virtual ~RewriteReceiver(); - - virtual void insert(SourceLocation loc, StringRef text) = 0; - virtual void remove(CharSourceRange range) = 0; - virtual void increaseIndentation(CharSourceRange range, - SourceLocation parentIndent) = 0; - }; - - void applyRewrites(RewriteReceiver &receiver); -}; - -class Transaction { - TransformActions &TA; - bool Aborted; - -public: - Transaction(TransformActions &TA) : TA(TA), Aborted(false) { - TA.startTransaction(); - } - - ~Transaction() { - if (!isAborted()) - TA.commitTransaction(); - } - - void abort() { - TA.abortTransaction(); - Aborted = true; - } - - bool isAborted() const { return Aborted; } -}; - -class MigrationPass { -public: - ASTContext &Ctx; - LangOptions::GCMode OrigGCMode; - MigratorOptions MigOptions; - Sema &SemaRef; - TransformActions &TA; - const CapturedDiagList &CapturedDiags; - std::vector &ARCMTMacroLocs; - std::optional EnableCFBridgeFns; - - MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode, Sema &sema, - TransformActions &TA, const CapturedDiagList &capturedDiags, - std::vector &ARCMTMacroLocs) - : Ctx(Ctx), OrigGCMode(OrigGCMode), SemaRef(sema), TA(TA), - CapturedDiags(capturedDiags), ARCMTMacroLocs(ARCMTMacroLocs) {} - - const CapturedDiagList &getDiags() const { return CapturedDiags; } - - bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; } - bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; } - void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; } - - bool CFBridgingFunctionsDefined(); -}; - -static inline StringRef getARCMTMacroName() { - return "__IMPL_ARCMT_REMOVED_EXPR__"; -} - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp deleted file mode 100644 index c1bc7c762088f..0000000000000 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ /dev/null @@ -1,2262 +0,0 @@ -//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "clang/Analysis/RetainSummaryManager.h" -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/ARCMigrate/ARCMTActions.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/AST/NSAPI.h" -#include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" -#include "clang/Basic/FileManager.h" -#include "clang/Edit/Commit.h" -#include "clang/Edit/EditedSource.h" -#include "clang/Edit/EditsReceiver.h" -#include "clang/Edit/Rewriters.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/MultiplexConsumer.h" -#include "clang/Lex/PPConditionalDirectiveRecord.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/YAMLParser.h" - -using namespace clang; -using namespace arcmt; -using namespace ento; -using llvm::RewriteBuffer; - -namespace { - -class ObjCMigrateASTConsumer : public ASTConsumer { - enum CF_BRIDGING_KIND { - CF_BRIDGING_NONE, - CF_BRIDGING_ENABLE, - CF_BRIDGING_MAY_INCLUDE - }; - - void migrateDecl(Decl *D); - void migrateObjCContainerDecl(ASTContext &Ctx, ObjCContainerDecl *D); - void migrateProtocolConformance(ASTContext &Ctx, - const ObjCImplementationDecl *ImpDecl); - void CacheObjCNSIntegerTypedefed(const TypedefDecl *TypedefDcl); - bool migrateNSEnumDecl(ASTContext &Ctx, const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl); - void migrateAllMethodInstaceType(ASTContext &Ctx, ObjCContainerDecl *CDecl); - void migrateMethodInstanceType(ASTContext &Ctx, ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM); - bool migrateProperty(ASTContext &Ctx, ObjCContainerDecl *D, ObjCMethodDecl *OM); - void migrateNsReturnsInnerPointer(ASTContext &Ctx, ObjCMethodDecl *OM); - void migratePropertyNsReturnsInnerPointer(ASTContext &Ctx, ObjCPropertyDecl *P); - void migrateFactoryMethod(ASTContext &Ctx, ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM, - ObjCInstanceTypeFamily OIT_Family = OIT_None); - - void migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl); - void AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const FunctionDecl *FuncDecl, bool ResultAnnotated); - void AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const ObjCMethodDecl *MethodDecl, bool ResultAnnotated); - - void AnnotateImplicitBridging(ASTContext &Ctx); - - CF_BRIDGING_KIND migrateAddFunctionAnnotation(ASTContext &Ctx, - const FunctionDecl *FuncDecl); - - void migrateARCSafeAnnotation(ASTContext &Ctx, ObjCContainerDecl *CDecl); - - void migrateAddMethodAnnotation(ASTContext &Ctx, - const ObjCMethodDecl *MethodDecl); - - void inferDesignatedInitializers(ASTContext &Ctx, - const ObjCImplementationDecl *ImplD); - - bool InsertFoundation(ASTContext &Ctx, SourceLocation Loc); - - std::unique_ptr Summaries; - -public: - std::string MigrateDir; - unsigned ASTMigrateActions; - FileID FileId; - const TypedefDecl *NSIntegerTypedefed; - const TypedefDecl *NSUIntegerTypedefed; - std::unique_ptr NSAPIObj; - std::unique_ptr Editor; - FileRemapper &Remapper; - FileManager &FileMgr; - const PPConditionalDirectiveRecord *PPRec; - Preprocessor &PP; - bool IsOutputFile; - bool FoundationIncluded; - llvm::SmallPtrSet ObjCProtocolDecls; - llvm::SmallVector CFFunctionIBCandidates; - llvm::StringSet<> AllowListFilenames; - - RetainSummaryManager &getSummaryManager(ASTContext &Ctx) { - if (!Summaries) - Summaries.reset(new RetainSummaryManager(Ctx, - /*TrackNSCFObjects=*/true, - /*trackOSObjects=*/false)); - return *Summaries; - } - - ObjCMigrateASTConsumer(StringRef migrateDir, unsigned astMigrateActions, - FileRemapper &remapper, FileManager &fileMgr, - const PPConditionalDirectiveRecord *PPRec, - Preprocessor &PP, bool isOutputFile, - ArrayRef AllowList) - : MigrateDir(migrateDir), ASTMigrateActions(astMigrateActions), - NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr), - Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), - IsOutputFile(isOutputFile), FoundationIncluded(false) { - AllowListFilenames.insert(AllowList.begin(), AllowList.end()); - } - -protected: - void Initialize(ASTContext &Context) override { - NSAPIObj.reset(new NSAPI(Context)); - Editor.reset(new edit::EditedSource(Context.getSourceManager(), - Context.getLangOpts(), - PPRec)); - } - - bool HandleTopLevelDecl(DeclGroupRef DG) override { - for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) - migrateDecl(*I); - return true; - } - void HandleInterestingDecl(DeclGroupRef DG) override { - // Ignore decls from the PCH. - } - void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override { - ObjCMigrateASTConsumer::HandleTopLevelDecl(DG); - } - - void HandleTranslationUnit(ASTContext &Ctx) override; - - bool canModifyFile(StringRef Path) { - if (AllowListFilenames.empty()) - return true; - return AllowListFilenames.contains(llvm::sys::path::filename(Path)); - } - bool canModifyFile(OptionalFileEntryRef FE) { - if (!FE) - return false; - return canModifyFile(FE->getName()); - } - bool canModifyFile(FileID FID) { - if (FID.isInvalid()) - return false; - return canModifyFile(PP.getSourceManager().getFileEntryRefForID(FID)); - } - - bool canModify(const Decl *D) { - if (!D) - return false; - if (const ObjCCategoryImplDecl *CatImpl = dyn_cast(D)) - return canModify(CatImpl->getCategoryDecl()); - if (const ObjCImplementationDecl *Impl = dyn_cast(D)) - return canModify(Impl->getClassInterface()); - if (const ObjCMethodDecl *MD = dyn_cast(D)) - return canModify(cast(MD->getDeclContext())); - - FileID FID = PP.getSourceManager().getFileID(D->getLocation()); - return canModifyFile(FID); - } -}; - -} // end anonymous namespace - -ObjCMigrateAction::ObjCMigrateAction( - std::unique_ptr WrappedAction, StringRef migrateDir, - unsigned migrateAction) - : WrapperFrontendAction(std::move(WrappedAction)), MigrateDir(migrateDir), - ObjCMigAction(migrateAction), CompInst(nullptr) { - if (MigrateDir.empty()) - MigrateDir = "."; // user current directory if none is given. -} - -std::unique_ptr -ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - PPConditionalDirectiveRecord * - PPRec = new PPConditionalDirectiveRecord(CompInst->getSourceManager()); - CI.getPreprocessor().addPPCallbacks(std::unique_ptr(PPRec)); - std::vector> Consumers; - Consumers.push_back(WrapperFrontendAction::CreateASTConsumer(CI, InFile)); - Consumers.push_back(std::make_unique( - MigrateDir, ObjCMigAction, Remapper, CompInst->getFileManager(), PPRec, - CompInst->getPreprocessor(), false, std::nullopt)); - return std::make_unique(std::move(Consumers)); -} - -bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) { - Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(), - /*ignoreIfFilesChanged=*/true); - CompInst = &CI; - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -namespace { - // FIXME. This duplicates one in RewriteObjCFoundationAPI.cpp - bool subscriptOperatorNeedsParens(const Expr *FullExpr) { - const Expr* Expr = FullExpr->IgnoreImpCasts(); - return !(isa(Expr) || isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || - isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || isa(Expr) || - isa(Expr) || isa(FullExpr) || - isa(Expr) || isa(Expr)); - } - - /// - Rewrite message expression for Objective-C setter and getters into - /// property-dot syntax. - bool rewriteToPropertyDotSyntax(const ObjCMessageExpr *Msg, - Preprocessor &PP, - const NSAPI &NS, edit::Commit &commit, - const ParentMap *PMap) { - if (!Msg || Msg->isImplicit() || - (Msg->getReceiverKind() != ObjCMessageExpr::Instance && - Msg->getReceiverKind() != ObjCMessageExpr::SuperInstance)) - return false; - if (const Expr *Receiver = Msg->getInstanceReceiver()) - if (Receiver->getType()->isObjCBuiltinType()) - return false; - - const ObjCMethodDecl *Method = Msg->getMethodDecl(); - if (!Method) - return false; - if (!Method->isPropertyAccessor()) - return false; - - const ObjCPropertyDecl *Prop = Method->findPropertyDecl(); - if (!Prop) - return false; - - SourceRange MsgRange = Msg->getSourceRange(); - bool ReceiverIsSuper = - (Msg->getReceiverKind() == ObjCMessageExpr::SuperInstance); - // for 'super' receiver is nullptr. - const Expr *receiver = Msg->getInstanceReceiver(); - bool NeedsParen = - ReceiverIsSuper ? false : subscriptOperatorNeedsParens(receiver); - bool IsGetter = (Msg->getNumArgs() == 0); - if (IsGetter) { - // Find space location range between receiver expression and getter method. - SourceLocation BegLoc = - ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc(); - BegLoc = PP.getLocForEndOfToken(BegLoc); - SourceLocation EndLoc = Msg->getSelectorLoc(0); - SourceRange SpaceRange(BegLoc, EndLoc); - std::string PropertyDotString; - // rewrite getter method expression into: receiver.property or - // (receiver).property - if (NeedsParen) { - commit.insertBefore(receiver->getBeginLoc(), "("); - PropertyDotString = ")."; - } - else - PropertyDotString = "."; - PropertyDotString += Prop->getName(); - commit.replace(SpaceRange, PropertyDotString); - - // remove '[' ']' - commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), ""); - commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), ""); - } else { - if (NeedsParen) - commit.insertWrap("(", receiver->getSourceRange(), ")"); - std::string PropertyDotString = "."; - PropertyDotString += Prop->getName(); - PropertyDotString += " ="; - const Expr*const* Args = Msg->getArgs(); - const Expr *RHS = Args[0]; - if (!RHS) - return false; - SourceLocation BegLoc = - ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc(); - BegLoc = PP.getLocForEndOfToken(BegLoc); - SourceLocation EndLoc = RHS->getBeginLoc(); - EndLoc = EndLoc.getLocWithOffset(-1); - const char *colon = PP.getSourceManager().getCharacterData(EndLoc); - // Add a space after '=' if there is no space between RHS and '=' - if (colon && colon[0] == ':') - PropertyDotString += " "; - SourceRange Range(BegLoc, EndLoc); - commit.replace(Range, PropertyDotString); - // remove '[' ']' - commit.replace(SourceRange(MsgRange.getBegin(), MsgRange.getBegin()), ""); - commit.replace(SourceRange(MsgRange.getEnd(), MsgRange.getEnd()), ""); - } - return true; - } - -class ObjCMigrator : public RecursiveASTVisitor { - ObjCMigrateASTConsumer &Consumer; - ParentMap &PMap; - -public: - ObjCMigrator(ObjCMigrateASTConsumer &consumer, ParentMap &PMap) - : Consumer(consumer), PMap(PMap) { } - - bool shouldVisitTemplateInstantiations() const { return false; } - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Literals) { - edit::Commit commit(*Consumer.Editor); - edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit, &PMap); - Consumer.Editor->commit(commit); - } - - if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_Subscripting) { - edit::Commit commit(*Consumer.Editor); - edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit); - Consumer.Editor->commit(commit); - } - - if (Consumer.ASTMigrateActions & FrontendOptions::ObjCMT_PropertyDotSyntax) { - edit::Commit commit(*Consumer.Editor); - rewriteToPropertyDotSyntax(E, Consumer.PP, *Consumer.NSAPIObj, - commit, &PMap); - Consumer.Editor->commit(commit); - } - - return true; - } - - bool TraverseObjCMessageExpr(ObjCMessageExpr *E) { - // Do depth first; we want to rewrite the subexpressions first so that if - // we have to move expressions we will move them already rewritten. - for (Stmt *SubStmt : E->children()) - if (!TraverseStmt(SubStmt)) - return false; - - return WalkUpFromObjCMessageExpr(E); - } -}; - -class BodyMigrator : public RecursiveASTVisitor { - ObjCMigrateASTConsumer &Consumer; - std::unique_ptr PMap; - -public: - BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { } - - bool shouldVisitTemplateInstantiations() const { return false; } - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool TraverseStmt(Stmt *S) { - PMap.reset(new ParentMap(S)); - ObjCMigrator(Consumer, *PMap).TraverseStmt(S); - return true; - } -}; -} // end anonymous namespace - -void ObjCMigrateASTConsumer::migrateDecl(Decl *D) { - if (!D) - return; - if (isa(D)) - return; // Wait for the ObjC container declaration. - - BodyMigrator(*this).TraverseDecl(D); -} - -static void append_attr(std::string &PropertyString, const char *attr, - bool &LParenAdded) { - if (!LParenAdded) { - PropertyString += "("; - LParenAdded = true; - } - else - PropertyString += ", "; - PropertyString += attr; -} - -static -void MigrateBlockOrFunctionPointerTypeVariable(std::string & PropertyString, - const std::string& TypeString, - const char *name) { - const char *argPtr = TypeString.c_str(); - int paren = 0; - while (*argPtr) { - switch (*argPtr) { - case '(': - PropertyString += *argPtr; - paren++; - break; - case ')': - PropertyString += *argPtr; - paren--; - break; - case '^': - case '*': - PropertyString += (*argPtr); - if (paren == 1) { - PropertyString += name; - name = ""; - } - break; - default: - PropertyString += *argPtr; - break; - } - argPtr++; - } -} - -static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType) { - Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime(); - bool RetainableObject = ArgType->isObjCRetainableType(); - if (RetainableObject && - (propertyLifetime == Qualifiers::OCL_Strong - || propertyLifetime == Qualifiers::OCL_None)) { - if (const ObjCObjectPointerType *ObjPtrTy = - ArgType->getAs()) { - ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); - if (IDecl && - IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying"))) - return "copy"; - else - return "strong"; - } - else if (ArgType->isBlockPointerType()) - return "copy"; - } else if (propertyLifetime == Qualifiers::OCL_Weak) - // TODO. More precise determination of 'weak' attribute requires - // looking into setter's implementation for backing weak ivar. - return "weak"; - else if (RetainableObject) - return ArgType->isBlockPointerType() ? "copy" : "strong"; - return nullptr; -} - -static void rewriteToObjCProperty(const ObjCMethodDecl *Getter, - const ObjCMethodDecl *Setter, - const NSAPI &NS, edit::Commit &commit, - unsigned LengthOfPrefix, - bool Atomic, bool UseNsIosOnlyMacro, - bool AvailabilityArgsMatch) { - ASTContext &Context = NS.getASTContext(); - bool LParenAdded = false; - std::string PropertyString = "@property "; - if (UseNsIosOnlyMacro && NS.isMacroDefined("NS_NONATOMIC_IOSONLY")) { - PropertyString += "(NS_NONATOMIC_IOSONLY"; - LParenAdded = true; - } else if (!Atomic) { - PropertyString += "(nonatomic"; - LParenAdded = true; - } - - std::string PropertyNameString = Getter->getNameAsString(); - StringRef PropertyName(PropertyNameString); - if (LengthOfPrefix > 0) { - if (!LParenAdded) { - PropertyString += "(getter="; - LParenAdded = true; - } - else - PropertyString += ", getter="; - PropertyString += PropertyNameString; - } - // Property with no setter may be suggested as a 'readonly' property. - if (!Setter) - append_attr(PropertyString, "readonly", LParenAdded); - - - // Short circuit 'delegate' properties that contain the name "delegate" or - // "dataSource", or have exact name "target" to have 'assign' attribute. - if (PropertyName == "target" || PropertyName.contains("delegate") || - PropertyName.contains("dataSource")) { - QualType QT = Getter->getReturnType(); - if (!QT->isRealType()) - append_attr(PropertyString, "assign", LParenAdded); - } else if (!Setter) { - QualType ResType = Context.getCanonicalType(Getter->getReturnType()); - if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType)) - append_attr(PropertyString, MemoryManagementAttr, LParenAdded); - } else { - const ParmVarDecl *argDecl = *Setter->param_begin(); - QualType ArgType = Context.getCanonicalType(argDecl->getType()); - if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ArgType)) - append_attr(PropertyString, MemoryManagementAttr, LParenAdded); - } - if (LParenAdded) - PropertyString += ')'; - QualType RT = Getter->getReturnType(); - if (!RT->getAs()) { - // strip off any ARC lifetime qualifier. - QualType CanResultTy = Context.getCanonicalType(RT); - if (CanResultTy.getQualifiers().hasObjCLifetime()) { - Qualifiers Qs = CanResultTy.getQualifiers(); - Qs.removeObjCLifetime(); - RT = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs); - } - } - PropertyString += " "; - PrintingPolicy SubPolicy(Context.getPrintingPolicy()); - SubPolicy.SuppressStrongLifetime = true; - SubPolicy.SuppressLifetimeQualifiers = true; - std::string TypeString = RT.getAsString(SubPolicy); - if (LengthOfPrefix > 0) { - // property name must strip off "is" and lower case the first character - // after that; e.g. isContinuous will become continuous. - StringRef PropertyNameStringRef(PropertyNameString); - PropertyNameStringRef = PropertyNameStringRef.drop_front(LengthOfPrefix); - PropertyNameString = std::string(PropertyNameStringRef); - bool NoLowering = (isUppercase(PropertyNameString[0]) && - PropertyNameString.size() > 1 && - isUppercase(PropertyNameString[1])); - if (!NoLowering) - PropertyNameString[0] = toLowercase(PropertyNameString[0]); - } - if (RT->isBlockPointerType() || RT->isFunctionPointerType()) - MigrateBlockOrFunctionPointerTypeVariable(PropertyString, - TypeString, - PropertyNameString.c_str()); - else { - char LastChar = TypeString[TypeString.size()-1]; - PropertyString += TypeString; - if (LastChar != '*') - PropertyString += ' '; - PropertyString += PropertyNameString; - } - SourceLocation StartGetterSelectorLoc = Getter->getSelectorStartLoc(); - Selector GetterSelector = Getter->getSelector(); - - SourceLocation EndGetterSelectorLoc = - StartGetterSelectorLoc.getLocWithOffset(GetterSelector.getNameForSlot(0).size()); - commit.replace(CharSourceRange::getCharRange(Getter->getBeginLoc(), - EndGetterSelectorLoc), - PropertyString); - if (Setter && AvailabilityArgsMatch) { - SourceLocation EndLoc = Setter->getDeclaratorEndLoc(); - // Get location past ';' - EndLoc = EndLoc.getLocWithOffset(1); - SourceLocation BeginOfSetterDclLoc = Setter->getBeginLoc(); - // FIXME. This assumes that setter decl; is immediately preceded by eoln. - // It is trying to remove the setter method decl. line entirely. - BeginOfSetterDclLoc = BeginOfSetterDclLoc.getLocWithOffset(-1); - commit.remove(SourceRange(BeginOfSetterDclLoc, EndLoc)); - } -} - -static bool IsCategoryNameWithDeprecatedSuffix(ObjCContainerDecl *D) { - if (ObjCCategoryDecl *CatDecl = dyn_cast(D)) { - StringRef Name = CatDecl->getName(); - return Name.ends_with("Deprecated"); - } - return false; -} - -void ObjCMigrateASTConsumer::migrateObjCContainerDecl(ASTContext &Ctx, - ObjCContainerDecl *D) { - if (D->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(D)) - return; - - for (auto *Method : D->methods()) { - if (Method->isDeprecated()) - continue; - bool PropertyInferred = migrateProperty(Ctx, D, Method); - // If a property is inferred, do not attempt to attach NS_RETURNS_INNER_POINTER to - // the getter method as it ends up on the property itself which we don't want - // to do unless -objcmt-returns-innerpointer-property option is on. - if (!PropertyInferred || - (ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty)) - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) - migrateNsReturnsInnerPointer(Ctx, Method); - } - if (!(ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty)) - return; - - for (auto *Prop : D->instance_properties()) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && - !Prop->isDeprecated()) - migratePropertyNsReturnsInnerPointer(Ctx, Prop); - } -} - -static bool -ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, - const ObjCImplementationDecl *ImpDecl, - const ObjCInterfaceDecl *IDecl, - ObjCProtocolDecl *Protocol) { - // In auto-synthesis, protocol properties are not synthesized. So, - // a conforming protocol must have its required properties declared - // in class interface. - bool HasAtleastOneRequiredProperty = false; - if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) - for (const auto *Property : PDecl->instance_properties()) { - if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional) - continue; - HasAtleastOneRequiredProperty = true; - DeclContext::lookup_result R = IDecl->lookup(Property->getDeclName()); - if (R.empty()) { - // Relax the rule and look into class's implementation for a synthesize - // or dynamic declaration. Class is implementing a property coming from - // another protocol. This still makes the target protocol as conforming. - if (!ImpDecl->FindPropertyImplDecl( - Property->getDeclName().getAsIdentifierInfo(), - Property->getQueryKind())) - return false; - } else if (auto *ClassProperty = R.find_first()) { - if ((ClassProperty->getPropertyAttributes() != - Property->getPropertyAttributes()) || - !Ctx.hasSameType(ClassProperty->getType(), Property->getType())) - return false; - } else - return false; - } - - // At this point, all required properties in this protocol conform to those - // declared in the class. - // Check that class implements the required methods of the protocol too. - bool HasAtleastOneRequiredMethod = false; - if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) { - if (PDecl->meth_begin() == PDecl->meth_end()) - return HasAtleastOneRequiredProperty; - for (const auto *MD : PDecl->methods()) { - if (MD->isImplicit()) - continue; - if (MD->getImplementationControl() == ObjCImplementationControl::Optional) - continue; - DeclContext::lookup_result R = ImpDecl->lookup(MD->getDeclName()); - if (R.empty()) - return false; - bool match = false; - HasAtleastOneRequiredMethod = true; - for (NamedDecl *ND : R) - if (ObjCMethodDecl *ImpMD = dyn_cast(ND)) - if (Ctx.ObjCMethodsAreEqual(MD, ImpMD)) { - match = true; - break; - } - if (!match) - return false; - } - } - return HasAtleastOneRequiredProperty || HasAtleastOneRequiredMethod; -} - -static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl, - llvm::SmallVectorImpl &ConformingProtocols, - const NSAPI &NS, edit::Commit &commit) { - const ObjCList &Protocols = IDecl->getReferencedProtocols(); - std::string ClassString; - SourceLocation EndLoc = - IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation(); - - if (Protocols.empty()) { - ClassString = '<'; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - ClassString += ConformingProtocols[i]->getNameAsString(); - if (i != (e-1)) - ClassString += ", "; - } - ClassString += "> "; - } - else { - ClassString = ", "; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - ClassString += ConformingProtocols[i]->getNameAsString(); - if (i != (e-1)) - ClassString += ", "; - } - ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1; - EndLoc = *PL; - } - - commit.insertAfterToken(EndLoc, ClassString); - return true; -} - -static StringRef GetUnsignedName(StringRef NSIntegerName) { - StringRef UnsignedName = llvm::StringSwitch(NSIntegerName) - .Case("int8_t", "uint8_t") - .Case("int16_t", "uint16_t") - .Case("int32_t", "uint32_t") - .Case("NSInteger", "NSUInteger") - .Case("int64_t", "uint64_t") - .Default(NSIntegerName); - return UnsignedName; -} - -static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl, - const NSAPI &NS, edit::Commit &commit, - StringRef NSIntegerName, - bool NSOptions) { - std::string ClassString; - if (NSOptions) { - ClassString = "typedef NS_OPTIONS("; - ClassString += GetUnsignedName(NSIntegerName); - } - else { - ClassString = "typedef NS_ENUM("; - ClassString += NSIntegerName; - } - ClassString += ", "; - - ClassString += TypedefDcl->getIdentifier()->getName(); - ClassString += ')'; - SourceRange R(EnumDcl->getBeginLoc(), EnumDcl->getBeginLoc()); - commit.replace(R, ClassString); - SourceLocation EndOfEnumDclLoc = EnumDcl->getEndLoc(); - EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc, - NS.getASTContext(), /*IsDecl*/true); - if (EndOfEnumDclLoc.isValid()) { - SourceRange EnumDclRange(EnumDcl->getBeginLoc(), EndOfEnumDclLoc); - commit.insertFromRange(TypedefDcl->getBeginLoc(), EnumDclRange); - } - else - return false; - - SourceLocation EndTypedefDclLoc = TypedefDcl->getEndLoc(); - EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc, - NS.getASTContext(), /*IsDecl*/true); - if (EndTypedefDclLoc.isValid()) { - SourceRange TDRange(TypedefDcl->getBeginLoc(), EndTypedefDclLoc); - commit.remove(TDRange); - } - else - return false; - - EndOfEnumDclLoc = - trans::findLocationAfterSemi(EnumDcl->getEndLoc(), NS.getASTContext(), - /*IsDecl*/ true); - if (EndOfEnumDclLoc.isValid()) { - SourceLocation BeginOfEnumDclLoc = EnumDcl->getBeginLoc(); - // FIXME. This assumes that enum decl; is immediately preceded by eoln. - // It is trying to remove the enum decl. lines entirely. - BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1); - commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc)); - return true; - } - return false; -} - -static void rewriteToNSMacroDecl(ASTContext &Ctx, - const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl, - const NSAPI &NS, edit::Commit &commit, - bool IsNSIntegerType) { - QualType DesignatedEnumType = EnumDcl->getIntegerType(); - assert(!DesignatedEnumType.isNull() - && "rewriteToNSMacroDecl - underlying enum type is null"); - - PrintingPolicy Policy(Ctx.getPrintingPolicy()); - std::string TypeString = DesignatedEnumType.getAsString(Policy); - std::string ClassString = IsNSIntegerType ? "NS_ENUM(" : "NS_OPTIONS("; - ClassString += TypeString; - ClassString += ", "; - - ClassString += TypedefDcl->getIdentifier()->getName(); - ClassString += ") "; - SourceLocation EndLoc = EnumDcl->getBraceRange().getBegin(); - if (EndLoc.isInvalid()) - return; - CharSourceRange R = - CharSourceRange::getCharRange(EnumDcl->getBeginLoc(), EndLoc); - commit.replace(R, ClassString); - // This is to remove spaces between '}' and typedef name. - SourceLocation StartTypedefLoc = EnumDcl->getEndLoc(); - StartTypedefLoc = StartTypedefLoc.getLocWithOffset(+1); - SourceLocation EndTypedefLoc = TypedefDcl->getEndLoc(); - - commit.remove(SourceRange(StartTypedefLoc, EndTypedefLoc)); -} - -static bool UseNSOptionsMacro(Preprocessor &PP, ASTContext &Ctx, - const EnumDecl *EnumDcl) { - bool PowerOfTwo = true; - bool AllHexdecimalEnumerator = true; - uint64_t MaxPowerOfTwoVal = 0; - for (auto *Enumerator : EnumDcl->enumerators()) { - const Expr *InitExpr = Enumerator->getInitExpr(); - if (!InitExpr) { - PowerOfTwo = false; - AllHexdecimalEnumerator = false; - continue; - } - InitExpr = InitExpr->IgnoreParenCasts(); - if (const BinaryOperator *BO = dyn_cast(InitExpr)) - if (BO->isShiftOp() || BO->isBitwiseOp()) - return true; - - uint64_t EnumVal = Enumerator->getInitVal().getZExtValue(); - if (PowerOfTwo && EnumVal) { - if (!llvm::isPowerOf2_64(EnumVal)) - PowerOfTwo = false; - else if (EnumVal > MaxPowerOfTwoVal) - MaxPowerOfTwoVal = EnumVal; - } - if (AllHexdecimalEnumerator && EnumVal) { - bool FoundHexdecimalEnumerator = false; - SourceLocation EndLoc = Enumerator->getEndLoc(); - Token Tok; - if (!PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true)) - if (Tok.isLiteral() && Tok.getLength() > 2) { - if (const char *StringLit = Tok.getLiteralData()) - FoundHexdecimalEnumerator = - (StringLit[0] == '0' && (toLowercase(StringLit[1]) == 'x')); - } - if (!FoundHexdecimalEnumerator) - AllHexdecimalEnumerator = false; - } - } - return AllHexdecimalEnumerator || (PowerOfTwo && (MaxPowerOfTwoVal > 2)); -} - -void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx, - const ObjCImplementationDecl *ImpDecl) { - const ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface(); - if (!IDecl || ObjCProtocolDecls.empty() || IDecl->isDeprecated()) - return; - // Find all implicit conforming protocols for this class - // and make them explicit. - llvm::SmallPtrSet ExplicitProtocols; - Ctx.CollectInheritedProtocols(IDecl, ExplicitProtocols); - llvm::SmallVector PotentialImplicitProtocols; - - for (ObjCProtocolDecl *ProtDecl : ObjCProtocolDecls) - if (!ExplicitProtocols.count(ProtDecl)) - PotentialImplicitProtocols.push_back(ProtDecl); - - if (PotentialImplicitProtocols.empty()) - return; - - // go through list of non-optional methods and properties in each protocol - // in the PotentialImplicitProtocols list. If class implements every one of the - // methods and properties, then this class conforms to this protocol. - llvm::SmallVector ConformingProtocols; - for (unsigned i = 0, e = PotentialImplicitProtocols.size(); i != e; i++) - if (ClassImplementsAllMethodsAndProperties(Ctx, ImpDecl, IDecl, - PotentialImplicitProtocols[i])) - ConformingProtocols.push_back(PotentialImplicitProtocols[i]); - - if (ConformingProtocols.empty()) - return; - - // Further reduce number of conforming protocols. If protocol P1 is in the list - // protocol P2 (P2), No need to include P1. - llvm::SmallVector MinimalConformingProtocols; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - bool DropIt = false; - ObjCProtocolDecl *TargetPDecl = ConformingProtocols[i]; - for (unsigned i1 = 0, e1 = ConformingProtocols.size(); i1 != e1; i1++) { - ObjCProtocolDecl *PDecl = ConformingProtocols[i1]; - if (PDecl == TargetPDecl) - continue; - if (PDecl->lookupProtocolNamed( - TargetPDecl->getDeclName().getAsIdentifierInfo())) { - DropIt = true; - break; - } - } - if (!DropIt) - MinimalConformingProtocols.push_back(TargetPDecl); - } - if (MinimalConformingProtocols.empty()) - return; - edit::Commit commit(*Editor); - rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols, - *NSAPIObj, commit); - Editor->commit(commit); -} - -void ObjCMigrateASTConsumer::CacheObjCNSIntegerTypedefed( - const TypedefDecl *TypedefDcl) { - - QualType qt = TypedefDcl->getTypeSourceInfo()->getType(); - if (NSAPIObj->isObjCNSIntegerType(qt)) - NSIntegerTypedefed = TypedefDcl; - else if (NSAPIObj->isObjCNSUIntegerType(qt)) - NSUIntegerTypedefed = TypedefDcl; -} - -bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx, - const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl) { - if (!EnumDcl->isCompleteDefinition() || EnumDcl->getIdentifier() || - EnumDcl->isDeprecated()) - return false; - if (!TypedefDcl) { - if (NSIntegerTypedefed) { - TypedefDcl = NSIntegerTypedefed; - NSIntegerTypedefed = nullptr; - } - else if (NSUIntegerTypedefed) { - TypedefDcl = NSUIntegerTypedefed; - NSUIntegerTypedefed = nullptr; - } - else - return false; - FileID FileIdOfTypedefDcl = - PP.getSourceManager().getFileID(TypedefDcl->getLocation()); - FileID FileIdOfEnumDcl = - PP.getSourceManager().getFileID(EnumDcl->getLocation()); - if (FileIdOfTypedefDcl != FileIdOfEnumDcl) - return false; - } - if (TypedefDcl->isDeprecated()) - return false; - - QualType qt = TypedefDcl->getTypeSourceInfo()->getType(); - StringRef NSIntegerName = NSAPIObj->GetNSIntegralKind(qt); - - if (NSIntegerName.empty()) { - // Also check for typedef enum {...} TD; - if (const EnumType *EnumTy = qt->getAs()) { - if (EnumTy->getDecl() == EnumDcl) { - bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl); - if (!InsertFoundation(Ctx, TypedefDcl->getBeginLoc())) - return false; - edit::Commit commit(*Editor); - rewriteToNSMacroDecl(Ctx, EnumDcl, TypedefDcl, *NSAPIObj, commit, !NSOptions); - Editor->commit(commit); - return true; - } - } - return false; - } - - // We may still use NS_OPTIONS based on what we find in the enumertor list. - bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl); - if (!InsertFoundation(Ctx, TypedefDcl->getBeginLoc())) - return false; - edit::Commit commit(*Editor); - bool Res = rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, - commit, NSIntegerName, NSOptions); - Editor->commit(commit); - return Res; -} - -static void ReplaceWithInstancetype(ASTContext &Ctx, - const ObjCMigrateASTConsumer &ASTC, - ObjCMethodDecl *OM) { - if (OM->getReturnType() == Ctx.getObjCInstanceType()) - return; // already has instancetype. - - SourceRange R; - std::string ClassString; - if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) { - TypeLoc TL = TSInfo->getTypeLoc(); - R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); - ClassString = "instancetype"; - } - else { - R = SourceRange(OM->getBeginLoc(), OM->getBeginLoc()); - ClassString = OM->isInstanceMethod() ? '-' : '+'; - ClassString += " (instancetype)"; - } - edit::Commit commit(*ASTC.Editor); - commit.replace(R, ClassString); - ASTC.Editor->commit(commit); -} - -static void ReplaceWithClasstype(const ObjCMigrateASTConsumer &ASTC, - ObjCMethodDecl *OM) { - ObjCInterfaceDecl *IDecl = OM->getClassInterface(); - SourceRange R; - std::string ClassString; - if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) { - TypeLoc TL = TSInfo->getTypeLoc(); - R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); { - ClassString = std::string(IDecl->getName()); - ClassString += "*"; - } - } - else { - R = SourceRange(OM->getBeginLoc(), OM->getBeginLoc()); - ClassString = "+ ("; - ClassString += IDecl->getName(); ClassString += "*)"; - } - edit::Commit commit(*ASTC.Editor); - commit.replace(R, ClassString); - ASTC.Editor->commit(commit); -} - -void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx, - ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM) { - ObjCInstanceTypeFamily OIT_Family = - Selector::getInstTypeMethodFamily(OM->getSelector()); - - std::string ClassName; - switch (OIT_Family) { - case OIT_None: - migrateFactoryMethod(Ctx, CDecl, OM); - return; - case OIT_Array: - ClassName = "NSArray"; - break; - case OIT_Dictionary: - ClassName = "NSDictionary"; - break; - case OIT_Singleton: - migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton); - return; - case OIT_Init: - if (OM->getReturnType()->isObjCIdType()) - ReplaceWithInstancetype(Ctx, *this, OM); - return; - case OIT_ReturnsSelf: - migrateFactoryMethod(Ctx, CDecl, OM, OIT_ReturnsSelf); - return; - } - if (!OM->getReturnType()->isObjCIdType()) - return; - - ObjCInterfaceDecl *IDecl = dyn_cast(CDecl); - if (!IDecl) { - if (ObjCCategoryDecl *CatDecl = dyn_cast(CDecl)) - IDecl = CatDecl->getClassInterface(); - else if (ObjCImplDecl *ImpDecl = dyn_cast(CDecl)) - IDecl = ImpDecl->getClassInterface(); - } - if (!IDecl || - !IDecl->lookupInheritedClass(&Ctx.Idents.get(ClassName))) { - migrateFactoryMethod(Ctx, CDecl, OM); - return; - } - ReplaceWithInstancetype(Ctx, *this, OM); -} - -static bool TypeIsInnerPointer(QualType T) { - if (!T->isAnyPointerType()) - return false; - if (T->isObjCObjectPointerType() || T->isObjCBuiltinType() || - T->isBlockPointerType() || T->isFunctionPointerType() || - ento::coreFoundation::isCFObjectRef(T)) - return false; - // Also, typedef-of-pointer-to-incomplete-struct is something that we assume - // is not an innter pointer type. - QualType OrigT = T; - while (const auto *TD = T->getAs()) - T = TD->getDecl()->getUnderlyingType(); - if (OrigT == T || !T->isPointerType()) - return true; - const PointerType* PT = T->getAs(); - QualType UPointeeT = PT->getPointeeType().getUnqualifiedType(); - if (UPointeeT->isRecordType()) { - const RecordType *RecordTy = UPointeeT->getAs(); - if (!RecordTy->getDecl()->isCompleteDefinition()) - return false; - } - return true; -} - -/// Check whether the two versions match. -static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y) { - return (X == Y); -} - -/// AvailabilityAttrsMatch - This routine checks that if comparing two -/// availability attributes, all their components match. It returns -/// true, if not dealing with availability or when all components of -/// availability attributes match. This routine is only called when -/// the attributes are of the same kind. -static bool AvailabilityAttrsMatch(Attr *At1, Attr *At2) { - const AvailabilityAttr *AA1 = dyn_cast(At1); - if (!AA1) - return true; - const AvailabilityAttr *AA2 = cast(At2); - - VersionTuple Introduced1 = AA1->getIntroduced(); - VersionTuple Deprecated1 = AA1->getDeprecated(); - VersionTuple Obsoleted1 = AA1->getObsoleted(); - bool IsUnavailable1 = AA1->getUnavailable(); - VersionTuple Introduced2 = AA2->getIntroduced(); - VersionTuple Deprecated2 = AA2->getDeprecated(); - VersionTuple Obsoleted2 = AA2->getObsoleted(); - bool IsUnavailable2 = AA2->getUnavailable(); - return (versionsMatch(Introduced1, Introduced2) && - versionsMatch(Deprecated1, Deprecated2) && - versionsMatch(Obsoleted1, Obsoleted2) && - IsUnavailable1 == IsUnavailable2); -} - -static bool MatchTwoAttributeLists(const AttrVec &Attrs1, const AttrVec &Attrs2, - bool &AvailabilityArgsMatch) { - // This list is very small, so this need not be optimized. - for (unsigned i = 0, e = Attrs1.size(); i != e; i++) { - bool match = false; - for (unsigned j = 0, f = Attrs2.size(); j != f; j++) { - // Matching attribute kind only. Except for Availability attributes, - // we are not getting into details of the attributes. For all practical purposes - // this is sufficient. - if (Attrs1[i]->getKind() == Attrs2[j]->getKind()) { - if (AvailabilityArgsMatch) - AvailabilityArgsMatch = AvailabilityAttrsMatch(Attrs1[i], Attrs2[j]); - match = true; - break; - } - } - if (!match) - return false; - } - return true; -} - -/// AttributesMatch - This routine checks list of attributes for two -/// decls. It returns false, if there is a mismatch in kind of -/// attributes seen in the decls. It returns true if the two decls -/// have list of same kind of attributes. Furthermore, when there -/// are availability attributes in the two decls, it sets the -/// AvailabilityArgsMatch to false if availability attributes have -/// different versions, etc. -static bool AttributesMatch(const Decl *Decl1, const Decl *Decl2, - bool &AvailabilityArgsMatch) { - if (!Decl1->hasAttrs() || !Decl2->hasAttrs()) { - AvailabilityArgsMatch = (Decl1->hasAttrs() == Decl2->hasAttrs()); - return true; - } - AvailabilityArgsMatch = true; - const AttrVec &Attrs1 = Decl1->getAttrs(); - const AttrVec &Attrs2 = Decl2->getAttrs(); - bool match = MatchTwoAttributeLists(Attrs1, Attrs2, AvailabilityArgsMatch); - if (match && (Attrs2.size() > Attrs1.size())) - return MatchTwoAttributeLists(Attrs2, Attrs1, AvailabilityArgsMatch); - return match; -} - -static bool IsValidIdentifier(ASTContext &Ctx, - const char *Name) { - if (!isAsciiIdentifierStart(Name[0])) - return false; - std::string NameString = Name; - NameString[0] = toLowercase(NameString[0]); - const IdentifierInfo *II = &Ctx.Idents.get(NameString); - return II->getTokenID() == tok::identifier; -} - -bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx, - ObjCContainerDecl *D, - ObjCMethodDecl *Method) { - if (Method->isPropertyAccessor() || !Method->isInstanceMethod() || - Method->param_size() != 0) - return false; - // Is this method candidate to be a getter? - QualType GRT = Method->getReturnType(); - if (GRT->isVoidType()) - return false; - - Selector GetterSelector = Method->getSelector(); - ObjCInstanceTypeFamily OIT_Family = - Selector::getInstTypeMethodFamily(GetterSelector); - - if (OIT_Family != OIT_None) - return false; - - const IdentifierInfo *getterName = GetterSelector.getIdentifierInfoForSlot(0); - Selector SetterSelector = - SelectorTable::constructSetterSelector(PP.getIdentifierTable(), - PP.getSelectorTable(), - getterName); - ObjCMethodDecl *SetterMethod = D->getInstanceMethod(SetterSelector); - unsigned LengthOfPrefix = 0; - if (!SetterMethod) { - // try a different naming convention for getter: isXxxxx - StringRef getterNameString = getterName->getName(); - bool IsPrefix = getterNameString.starts_with("is"); - // Note that we don't want to change an isXXX method of retainable object - // type to property (readonly or otherwise). - if (IsPrefix && GRT->isObjCRetainableType()) - return false; - if (IsPrefix || getterNameString.starts_with("get")) { - LengthOfPrefix = (IsPrefix ? 2 : 3); - const char *CGetterName = getterNameString.data() + LengthOfPrefix; - // Make sure that first character after "is" or "get" prefix can - // start an identifier. - if (!IsValidIdentifier(Ctx, CGetterName)) - return false; - if (CGetterName[0] && isUppercase(CGetterName[0])) { - getterName = &Ctx.Idents.get(CGetterName); - SetterSelector = - SelectorTable::constructSetterSelector(PP.getIdentifierTable(), - PP.getSelectorTable(), - getterName); - SetterMethod = D->getInstanceMethod(SetterSelector); - } - } - } - - if (SetterMethod) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_ReadwriteProperty) == 0) - return false; - bool AvailabilityArgsMatch; - if (SetterMethod->isDeprecated() || - !AttributesMatch(Method, SetterMethod, AvailabilityArgsMatch)) - return false; - - // Is this a valid setter, matching the target getter? - QualType SRT = SetterMethod->getReturnType(); - if (!SRT->isVoidType()) - return false; - const ParmVarDecl *argDecl = *SetterMethod->param_begin(); - QualType ArgType = argDecl->getType(); - if (!Ctx.hasSameUnqualifiedType(ArgType, GRT)) - return false; - edit::Commit commit(*Editor); - rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit, - LengthOfPrefix, - (ASTMigrateActions & - FrontendOptions::ObjCMT_AtomicProperty) != 0, - (ASTMigrateActions & - FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty) != 0, - AvailabilityArgsMatch); - Editor->commit(commit); - return true; - } - else if (ASTMigrateActions & FrontendOptions::ObjCMT_ReadonlyProperty) { - // Try a non-void method with no argument (and no setter or property of same name - // as a 'readonly' property. - edit::Commit commit(*Editor); - rewriteToObjCProperty(Method, nullptr /*SetterMethod*/, *NSAPIObj, commit, - LengthOfPrefix, - (ASTMigrateActions & - FrontendOptions::ObjCMT_AtomicProperty) != 0, - (ASTMigrateActions & - FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty) != 0, - /*AvailabilityArgsMatch*/false); - Editor->commit(commit); - return true; - } - return false; -} - -void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx, - ObjCMethodDecl *OM) { - if (OM->isImplicit() || - !OM->isInstanceMethod() || - OM->hasAttr()) - return; - - QualType RT = OM->getReturnType(); - if (!TypeIsInnerPointer(RT) || - !NSAPIObj->isMacroDefined("NS_RETURNS_INNER_POINTER")) - return; - - edit::Commit commit(*Editor); - commit.insertBefore(OM->getEndLoc(), " NS_RETURNS_INNER_POINTER"); - Editor->commit(commit); -} - -void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ctx, - ObjCPropertyDecl *P) { - QualType T = P->getType(); - - if (!TypeIsInnerPointer(T) || - !NSAPIObj->isMacroDefined("NS_RETURNS_INNER_POINTER")) - return; - edit::Commit commit(*Editor); - commit.insertBefore(P->getEndLoc(), " NS_RETURNS_INNER_POINTER "); - Editor->commit(commit); -} - -void ObjCMigrateASTConsumer::migrateAllMethodInstaceType(ASTContext &Ctx, - ObjCContainerDecl *CDecl) { - if (CDecl->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(CDecl)) - return; - - // migrate methods which can have instancetype as their result type. - for (auto *Method : CDecl->methods()) { - if (Method->isDeprecated()) - continue; - migrateMethodInstanceType(Ctx, CDecl, Method); - } -} - -void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx, - ObjCContainerDecl *CDecl, - ObjCMethodDecl *OM, - ObjCInstanceTypeFamily OIT_Family) { - if (OM->isInstanceMethod() || - OM->getReturnType() == Ctx.getObjCInstanceType() || - !OM->getReturnType()->isObjCIdType()) - return; - - // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class - // NSYYYNamE with matching names be at least 3 characters long. - ObjCInterfaceDecl *IDecl = dyn_cast(CDecl); - if (!IDecl) { - if (ObjCCategoryDecl *CatDecl = dyn_cast(CDecl)) - IDecl = CatDecl->getClassInterface(); - else if (ObjCImplDecl *ImpDecl = dyn_cast(CDecl)) - IDecl = ImpDecl->getClassInterface(); - } - if (!IDecl) - return; - - std::string StringClassName = std::string(IDecl->getName()); - StringRef LoweredClassName(StringClassName); - std::string StringLoweredClassName = LoweredClassName.lower(); - LoweredClassName = StringLoweredClassName; - - const IdentifierInfo *MethodIdName = - OM->getSelector().getIdentifierInfoForSlot(0); - // Handle method with no name at its first selector slot; e.g. + (id):(int)x. - if (!MethodIdName) - return; - - std::string MethodName = std::string(MethodIdName->getName()); - if (OIT_Family == OIT_Singleton || OIT_Family == OIT_ReturnsSelf) { - StringRef STRefMethodName(MethodName); - size_t len = 0; - if (STRefMethodName.starts_with("standard")) - len = strlen("standard"); - else if (STRefMethodName.starts_with("shared")) - len = strlen("shared"); - else if (STRefMethodName.starts_with("default")) - len = strlen("default"); - else - return; - MethodName = std::string(STRefMethodName.substr(len)); - } - std::string MethodNameSubStr = MethodName.substr(0, 3); - StringRef MethodNamePrefix(MethodNameSubStr); - std::string StringLoweredMethodNamePrefix = MethodNamePrefix.lower(); - MethodNamePrefix = StringLoweredMethodNamePrefix; - size_t Ix = LoweredClassName.rfind(MethodNamePrefix); - if (Ix == StringRef::npos) - return; - std::string ClassNamePostfix = std::string(LoweredClassName.substr(Ix)); - StringRef LoweredMethodName(MethodName); - std::string StringLoweredMethodName = LoweredMethodName.lower(); - LoweredMethodName = StringLoweredMethodName; - if (!LoweredMethodName.starts_with(ClassNamePostfix)) - return; - if (OIT_Family == OIT_ReturnsSelf) - ReplaceWithClasstype(*this, OM); - else - ReplaceWithInstancetype(Ctx, *this, OM); -} - -static bool IsVoidStarType(QualType Ty) { - if (!Ty->isPointerType()) - return false; - - // Is the type void*? - const PointerType* PT = Ty->castAs(); - if (PT->getPointeeType().getUnqualifiedType()->isVoidType()) - return true; - return IsVoidStarType(PT->getPointeeType()); -} - -/// AuditedType - This routine audits the type AT and returns false if it is one of known -/// CF object types or of the "void *" variety. It returns true if we don't care about the type -/// such as a non-pointer or pointers which have no ownership issues (such as "int *"). -static bool AuditedType (QualType AT) { - if (!AT->isAnyPointerType() && !AT->isBlockPointerType()) - return true; - // FIXME. There isn't much we can say about CF pointer type; or is there? - if (ento::coreFoundation::isCFObjectRef(AT) || - IsVoidStarType(AT) || - // If an ObjC object is type, assuming that it is not a CF function and - // that it is an un-audited function. - AT->isObjCObjectPointerType() || AT->isObjCBuiltinType()) - return false; - // All other pointers are assumed audited as harmless. - return true; -} - -void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) { - if (CFFunctionIBCandidates.empty()) - return; - if (!NSAPIObj->isMacroDefined("CF_IMPLICIT_BRIDGING_ENABLED")) { - CFFunctionIBCandidates.clear(); - FileId = FileID(); - return; - } - // Insert CF_IMPLICIT_BRIDGING_ENABLE/CF_IMPLICIT_BRIDGING_DISABLED - const Decl *FirstFD = CFFunctionIBCandidates[0]; - const Decl *LastFD = - CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1]; - const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n"; - edit::Commit commit(*Editor); - commit.insertBefore(FirstFD->getBeginLoc(), PragmaString); - PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n"; - SourceLocation EndLoc = LastFD->getEndLoc(); - // get location just past end of function location. - EndLoc = PP.getLocForEndOfToken(EndLoc); - if (isa(LastFD)) { - // For Methods, EndLoc points to the ending semcolon. So, - // not of these extra work is needed. - Token Tok; - // get locaiton of token that comes after end of function. - bool Failed = PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true); - if (!Failed) - EndLoc = Tok.getLocation(); - } - commit.insertAfterToken(EndLoc, PragmaString); - Editor->commit(commit); - FileId = FileID(); - CFFunctionIBCandidates.clear(); -} - -void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl) { - if (Decl->isDeprecated()) - return; - - if (Decl->hasAttr()) { - assert(CFFunctionIBCandidates.empty() && - "Cannot have audited functions/methods inside user " - "provided CF_IMPLICIT_BRIDGING_ENABLE"); - return; - } - - // Finction must be annotated first. - if (const FunctionDecl *FuncDecl = dyn_cast(Decl)) { - CF_BRIDGING_KIND AuditKind = migrateAddFunctionAnnotation(Ctx, FuncDecl); - if (AuditKind == CF_BRIDGING_ENABLE) { - CFFunctionIBCandidates.push_back(Decl); - if (FileId.isInvalid()) - FileId = PP.getSourceManager().getFileID(Decl->getLocation()); - } - else if (AuditKind == CF_BRIDGING_MAY_INCLUDE) { - if (!CFFunctionIBCandidates.empty()) { - CFFunctionIBCandidates.push_back(Decl); - if (FileId.isInvalid()) - FileId = PP.getSourceManager().getFileID(Decl->getLocation()); - } - } - else - AnnotateImplicitBridging(Ctx); - } - else { - migrateAddMethodAnnotation(Ctx, cast(Decl)); - AnnotateImplicitBridging(Ctx); - } -} - -void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const FunctionDecl *FuncDecl, - bool ResultAnnotated) { - // Annotate function. - if (!ResultAnnotated) { - RetEffect Ret = RS->getRetEffect(); - const char *AnnotationString = nullptr; - if (Ret.getObjKind() == ObjKind::CF) { - if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED")) - AnnotationString = " CF_RETURNS_RETAINED"; - else if (Ret.notOwned() && - NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED")) - AnnotationString = " CF_RETURNS_NOT_RETAINED"; - } - else if (Ret.getObjKind() == ObjKind::ObjC) { - if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED")) - AnnotationString = " NS_RETURNS_RETAINED"; - } - - if (AnnotationString) { - edit::Commit commit(*Editor); - commit.insertAfterToken(FuncDecl->getEndLoc(), AnnotationString); - Editor->commit(commit); - } - } - unsigned i = 0; - for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(), - pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF && - !pd->hasAttr() && - NSAPIObj->isMacroDefined("CF_CONSUMED")) { - edit::Commit commit(*Editor); - commit.insertBefore(pd->getLocation(), "CF_CONSUMED "); - Editor->commit(commit); - } else if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::ObjC && - !pd->hasAttr() && - NSAPIObj->isMacroDefined("NS_CONSUMED")) { - edit::Commit commit(*Editor); - commit.insertBefore(pd->getLocation(), "NS_CONSUMED "); - Editor->commit(commit); - } - } -} - -ObjCMigrateASTConsumer::CF_BRIDGING_KIND - ObjCMigrateASTConsumer::migrateAddFunctionAnnotation( - ASTContext &Ctx, - const FunctionDecl *FuncDecl) { - if (FuncDecl->hasBody()) - return CF_BRIDGING_NONE; - - const RetainSummary *RS = - getSummaryManager(Ctx).getSummary(AnyCall(FuncDecl)); - bool FuncIsReturnAnnotated = (FuncDecl->hasAttr() || - FuncDecl->hasAttr() || - FuncDecl->hasAttr() || - FuncDecl->hasAttr() || - FuncDecl->hasAttr()); - - // Trivial case of when function is annotated and has no argument. - if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0) - return CF_BRIDGING_NONE; - - bool ReturnCFAudited = false; - if (!FuncIsReturnAnnotated) { - RetEffect Ret = RS->getRetEffect(); - if (Ret.getObjKind() == ObjKind::CF && - (Ret.isOwned() || Ret.notOwned())) - ReturnCFAudited = true; - else if (!AuditedType(FuncDecl->getReturnType())) - return CF_BRIDGING_NONE; - } - - // At this point result type is audited for potential inclusion. - unsigned i = 0; - bool ArgCFAudited = false; - for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(), - pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if ((AE.getKind() == DecRef /*CFConsumed annotated*/ || - AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) { - if (AE.getKind() == DecRef && !pd->hasAttr()) - ArgCFAudited = true; - else if (AE.getKind() == IncRef) - ArgCFAudited = true; - } else { - QualType AT = pd->getType(); - if (!AuditedType(AT)) { - AddCFAnnotations(Ctx, RS, FuncDecl, FuncIsReturnAnnotated); - return CF_BRIDGING_NONE; - } - } - } - if (ReturnCFAudited || ArgCFAudited) - return CF_BRIDGING_ENABLE; - - return CF_BRIDGING_MAY_INCLUDE; -} - -void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx, - ObjCContainerDecl *CDecl) { - if (!isa(CDecl) || CDecl->isDeprecated()) - return; - - // migrate methods which can have instancetype as their result type. - for (const auto *Method : CDecl->methods()) - migrateCFAnnotation(Ctx, Method); -} - -void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx, - const RetainSummary *RS, - const ObjCMethodDecl *MethodDecl, - bool ResultAnnotated) { - // Annotate function. - if (!ResultAnnotated) { - RetEffect Ret = RS->getRetEffect(); - const char *AnnotationString = nullptr; - if (Ret.getObjKind() == ObjKind::CF) { - if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED")) - AnnotationString = " CF_RETURNS_RETAINED"; - else if (Ret.notOwned() && - NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED")) - AnnotationString = " CF_RETURNS_NOT_RETAINED"; - } - else if (Ret.getObjKind() == ObjKind::ObjC) { - ObjCMethodFamily OMF = MethodDecl->getMethodFamily(); - switch (OMF) { - case clang::OMF_alloc: - case clang::OMF_new: - case clang::OMF_copy: - case clang::OMF_init: - case clang::OMF_mutableCopy: - break; - - default: - if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED")) - AnnotationString = " NS_RETURNS_RETAINED"; - break; - } - } - - if (AnnotationString) { - edit::Commit commit(*Editor); - commit.insertBefore(MethodDecl->getEndLoc(), AnnotationString); - Editor->commit(commit); - } - } - unsigned i = 0; - for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(), - pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if (AE.getKind() == DecRef - && AE.getObjKind() == ObjKind::CF - && !pd->hasAttr() && - NSAPIObj->isMacroDefined("CF_CONSUMED")) { - edit::Commit commit(*Editor); - commit.insertBefore(pd->getLocation(), "CF_CONSUMED "); - Editor->commit(commit); - } - } -} - -void ObjCMigrateASTConsumer::migrateAddMethodAnnotation( - ASTContext &Ctx, - const ObjCMethodDecl *MethodDecl) { - if (MethodDecl->hasBody() || MethodDecl->isImplicit()) - return; - - const RetainSummary *RS = - getSummaryManager(Ctx).getSummary(AnyCall(MethodDecl)); - - bool MethodIsReturnAnnotated = - (MethodDecl->hasAttr() || - MethodDecl->hasAttr() || - MethodDecl->hasAttr() || - MethodDecl->hasAttr() || - MethodDecl->hasAttr()); - - if (RS->getReceiverEffect().getKind() == DecRef && - !MethodDecl->hasAttr() && - MethodDecl->getMethodFamily() != OMF_init && - MethodDecl->getMethodFamily() != OMF_release && - NSAPIObj->isMacroDefined("NS_CONSUMES_SELF")) { - edit::Commit commit(*Editor); - commit.insertBefore(MethodDecl->getEndLoc(), " NS_CONSUMES_SELF"); - Editor->commit(commit); - } - - // Trivial case of when function is annotated and has no argument. - if (MethodIsReturnAnnotated && - (MethodDecl->param_begin() == MethodDecl->param_end())) - return; - - if (!MethodIsReturnAnnotated) { - RetEffect Ret = RS->getRetEffect(); - if ((Ret.getObjKind() == ObjKind::CF || - Ret.getObjKind() == ObjKind::ObjC) && - (Ret.isOwned() || Ret.notOwned())) { - AddCFAnnotations(Ctx, RS, MethodDecl, false); - return; - } else if (!AuditedType(MethodDecl->getReturnType())) - return; - } - - // At this point result type is either annotated or audited. - unsigned i = 0; - for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(), - pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) { - const ParmVarDecl *pd = *pi; - ArgEffect AE = RS->getArg(i); - if ((AE.getKind() == DecRef && !pd->hasAttr()) || - AE.getKind() == IncRef || !AuditedType(pd->getType())) { - AddCFAnnotations(Ctx, RS, MethodDecl, MethodIsReturnAnnotated); - return; - } - } -} - -namespace { -class SuperInitChecker : public RecursiveASTVisitor { -public: - bool shouldVisitTemplateInstantiations() const { return false; } - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) { - if (E->getMethodFamily() == OMF_init) - return false; - } - return true; - } -}; -} // end anonymous namespace - -static bool hasSuperInitCall(const ObjCMethodDecl *MD) { - return !SuperInitChecker().TraverseStmt(MD->getBody()); -} - -void ObjCMigrateASTConsumer::inferDesignatedInitializers( - ASTContext &Ctx, - const ObjCImplementationDecl *ImplD) { - - const ObjCInterfaceDecl *IFace = ImplD->getClassInterface(); - if (!IFace || IFace->hasDesignatedInitializers()) - return; - if (!NSAPIObj->isMacroDefined("NS_DESIGNATED_INITIALIZER")) - return; - - for (const auto *MD : ImplD->instance_methods()) { - if (MD->isDeprecated() || - MD->getMethodFamily() != OMF_init || - MD->isDesignatedInitializerForTheInterface()) - continue; - const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(), - /*isInstance=*/true); - if (!IFaceM) - continue; - if (hasSuperInitCall(MD)) { - edit::Commit commit(*Editor); - commit.insert(IFaceM->getEndLoc(), " NS_DESIGNATED_INITIALIZER"); - Editor->commit(commit); - } - } -} - -bool ObjCMigrateASTConsumer::InsertFoundation(ASTContext &Ctx, - SourceLocation Loc) { - if (FoundationIncluded) - return true; - if (Loc.isInvalid()) - return false; - auto *nsEnumId = &Ctx.Idents.get("NS_ENUM"); - if (PP.getMacroDefinitionAtLoc(nsEnumId, Loc)) { - FoundationIncluded = true; - return true; - } - edit::Commit commit(*Editor); - if (Ctx.getLangOpts().Modules) - commit.insert(Loc, "#ifndef NS_ENUM\n@import Foundation;\n#endif\n"); - else - commit.insert(Loc, "#ifndef NS_ENUM\n#import \n#endif\n"); - Editor->commit(commit); - FoundationIncluded = true; - return true; -} - -namespace { - -class RewritesReceiver : public edit::EditsReceiver { - Rewriter &Rewrite; - -public: - RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { } - - void insert(SourceLocation loc, StringRef text) override { - Rewrite.InsertText(loc, text); - } - void replace(CharSourceRange range, StringRef text) override { - Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text); - } -}; - -class JSONEditWriter : public edit::EditsReceiver { - SourceManager &SourceMgr; - llvm::raw_ostream &OS; - -public: - JSONEditWriter(SourceManager &SM, llvm::raw_ostream &OS) - : SourceMgr(SM), OS(OS) { - OS << "[\n"; - } - ~JSONEditWriter() override { OS << "]\n"; } - -private: - struct EntryWriter { - SourceManager &SourceMgr; - llvm::raw_ostream &OS; - - EntryWriter(SourceManager &SM, llvm::raw_ostream &OS) - : SourceMgr(SM), OS(OS) { - OS << " {\n"; - } - ~EntryWriter() { - OS << " },\n"; - } - - void writeLoc(SourceLocation Loc) { - FileID FID; - unsigned Offset; - std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc); - assert(FID.isValid()); - SmallString<200> Path = - StringRef(SourceMgr.getFileEntryRefForID(FID)->getName()); - llvm::sys::fs::make_absolute(Path); - OS << " \"file\": \""; - OS.write_escaped(Path.str()) << "\",\n"; - OS << " \"offset\": " << Offset << ",\n"; - } - - void writeRemove(CharSourceRange Range) { - assert(Range.isCharRange()); - std::pair Begin = - SourceMgr.getDecomposedLoc(Range.getBegin()); - std::pair End = - SourceMgr.getDecomposedLoc(Range.getEnd()); - assert(Begin.first == End.first); - assert(Begin.second <= End.second); - unsigned Length = End.second - Begin.second; - - OS << " \"remove\": " << Length << ",\n"; - } - - void writeText(StringRef Text) { - OS << " \"text\": \""; - OS.write_escaped(Text) << "\",\n"; - } - }; - - void insert(SourceLocation Loc, StringRef Text) override { - EntryWriter Writer(SourceMgr, OS); - Writer.writeLoc(Loc); - Writer.writeText(Text); - } - - void replace(CharSourceRange Range, StringRef Text) override { - EntryWriter Writer(SourceMgr, OS); - Writer.writeLoc(Range.getBegin()); - Writer.writeRemove(Range); - Writer.writeText(Text); - } - - void remove(CharSourceRange Range) override { - EntryWriter Writer(SourceMgr, OS); - Writer.writeLoc(Range.getBegin()); - Writer.writeRemove(Range); - } -}; - -} // end anonymous namespace - -void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { - - TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl(); - if (ASTMigrateActions & FrontendOptions::ObjCMT_MigrateDecls) { - for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); - D != DEnd; ++D) { - FileID FID = PP.getSourceManager().getFileID((*D)->getLocation()); - if (FID.isValid()) - if (FileId.isValid() && FileId != FID) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) - AnnotateImplicitBridging(Ctx); - } - - if (ObjCInterfaceDecl *CDecl = dyn_cast(*D)) - if (canModify(CDecl)) - migrateObjCContainerDecl(Ctx, CDecl); - if (ObjCCategoryDecl *CatDecl = dyn_cast(*D)) { - if (canModify(CatDecl)) - migrateObjCContainerDecl(Ctx, CatDecl); - } - else if (ObjCProtocolDecl *PDecl = dyn_cast(*D)) { - ObjCProtocolDecls.insert(PDecl->getCanonicalDecl()); - if (canModify(PDecl)) - migrateObjCContainerDecl(Ctx, PDecl); - } - else if (const ObjCImplementationDecl *ImpDecl = - dyn_cast(*D)) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) && - canModify(ImpDecl)) - migrateProtocolConformance(Ctx, ImpDecl); - } - else if (const EnumDecl *ED = dyn_cast(*D)) { - if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) - continue; - if (!canModify(ED)) - continue; - DeclContext::decl_iterator N = D; - if (++N != DEnd) { - const TypedefDecl *TD = dyn_cast(*N); - if (migrateNSEnumDecl(Ctx, ED, TD) && TD) - D++; - } - else - migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */nullptr); - } - else if (const TypedefDecl *TD = dyn_cast(*D)) { - if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) - continue; - if (!canModify(TD)) - continue; - DeclContext::decl_iterator N = D; - if (++N == DEnd) - continue; - if (const EnumDecl *ED = dyn_cast(*N)) { - if (canModify(ED)) { - if (++N != DEnd) - if (const TypedefDecl *TDF = dyn_cast(*N)) { - // prefer typedef-follows-enum to enum-follows-typedef pattern. - if (migrateNSEnumDecl(Ctx, ED, TDF)) { - ++D; ++D; - CacheObjCNSIntegerTypedefed(TD); - continue; - } - } - if (migrateNSEnumDecl(Ctx, ED, TD)) { - ++D; - continue; - } - } - } - CacheObjCNSIntegerTypedefed(TD); - } - else if (const FunctionDecl *FD = dyn_cast(*D)) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && - canModify(FD)) - migrateCFAnnotation(Ctx, FD); - } - - if (ObjCContainerDecl *CDecl = dyn_cast(*D)) { - bool CanModify = canModify(CDecl); - // migrate methods which can have instancetype as their result type. - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) && - CanModify) - migrateAllMethodInstaceType(Ctx, CDecl); - // annotate methods with CF annotations. - if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && - CanModify) - migrateARCSafeAnnotation(Ctx, CDecl); - } - - if (const ObjCImplementationDecl * - ImplD = dyn_cast(*D)) { - if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) && - canModify(ImplD)) - inferDesignatedInitializers(Ctx, ImplD); - } - } - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) - AnnotateImplicitBridging(Ctx); - } - - if (IsOutputFile) { - std::error_code EC; - llvm::raw_fd_ostream OS(MigrateDir, EC, llvm::sys::fs::OF_None); - if (EC) { - DiagnosticsEngine &Diags = Ctx.getDiagnostics(); - Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0")) - << EC.message(); - return; - } - - JSONEditWriter Writer(Ctx.getSourceManager(), OS); - Editor->applyRewrites(Writer); - return; - } - - Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts()); - RewritesReceiver Rec(rewriter); - Editor->applyRewrites(Rec); - - for (Rewriter::buffer_iterator - I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) { - FileID FID = I->first; - RewriteBuffer &buf = I->second; - OptionalFileEntryRef file = - Ctx.getSourceManager().getFileEntryRefForID(FID); - assert(file); - SmallString<512> newText; - llvm::raw_svector_ostream vecOS(newText); - buf.write(vecOS); - std::unique_ptr memBuf( - llvm::MemoryBuffer::getMemBufferCopy(newText.str(), file->getName())); - SmallString<64> filePath(file->getName()); - FileMgr.FixupRelativePath(filePath); - Remapper.remap(filePath.str(), std::move(memBuf)); - } - - if (IsOutputFile) { - Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics()); - } else { - Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics()); - } -} - -bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) { - CI.getDiagnostics().setIgnoreAllWarnings(true); - return true; -} - -static std::vector getAllowListFilenames(StringRef DirPath) { - using namespace llvm::sys::fs; - using namespace llvm::sys::path; - - std::vector Filenames; - if (DirPath.empty() || !is_directory(DirPath)) - return Filenames; - - std::error_code EC; - directory_iterator DI = directory_iterator(DirPath, EC); - directory_iterator DE; - for (; !EC && DI != DE; DI = DI.increment(EC)) { - if (is_regular_file(DI->path())) - Filenames.push_back(std::string(filename(DI->path()))); - } - - return Filenames; -} - -std::unique_ptr -MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - PPConditionalDirectiveRecord * - PPRec = new PPConditionalDirectiveRecord(CI.getSourceManager()); - unsigned ObjCMTAction = CI.getFrontendOpts().ObjCMTAction; - unsigned ObjCMTOpts = ObjCMTAction; - // These are companion flags, they do not enable transformations. - ObjCMTOpts &= ~(FrontendOptions::ObjCMT_AtomicProperty | - FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty); - if (ObjCMTOpts == FrontendOptions::ObjCMT_None) { - // If no specific option was given, enable literals+subscripting transforms - // by default. - ObjCMTAction |= - FrontendOptions::ObjCMT_Literals | FrontendOptions::ObjCMT_Subscripting; - } - CI.getPreprocessor().addPPCallbacks(std::unique_ptr(PPRec)); - std::vector AllowList = - getAllowListFilenames(CI.getFrontendOpts().ObjCMTAllowListPath); - return std::make_unique( - CI.getFrontendOpts().OutputFile, ObjCMTAction, Remapper, - CI.getFileManager(), PPRec, CI.getPreprocessor(), - /*isOutputFile=*/true, AllowList); -} - -namespace { -struct EditEntry { - OptionalFileEntryRef File; - unsigned Offset = 0; - unsigned RemoveLen = 0; - std::string Text; -}; -} // end anonymous namespace - -namespace llvm { -template<> struct DenseMapInfo { - static inline EditEntry getEmptyKey() { - EditEntry Entry; - Entry.Offset = unsigned(-1); - return Entry; - } - static inline EditEntry getTombstoneKey() { - EditEntry Entry; - Entry.Offset = unsigned(-2); - return Entry; - } - static unsigned getHashValue(const EditEntry& Val) { - return (unsigned)llvm::hash_combine(Val.File, Val.Offset, Val.RemoveLen, - Val.Text); - } - static bool isEqual(const EditEntry &LHS, const EditEntry &RHS) { - return LHS.File == RHS.File && - LHS.Offset == RHS.Offset && - LHS.RemoveLen == RHS.RemoveLen && - LHS.Text == RHS.Text; - } -}; -} // end namespace llvm - -namespace { -class RemapFileParser { - FileManager &FileMgr; - -public: - RemapFileParser(FileManager &FileMgr) : FileMgr(FileMgr) { } - - bool parse(StringRef File, SmallVectorImpl &Entries) { - using namespace llvm::yaml; - - llvm::ErrorOr> FileBufOrErr = - llvm::MemoryBuffer::getFile(File); - if (!FileBufOrErr) - return true; - - llvm::SourceMgr SM; - Stream YAMLStream(FileBufOrErr.get()->getMemBufferRef(), SM); - document_iterator I = YAMLStream.begin(); - if (I == YAMLStream.end()) - return true; - Node *Root = I->getRoot(); - if (!Root) - return true; - - SequenceNode *SeqNode = dyn_cast(Root); - if (!SeqNode) - return true; - - for (SequenceNode::iterator - AI = SeqNode->begin(), AE = SeqNode->end(); AI != AE; ++AI) { - MappingNode *MapNode = dyn_cast(&*AI); - if (!MapNode) - continue; - parseEdit(MapNode, Entries); - } - - return false; - } - -private: - void parseEdit(llvm::yaml::MappingNode *Node, - SmallVectorImpl &Entries) { - using namespace llvm::yaml; - EditEntry Entry; - bool Ignore = false; - - for (MappingNode::iterator - KVI = Node->begin(), KVE = Node->end(); KVI != KVE; ++KVI) { - ScalarNode *KeyString = dyn_cast((*KVI).getKey()); - if (!KeyString) - continue; - SmallString<10> KeyStorage; - StringRef Key = KeyString->getValue(KeyStorage); - - ScalarNode *ValueString = dyn_cast((*KVI).getValue()); - if (!ValueString) - continue; - SmallString<64> ValueStorage; - StringRef Val = ValueString->getValue(ValueStorage); - - if (Key == "file") { - if (auto File = FileMgr.getOptionalFileRef(Val)) - Entry.File = File; - else - Ignore = true; - } else if (Key == "offset") { - if (Val.getAsInteger(10, Entry.Offset)) - Ignore = true; - } else if (Key == "remove") { - if (Val.getAsInteger(10, Entry.RemoveLen)) - Ignore = true; - } else if (Key == "text") { - Entry.Text = std::string(Val); - } - } - - if (!Ignore) - Entries.push_back(Entry); - } -}; -} // end anonymous namespace - -static bool reportDiag(const Twine &Err, DiagnosticsEngine &Diag) { - Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")) - << Err.str(); - return true; -} - -static std::string applyEditsToTemp(FileEntryRef FE, - ArrayRef Edits, - FileManager &FileMgr, - DiagnosticsEngine &Diag) { - using namespace llvm::sys; - - SourceManager SM(Diag, FileMgr); - FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User); - LangOptions LangOpts; - edit::EditedSource Editor(SM, LangOpts); - for (ArrayRef::iterator - I = Edits.begin(), E = Edits.end(); I != E; ++I) { - const EditEntry &Entry = *I; - assert(Entry.File == FE); - SourceLocation Loc = - SM.getLocForStartOfFile(FID).getLocWithOffset(Entry.Offset); - CharSourceRange Range; - if (Entry.RemoveLen != 0) { - Range = CharSourceRange::getCharRange(Loc, - Loc.getLocWithOffset(Entry.RemoveLen)); - } - - edit::Commit commit(Editor); - if (Range.isInvalid()) { - commit.insert(Loc, Entry.Text); - } else if (Entry.Text.empty()) { - commit.remove(Range); - } else { - commit.replace(Range, Entry.Text); - } - Editor.commit(commit); - } - - Rewriter rewriter(SM, LangOpts); - RewritesReceiver Rec(rewriter); - Editor.applyRewrites(Rec, /*adjustRemovals=*/false); - - const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID); - SmallString<512> NewText; - llvm::raw_svector_ostream OS(NewText); - Buf->write(OS); - - SmallString<64> TempPath; - int FD; - if (fs::createTemporaryFile(path::filename(FE.getName()), - path::extension(FE.getName()).drop_front(), FD, - TempPath)) { - reportDiag("Could not create file: " + TempPath.str(), Diag); - return std::string(); - } - - llvm::raw_fd_ostream TmpOut(FD, /*shouldClose=*/true); - TmpOut.write(NewText.data(), NewText.size()); - TmpOut.close(); - - return std::string(TempPath); -} - -bool arcmt::getFileRemappingsFromFileList( - std::vector > &remap, - ArrayRef remapFiles, - DiagnosticConsumer *DiagClient) { - bool hasErrorOccurred = false; - - FileSystemOptions FSOpts; - FileManager FileMgr(FSOpts); - RemapFileParser Parser(FileMgr); - - IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); - IntrusiveRefCntPtr Diags( - new DiagnosticsEngine(DiagID, new DiagnosticOptions, - DiagClient, /*ShouldOwnClient=*/false)); - - typedef llvm::DenseMap > - FileEditEntriesTy; - FileEditEntriesTy FileEditEntries; - - llvm::DenseSet EntriesSet; - - for (ArrayRef::iterator - I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) { - SmallVector Entries; - if (Parser.parse(*I, Entries)) - continue; - - for (SmallVectorImpl::iterator - EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) { - EditEntry &Entry = *EI; - if (!Entry.File) - continue; - std::pair::iterator, bool> - Insert = EntriesSet.insert(Entry); - if (!Insert.second) - continue; - - FileEditEntries[*Entry.File].push_back(Entry); - } - } - - for (FileEditEntriesTy::iterator - I = FileEditEntries.begin(), E = FileEditEntries.end(); I != E; ++I) { - std::string TempFile = applyEditsToTemp(I->first, I->second, - FileMgr, *Diags); - if (TempFile.empty()) { - hasErrorOccurred = true; - continue; - } - - remap.emplace_back(std::string(I->first.getName()), TempFile); - } - - return hasErrorOccurred; -} diff --git a/clang/lib/ARCMigrate/PlistReporter.cpp b/clang/lib/ARCMigrate/PlistReporter.cpp deleted file mode 100644 index f78ca5e1c9bdd..0000000000000 --- a/clang/lib/ARCMigrate/PlistReporter.cpp +++ /dev/null @@ -1,124 +0,0 @@ -//===--- PlistReporter.cpp - ARC Migrate Tool Plist Reporter ----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Internals.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/PlistSupport.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -using namespace clang; -using namespace arcmt; -using namespace markup; - -static StringRef getLevelName(DiagnosticsEngine::Level Level) { - switch (Level) { - case DiagnosticsEngine::Ignored: - llvm_unreachable("ignored"); - case DiagnosticsEngine::Note: - return "note"; - case DiagnosticsEngine::Remark: - case DiagnosticsEngine::Warning: - return "warning"; - case DiagnosticsEngine::Fatal: - case DiagnosticsEngine::Error: - return "error"; - } - llvm_unreachable("Invalid DiagnosticsEngine level!"); -} - -void arcmt::writeARCDiagsToPlist(const std::string &outPath, - ArrayRef diags, - SourceManager &SM, - const LangOptions &LangOpts) { - DiagnosticIDs DiagIDs; - - // Build up a set of FIDs that we use by scanning the locations and - // ranges of the diagnostics. - FIDMap FM; - SmallVector Fids; - - for (ArrayRef::iterator - I = diags.begin(), E = diags.end(); I != E; ++I) { - const StoredDiagnostic &D = *I; - - AddFID(FM, Fids, SM, D.getLocation()); - - for (StoredDiagnostic::range_iterator - RI = D.range_begin(), RE = D.range_end(); RI != RE; ++RI) { - AddFID(FM, Fids, SM, RI->getBegin()); - AddFID(FM, Fids, SM, RI->getEnd()); - } - } - - std::error_code EC; - llvm::raw_fd_ostream o(outPath, EC, llvm::sys::fs::OF_TextWithCRLF); - if (EC) { - llvm::errs() << "error: could not create file: " << outPath << '\n'; - return; - } - - EmitPlistHeader(o); - - // Write the root object: a containing... - // - "files", an mapping from FIDs to file names - // - "diagnostics", an containing the diagnostics - o << "\n" - " files\n" - " \n"; - - for (FileID FID : Fids) - EmitString(o << " ", SM.getFileEntryRefForID(FID)->getName()) << '\n'; - - o << " \n" - " diagnostics\n" - " \n"; - - for (ArrayRef::iterator - DI = diags.begin(), DE = diags.end(); DI != DE; ++DI) { - - const StoredDiagnostic &D = *DI; - - if (D.getLevel() == DiagnosticsEngine::Ignored) - continue; - - o << " \n"; - - // Output the diagnostic. - o << " description"; - EmitString(o, D.getMessage()) << '\n'; - o << " category"; - EmitString(o, DiagIDs.getCategoryNameFromID( - DiagIDs.getCategoryNumberForDiag(D.getID()))) << '\n'; - o << " type"; - EmitString(o, getLevelName(D.getLevel())) << '\n'; - - // Output the location of the bug. - o << " location\n"; - EmitLocation(o, SM, D.getLocation(), FM, 2); - - // Output the ranges (if any). - if (!D.getRanges().empty()) { - o << " ranges\n"; - o << " \n"; - for (auto &R : D.getRanges()) { - CharSourceRange ExpansionRange = SM.getExpansionRange(R); - EmitRange(o, SM, Lexer::getAsCharRange(ExpansionRange, SM, LangOpts), - FM, 4); - } - o << " \n"; - } - - // Close up the entry. - o << " \n"; - } - - o << " \n"; - - // Finish. - o << "\n\n"; -} diff --git a/clang/lib/ARCMigrate/TransAPIUses.cpp b/clang/lib/ARCMigrate/TransAPIUses.cpp deleted file mode 100644 index 8f5d4f4bde06c..0000000000000 --- a/clang/lib/ARCMigrate/TransAPIUses.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//===--- TransAPIUses.cpp - Transformations to ARC mode -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// checkAPIUses: -// -// Emits error/fix with some API uses that are obsolete or not safe in ARC mode: -// -// - NSInvocation's [get/set]ReturnValue and [get/set]Argument are only safe -// with __unsafe_unretained objects. -// - Calling -zone gets replaced with 'nil'. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class APIChecker : public RecursiveASTVisitor { - MigrationPass &Pass; - - Selector getReturnValueSel, setReturnValueSel; - Selector getArgumentSel, setArgumentSel; - - Selector zoneSel; -public: - APIChecker(MigrationPass &pass) : Pass(pass) { - SelectorTable &sels = Pass.Ctx.Selectors; - IdentifierTable &ids = Pass.Ctx.Idents; - getReturnValueSel = sels.getUnarySelector(&ids.get("getReturnValue")); - setReturnValueSel = sels.getUnarySelector(&ids.get("setReturnValue")); - - const IdentifierInfo *selIds[2]; - selIds[0] = &ids.get("getArgument"); - selIds[1] = &ids.get("atIndex"); - getArgumentSel = sels.getSelector(2, selIds); - selIds[0] = &ids.get("setArgument"); - setArgumentSel = sels.getSelector(2, selIds); - - zoneSel = sels.getNullarySelector(&ids.get("zone")); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - // NSInvocation. - if (E->isInstanceMessage() && - E->getReceiverInterface() && - E->getReceiverInterface()->getName() == "NSInvocation") { - StringRef selName; - if (E->getSelector() == getReturnValueSel) - selName = "getReturnValue"; - else if (E->getSelector() == setReturnValueSel) - selName = "setReturnValue"; - else if (E->getSelector() == getArgumentSel) - selName = "getArgument"; - else if (E->getSelector() == setArgumentSel) - selName = "setArgument"; - else - return true; - - Expr *parm = E->getArg(0)->IgnoreParenCasts(); - QualType pointee = parm->getType()->getPointeeType(); - if (pointee.isNull()) - return true; - - if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone) - Pass.TA.report(parm->getBeginLoc(), - diag::err_arcmt_nsinvocation_ownership, - parm->getSourceRange()) - << selName; - - return true; - } - - // -zone. - if (E->isInstanceMessage() && - E->getInstanceReceiver() && - E->getSelector() == zoneSel && - Pass.TA.hasDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - E->getSelectorLoc(0))) { - // Calling -zone is meaningless in ARC, change it to nil. - Transaction Trans(Pass.TA); - Pass.TA.clearDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - E->getSelectorLoc(0)); - Pass.TA.replace(E->getSourceRange(), getNilString(Pass)); - } - return true; - } -}; - -} // anonymous namespace - -void trans::checkAPIUses(MigrationPass &pass) { - APIChecker(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransARCAssign.cpp b/clang/lib/ARCMigrate/TransARCAssign.cpp deleted file mode 100644 index d1d5b9e014b17..0000000000000 --- a/clang/lib/ARCMigrate/TransARCAssign.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===--- TransARCAssign.cpp - Transformations to ARC mode -----------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// makeAssignARCSafe: -// -// Add '__strong' where appropriate. -// -// for (id x in collection) { -// x = 0; -// } -// ----> -// for (__strong id x in collection) { -// x = 0; -// } -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class ARCAssignChecker : public RecursiveASTVisitor { - MigrationPass &Pass; - llvm::DenseSet ModifiedVars; - -public: - ARCAssignChecker(MigrationPass &pass) : Pass(pass) { } - - bool VisitBinaryOperator(BinaryOperator *Exp) { - if (Exp->getType()->isDependentType()) - return true; - - Expr *E = Exp->getLHS(); - SourceLocation OrigLoc = E->getExprLoc(); - SourceLocation Loc = OrigLoc; - DeclRefExpr *declRef = dyn_cast(E->IgnoreParenCasts()); - if (declRef && isa(declRef->getDecl())) { - ASTContext &Ctx = Pass.Ctx; - Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(Ctx, &Loc); - if (IsLV != Expr::MLV_ConstQualified) - return true; - VarDecl *var = cast(declRef->getDecl()); - if (var->isARCPseudoStrong()) { - Transaction Trans(Pass.TA); - if (Pass.TA.clearDiagnostic(diag::err_typecheck_arr_assign_enumeration, - Exp->getOperatorLoc())) { - if (!ModifiedVars.count(var)) { - TypeLoc TLoc = var->getTypeSourceInfo()->getTypeLoc(); - Pass.TA.insert(TLoc.getBeginLoc(), "__strong "); - ModifiedVars.insert(var); - } - } - } - } - - return true; - } -}; - -} // anonymous namespace - -void trans::makeAssignARCSafe(MigrationPass &pass) { - ARCAssignChecker assignCheck(pass); - assignCheck.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp b/clang/lib/ARCMigrate/TransAutoreleasePool.cpp deleted file mode 100644 index 6d501228e712b..0000000000000 --- a/clang/lib/ARCMigrate/TransAutoreleasePool.cpp +++ /dev/null @@ -1,435 +0,0 @@ -//===--- TransAutoreleasePool.cpp - Transformations to ARC mode -----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteAutoreleasePool: -// -// Calls to NSAutoreleasePools will be rewritten as an @autorelease scope. -// -// NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; -// ... -// [pool release]; -// ----> -// @autorelease { -// ... -// } -// -// An NSAutoreleasePool will not be touched if: -// - There is not a corresponding -release/-drain in the same scope -// - Not all references of the NSAutoreleasePool variable can be removed -// - There is a variable that is declared inside the intended @autorelease scope -// which is also used outside it. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Sema/SemaDiagnostic.h" -#include - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class ReleaseCollector : public RecursiveASTVisitor { - Decl *Dcl; - SmallVectorImpl &Releases; - -public: - ReleaseCollector(Decl *D, SmallVectorImpl &releases) - : Dcl(D), Releases(releases) { } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (!E->isInstanceMessage()) - return true; - if (E->getMethodFamily() != OMF_release) - return true; - Expr *instance = E->getInstanceReceiver()->IgnoreParenCasts(); - if (DeclRefExpr *DE = dyn_cast(instance)) { - if (DE->getDecl() == Dcl) - Releases.push_back(E); - } - return true; - } -}; - -} - -namespace { - -class AutoreleasePoolRewriter - : public RecursiveASTVisitor { -public: - AutoreleasePoolRewriter(MigrationPass &pass) - : Body(nullptr), Pass(pass) { - PoolII = &pass.Ctx.Idents.get("NSAutoreleasePool"); - DrainSel = pass.Ctx.Selectors.getNullarySelector( - &pass.Ctx.Idents.get("drain")); - } - - void transformBody(Stmt *body, Decl *ParentD) { - Body = body; - TraverseStmt(body); - } - - ~AutoreleasePoolRewriter() { - SmallVector VarsToHandle; - - for (std::map::iterator - I = PoolVars.begin(), E = PoolVars.end(); I != E; ++I) { - VarDecl *var = I->first; - PoolVarInfo &info = I->second; - - // Check that we can handle/rewrite all references of the pool. - - clearRefsIn(info.Dcl, info.Refs); - for (SmallVectorImpl::iterator - scpI = info.Scopes.begin(), - scpE = info.Scopes.end(); scpI != scpE; ++scpI) { - PoolScope &scope = *scpI; - clearRefsIn(*scope.Begin, info.Refs); - clearRefsIn(*scope.End, info.Refs); - clearRefsIn(scope.Releases.begin(), scope.Releases.end(), info.Refs); - } - - // Even if one reference is not handled we will not do anything about that - // pool variable. - if (info.Refs.empty()) - VarsToHandle.push_back(var); - } - - for (unsigned i = 0, e = VarsToHandle.size(); i != e; ++i) { - PoolVarInfo &info = PoolVars[VarsToHandle[i]]; - - Transaction Trans(Pass.TA); - - clearUnavailableDiags(info.Dcl); - Pass.TA.removeStmt(info.Dcl); - - // Add "@autoreleasepool { }" - for (SmallVectorImpl::iterator - scpI = info.Scopes.begin(), - scpE = info.Scopes.end(); scpI != scpE; ++scpI) { - PoolScope &scope = *scpI; - clearUnavailableDiags(*scope.Begin); - clearUnavailableDiags(*scope.End); - if (scope.IsFollowedBySimpleReturnStmt) { - // Include the return in the scope. - Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {"); - Pass.TA.removeStmt(*scope.End); - Stmt::child_iterator retI = scope.End; - ++retI; - SourceLocation afterSemi = - findLocationAfterSemi((*retI)->getEndLoc(), Pass.Ctx); - assert(afterSemi.isValid() && - "Didn't we check before setting IsFollowedBySimpleReturnStmt " - "to true?"); - Pass.TA.insertAfterToken(afterSemi, "\n}"); - Pass.TA.increaseIndentation( - SourceRange(scope.getIndentedRange().getBegin(), - (*retI)->getEndLoc()), - scope.CompoundParent->getBeginLoc()); - } else { - Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {"); - Pass.TA.replaceStmt(*scope.End, "}"); - Pass.TA.increaseIndentation(scope.getIndentedRange(), - scope.CompoundParent->getBeginLoc()); - } - } - - // Remove rest of pool var references. - for (SmallVectorImpl::iterator - scpI = info.Scopes.begin(), - scpE = info.Scopes.end(); scpI != scpE; ++scpI) { - PoolScope &scope = *scpI; - for (SmallVectorImpl::iterator - relI = scope.Releases.begin(), - relE = scope.Releases.end(); relI != relE; ++relI) { - clearUnavailableDiags(*relI); - Pass.TA.removeStmt(*relI); - } - } - } - } - - bool VisitCompoundStmt(CompoundStmt *S) { - SmallVector Scopes; - - for (Stmt::child_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) { - Stmt *child = getEssential(*I); - if (DeclStmt *DclS = dyn_cast(child)) { - if (DclS->isSingleDecl()) { - if (VarDecl *VD = dyn_cast(DclS->getSingleDecl())) { - if (isNSAutoreleasePool(VD->getType())) { - PoolVarInfo &info = PoolVars[VD]; - info.Dcl = DclS; - collectRefs(VD, S, info.Refs); - // Does this statement follow the pattern: - // NSAutoreleasePool * pool = [NSAutoreleasePool new]; - if (isPoolCreation(VD->getInit())) { - Scopes.push_back(PoolScope()); - Scopes.back().PoolVar = VD; - Scopes.back().CompoundParent = S; - Scopes.back().Begin = I; - } - } - } - } - } else if (BinaryOperator *bop = dyn_cast(child)) { - if (DeclRefExpr *dref = dyn_cast(bop->getLHS())) { - if (VarDecl *VD = dyn_cast(dref->getDecl())) { - // Does this statement follow the pattern: - // pool = [NSAutoreleasePool new]; - if (isNSAutoreleasePool(VD->getType()) && - isPoolCreation(bop->getRHS())) { - Scopes.push_back(PoolScope()); - Scopes.back().PoolVar = VD; - Scopes.back().CompoundParent = S; - Scopes.back().Begin = I; - } - } - } - } - - if (Scopes.empty()) - continue; - - if (isPoolDrain(Scopes.back().PoolVar, child)) { - PoolScope &scope = Scopes.back(); - scope.End = I; - handlePoolScope(scope, S); - Scopes.pop_back(); - } - } - return true; - } - -private: - void clearUnavailableDiags(Stmt *S) { - if (S) - Pass.TA.clearDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - S->getSourceRange()); - } - - struct PoolScope { - VarDecl *PoolVar; - CompoundStmt *CompoundParent; - Stmt::child_iterator Begin; - Stmt::child_iterator End; - bool IsFollowedBySimpleReturnStmt; - SmallVector Releases; - - PoolScope() - : PoolVar(nullptr), CompoundParent(nullptr), - IsFollowedBySimpleReturnStmt(false) {} - - SourceRange getIndentedRange() const { - Stmt::child_iterator rangeS = Begin; - ++rangeS; - if (rangeS == End) - return SourceRange(); - Stmt::child_iterator rangeE = Begin; - for (Stmt::child_iterator I = rangeS; I != End; ++I) - ++rangeE; - return SourceRange((*rangeS)->getBeginLoc(), (*rangeE)->getEndLoc()); - } - }; - - class NameReferenceChecker : public RecursiveASTVisitor{ - ASTContext &Ctx; - SourceRange ScopeRange; - SourceLocation &referenceLoc, &declarationLoc; - - public: - NameReferenceChecker(ASTContext &ctx, PoolScope &scope, - SourceLocation &referenceLoc, - SourceLocation &declarationLoc) - : Ctx(ctx), referenceLoc(referenceLoc), - declarationLoc(declarationLoc) { - ScopeRange = SourceRange((*scope.Begin)->getBeginLoc(), - (*scope.End)->getBeginLoc()); - } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - return checkRef(E->getLocation(), E->getDecl()->getLocation()); - } - - bool VisitTypedefTypeLoc(TypedefTypeLoc TL) { - return checkRef(TL.getBeginLoc(), TL.getTypedefNameDecl()->getLocation()); - } - - bool VisitTagTypeLoc(TagTypeLoc TL) { - return checkRef(TL.getBeginLoc(), TL.getDecl()->getLocation()); - } - - private: - bool checkRef(SourceLocation refLoc, SourceLocation declLoc) { - if (isInScope(declLoc)) { - referenceLoc = refLoc; - declarationLoc = declLoc; - return false; - } - return true; - } - - bool isInScope(SourceLocation loc) { - if (loc.isInvalid()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - if (SM.isBeforeInTranslationUnit(loc, ScopeRange.getBegin())) - return false; - return SM.isBeforeInTranslationUnit(loc, ScopeRange.getEnd()); - } - }; - - void handlePoolScope(PoolScope &scope, CompoundStmt *compoundS) { - // Check that all names declared inside the scope are not used - // outside the scope. - { - bool nameUsedOutsideScope = false; - SourceLocation referenceLoc, declarationLoc; - Stmt::child_iterator SI = scope.End, SE = compoundS->body_end(); - ++SI; - // Check if the autoreleasepool scope is followed by a simple return - // statement, in which case we will include the return in the scope. - if (SI != SE) - if (ReturnStmt *retS = dyn_cast(*SI)) - if ((retS->getRetValue() == nullptr || - isa(retS->getRetValue()->IgnoreParenCasts())) && - findLocationAfterSemi(retS->getEndLoc(), Pass.Ctx).isValid()) { - scope.IsFollowedBySimpleReturnStmt = true; - ++SI; // the return will be included in scope, don't check it. - } - - for (; SI != SE; ++SI) { - nameUsedOutsideScope = !NameReferenceChecker(Pass.Ctx, scope, - referenceLoc, - declarationLoc).TraverseStmt(*SI); - if (nameUsedOutsideScope) - break; - } - - // If not all references were cleared it means some variables/typenames/etc - // declared inside the pool scope are used outside of it. - // We won't try to rewrite the pool. - if (nameUsedOutsideScope) { - Pass.TA.reportError("a name is referenced outside the " - "NSAutoreleasePool scope that it was declared in", referenceLoc); - Pass.TA.reportNote("name declared here", declarationLoc); - Pass.TA.reportNote("intended @autoreleasepool scope begins here", - (*scope.Begin)->getBeginLoc()); - Pass.TA.reportNote("intended @autoreleasepool scope ends here", - (*scope.End)->getBeginLoc()); - return; - } - } - - // Collect all releases of the pool; they will be removed. - { - ReleaseCollector releaseColl(scope.PoolVar, scope.Releases); - Stmt::child_iterator I = scope.Begin; - ++I; - for (; I != scope.End; ++I) - releaseColl.TraverseStmt(*I); - } - - PoolVars[scope.PoolVar].Scopes.push_back(scope); - } - - bool isPoolCreation(Expr *E) { - if (!E) return false; - E = getEssential(E); - ObjCMessageExpr *ME = dyn_cast(E); - if (!ME) return false; - if (ME->getMethodFamily() == OMF_new && - ME->getReceiverKind() == ObjCMessageExpr::Class && - isNSAutoreleasePool(ME->getReceiverInterface())) - return true; - if (ME->getReceiverKind() == ObjCMessageExpr::Instance && - ME->getMethodFamily() == OMF_init) { - Expr *rec = getEssential(ME->getInstanceReceiver()); - if (ObjCMessageExpr *recME = dyn_cast_or_null(rec)) { - if (recME->getMethodFamily() == OMF_alloc && - recME->getReceiverKind() == ObjCMessageExpr::Class && - isNSAutoreleasePool(recME->getReceiverInterface())) - return true; - } - } - - return false; - } - - bool isPoolDrain(VarDecl *poolVar, Stmt *S) { - if (!S) return false; - S = getEssential(S); - ObjCMessageExpr *ME = dyn_cast(S); - if (!ME) return false; - if (ME->getReceiverKind() == ObjCMessageExpr::Instance) { - Expr *rec = getEssential(ME->getInstanceReceiver()); - if (DeclRefExpr *dref = dyn_cast(rec)) - if (dref->getDecl() == poolVar) - return ME->getMethodFamily() == OMF_release || - ME->getSelector() == DrainSel; - } - - return false; - } - - bool isNSAutoreleasePool(ObjCInterfaceDecl *IDecl) { - return IDecl && IDecl->getIdentifier() == PoolII; - } - - bool isNSAutoreleasePool(QualType Ty) { - QualType pointee = Ty->getPointeeType(); - if (pointee.isNull()) - return false; - if (const ObjCInterfaceType *interT = pointee->getAs()) - return isNSAutoreleasePool(interT->getDecl()); - return false; - } - - static Expr *getEssential(Expr *E) { - return cast(getEssential((Stmt*)E)); - } - static Stmt *getEssential(Stmt *S) { - if (FullExpr *FE = dyn_cast(S)) - S = FE->getSubExpr(); - if (Expr *E = dyn_cast(S)) - S = E->IgnoreParenCasts(); - return S; - } - - Stmt *Body; - MigrationPass &Pass; - - IdentifierInfo *PoolII; - Selector DrainSel; - - struct PoolVarInfo { - DeclStmt *Dcl = nullptr; - ExprSet Refs; - SmallVector Scopes; - - PoolVarInfo() = default; - }; - - std::map PoolVars; -}; - -} // anonymous namespace - -void trans::rewriteAutoreleasePool(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp b/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp deleted file mode 100644 index 1e4db33135b6a..0000000000000 --- a/clang/lib/ARCMigrate/TransBlockObjCVariable.cpp +++ /dev/null @@ -1,146 +0,0 @@ -//===--- TransBlockObjCVariable.cpp - Transformations to ARC mode ---------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteBlockObjCVariable: -// -// Adding __block to an obj-c variable could be either because the variable -// is used for output storage or the user wanted to break a retain cycle. -// This transformation checks whether a reference of the variable for the block -// is actually needed (it is assigned to or its address is taken) or not. -// If the reference is not needed it will assume __block was added to break a -// cycle so it will remove '__block' and add __weak/__unsafe_unretained. -// e.g -// -// __block Foo *x; -// bar(^ { [x cake]; }); -// ----> -// __weak Foo *x; -// bar(^ { [x cake]; }); -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/Basic/SourceManager.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class RootBlockObjCVarRewriter : - public RecursiveASTVisitor { - llvm::DenseSet &VarsToChange; - - class BlockVarChecker : public RecursiveASTVisitor { - VarDecl *Var; - - typedef RecursiveASTVisitor base; - public: - BlockVarChecker(VarDecl *var) : Var(var) { } - - bool TraverseImplicitCastExpr(ImplicitCastExpr *castE) { - if (DeclRefExpr * - ref = dyn_cast(castE->getSubExpr())) { - if (ref->getDecl() == Var) { - if (castE->getCastKind() == CK_LValueToRValue) - return true; // Using the value of the variable. - if (castE->getCastKind() == CK_NoOp && castE->isLValue() && - Var->getASTContext().getLangOpts().CPlusPlus) - return true; // Binding to const C++ reference. - } - } - - return base::TraverseImplicitCastExpr(castE); - } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - if (E->getDecl() == Var) - return false; // The reference of the variable, and not just its value, - // is needed. - return true; - } - }; - -public: - RootBlockObjCVarRewriter(llvm::DenseSet &VarsToChange) - : VarsToChange(VarsToChange) { } - - bool VisitBlockDecl(BlockDecl *block) { - SmallVector BlockVars; - - for (const auto &I : block->captures()) { - VarDecl *var = I.getVariable(); - if (I.isByRef() && - var->getType()->isObjCObjectPointerType() && - isImplicitStrong(var->getType())) { - BlockVars.push_back(var); - } - } - - for (unsigned i = 0, e = BlockVars.size(); i != e; ++i) { - VarDecl *var = BlockVars[i]; - - BlockVarChecker checker(var); - bool onlyValueOfVarIsNeeded = checker.TraverseStmt(block->getBody()); - if (onlyValueOfVarIsNeeded) - VarsToChange.insert(var); - else - VarsToChange.erase(var); - } - - return true; - } - -private: - bool isImplicitStrong(QualType ty) { - if (isa(ty.getTypePtr())) - return false; - return ty.getLocalQualifiers().getObjCLifetime() == Qualifiers::OCL_Strong; - } -}; - -class BlockObjCVarRewriter : public RecursiveASTVisitor { - llvm::DenseSet &VarsToChange; - -public: - BlockObjCVarRewriter(llvm::DenseSet &VarsToChange) - : VarsToChange(VarsToChange) { } - - bool TraverseBlockDecl(BlockDecl *block) { - RootBlockObjCVarRewriter(VarsToChange).TraverseDecl(block); - return true; - } -}; - -} // anonymous namespace - -void BlockObjCVariableTraverser::traverseBody(BodyContext &BodyCtx) { - MigrationPass &Pass = BodyCtx.getMigrationContext().Pass; - llvm::DenseSet VarsToChange; - - BlockObjCVarRewriter trans(VarsToChange); - trans.TraverseStmt(BodyCtx.getTopStmt()); - - for (llvm::DenseSet::iterator - I = VarsToChange.begin(), E = VarsToChange.end(); I != E; ++I) { - VarDecl *var = *I; - BlocksAttr *attr = var->getAttr(); - if(!attr) - continue; - bool useWeak = canApplyWeak(Pass.Ctx, var->getType()); - SourceManager &SM = Pass.Ctx.getSourceManager(); - Transaction Trans(Pass.TA); - Pass.TA.replaceText(SM.getExpansionLoc(attr->getLocation()), - "__block", - useWeak ? "__weak" : "__unsafe_unretained"); - } -} diff --git a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp deleted file mode 100644 index e9c21b8106d7d..0000000000000 --- a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp +++ /dev/null @@ -1,249 +0,0 @@ -//===-- TransEmptyStatementsAndDealloc.cpp - Transformations to ARC mode --===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// removeEmptyStatementsAndDealloc: -// -// Removes empty statements that are leftovers from previous transformations. -// e.g for -// -// [x retain]; -// -// removeRetainReleaseDealloc will leave an empty ";" that removeEmptyStatements -// will remove. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/Basic/SourceManager.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -static bool isEmptyARCMTMacroStatement(NullStmt *S, - std::vector &MacroLocs, - ASTContext &Ctx) { - if (!S->hasLeadingEmptyMacro()) - return false; - - SourceLocation SemiLoc = S->getSemiLoc(); - if (SemiLoc.isInvalid() || SemiLoc.isMacroID()) - return false; - - if (MacroLocs.empty()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - std::vector::iterator I = llvm::upper_bound( - MacroLocs, SemiLoc, BeforeThanCompare(SM)); - --I; - SourceLocation - AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size()); - assert(AfterMacroLoc.isFileID()); - - if (AfterMacroLoc == SemiLoc) - return true; - - SourceLocation::IntTy RelOffs = 0; - if (!SM.isInSameSLocAddrSpace(AfterMacroLoc, SemiLoc, &RelOffs)) - return false; - if (RelOffs < 0) - return false; - - // We make the reasonable assumption that a semicolon after 100 characters - // means that it is not the next token after our macro. If this assumption - // fails it is not critical, we will just fail to clear out, e.g., an empty - // 'if'. - if (RelOffs - getARCMTMacroName().size() > 100) - return false; - - SourceLocation AfterMacroSemiLoc = findSemiAfterLocation(AfterMacroLoc, Ctx); - return AfterMacroSemiLoc == SemiLoc; -} - -namespace { - -/// Returns true if the statement became empty due to previous -/// transformations. -class EmptyChecker : public StmtVisitor { - ASTContext &Ctx; - std::vector &MacroLocs; - -public: - EmptyChecker(ASTContext &ctx, std::vector ¯oLocs) - : Ctx(ctx), MacroLocs(macroLocs) { } - - bool VisitNullStmt(NullStmt *S) { - return isEmptyARCMTMacroStatement(S, MacroLocs, Ctx); - } - bool VisitCompoundStmt(CompoundStmt *S) { - if (S->body_empty()) - return false; // was already empty, not because of transformations. - for (auto *I : S->body()) - if (!Visit(I)) - return false; - return true; - } - bool VisitIfStmt(IfStmt *S) { - if (S->getConditionVariable()) - return false; - Expr *condE = S->getCond(); - if (!condE) - return false; - if (hasSideEffects(condE, Ctx)) - return false; - if (!S->getThen() || !Visit(S->getThen())) - return false; - return !S->getElse() || Visit(S->getElse()); - } - bool VisitWhileStmt(WhileStmt *S) { - if (S->getConditionVariable()) - return false; - Expr *condE = S->getCond(); - if (!condE) - return false; - if (hasSideEffects(condE, Ctx)) - return false; - if (!S->getBody()) - return false; - return Visit(S->getBody()); - } - bool VisitDoStmt(DoStmt *S) { - Expr *condE = S->getCond(); - if (!condE) - return false; - if (hasSideEffects(condE, Ctx)) - return false; - if (!S->getBody()) - return false; - return Visit(S->getBody()); - } - bool VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { - Expr *Exp = S->getCollection(); - if (!Exp) - return false; - if (hasSideEffects(Exp, Ctx)) - return false; - if (!S->getBody()) - return false; - return Visit(S->getBody()); - } - bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { - if (!S->getSubStmt()) - return false; - return Visit(S->getSubStmt()); - } -}; - -class EmptyStatementsRemover : - public RecursiveASTVisitor { - MigrationPass &Pass; - -public: - EmptyStatementsRemover(MigrationPass &pass) : Pass(pass) { } - - bool TraverseStmtExpr(StmtExpr *E) { - CompoundStmt *S = E->getSubStmt(); - for (CompoundStmt::body_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) { - if (I != E - 1) - check(*I); - TraverseStmt(*I); - } - return true; - } - - bool VisitCompoundStmt(CompoundStmt *S) { - for (auto *I : S->body()) - check(I); - return true; - } - - ASTContext &getContext() { return Pass.Ctx; } - -private: - void check(Stmt *S) { - if (!S) return; - if (EmptyChecker(Pass.Ctx, Pass.ARCMTMacroLocs).Visit(S)) { - Transaction Trans(Pass.TA); - Pass.TA.removeStmt(S); - } - } -}; - -} // anonymous namespace - -static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx, - std::vector &MacroLocs) { - for (auto *I : body->body()) - if (!EmptyChecker(Ctx, MacroLocs).Visit(I)) - return false; - - return true; -} - -static void cleanupDeallocOrFinalize(MigrationPass &pass) { - ASTContext &Ctx = pass.Ctx; - TransformActions &TA = pass.TA; - DeclContext *DC = Ctx.getTranslationUnitDecl(); - Selector FinalizeSel = - Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); - - typedef DeclContext::specific_decl_iterator - impl_iterator; - for (impl_iterator I = impl_iterator(DC->decls_begin()), - E = impl_iterator(DC->decls_end()); I != E; ++I) { - ObjCMethodDecl *DeallocM = nullptr; - ObjCMethodDecl *FinalizeM = nullptr; - for (auto *MD : I->instance_methods()) { - if (!MD->hasBody()) - continue; - - if (MD->getMethodFamily() == OMF_dealloc) { - DeallocM = MD; - } else if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { - FinalizeM = MD; - } - } - - if (DeallocM) { - if (isBodyEmpty(DeallocM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { - Transaction Trans(TA); - TA.remove(DeallocM->getSourceRange()); - } - - if (FinalizeM) { - Transaction Trans(TA); - TA.remove(FinalizeM->getSourceRange()); - } - - } else if (FinalizeM) { - if (isBodyEmpty(FinalizeM->getCompoundBody(), Ctx, pass.ARCMTMacroLocs)) { - Transaction Trans(TA); - TA.remove(FinalizeM->getSourceRange()); - } else { - Transaction Trans(TA); - TA.replaceText(FinalizeM->getSelectorStartLoc(), "finalize", "dealloc"); - } - } - } -} - -void trans::removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass) { - EmptyStatementsRemover(pass).TraverseDecl(pass.Ctx.getTranslationUnitDecl()); - - cleanupDeallocOrFinalize(pass); - - for (unsigned i = 0, e = pass.ARCMTMacroLocs.size(); i != e; ++i) { - Transaction Trans(pass.TA); - pass.TA.remove(pass.ARCMTMacroLocs[i]); - } -} diff --git a/clang/lib/ARCMigrate/TransGCAttrs.cpp b/clang/lib/ARCMigrate/TransGCAttrs.cpp deleted file mode 100644 index 85e3fe77660b5..0000000000000 --- a/clang/lib/ARCMigrate/TransGCAttrs.cpp +++ /dev/null @@ -1,350 +0,0 @@ -//===--- TransGCAttrs.cpp - Transformations to ARC mode -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/TinyPtrVector.h" -#include "llvm/Support/SaveAndRestore.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -/// Collects all the places where GC attributes __strong/__weak occur. -class GCAttrsCollector : public RecursiveASTVisitor { - MigrationContext &MigrateCtx; - bool FullyMigratable; - std::vector &AllProps; - - typedef RecursiveASTVisitor base; -public: - GCAttrsCollector(MigrationContext &ctx, - std::vector &AllProps) - : MigrateCtx(ctx), FullyMigratable(false), - AllProps(AllProps) { } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitAttributedTypeLoc(AttributedTypeLoc TL) { - handleAttr(TL); - return true; - } - - bool TraverseDecl(Decl *D) { - if (!D || D->isImplicit()) - return true; - - SaveAndRestore Save(FullyMigratable, isMigratable(D)); - - if (ObjCPropertyDecl *PropD = dyn_cast(D)) { - lookForAttribute(PropD, PropD->getTypeSourceInfo()); - AllProps.push_back(PropD); - } else if (DeclaratorDecl *DD = dyn_cast(D)) { - lookForAttribute(DD, DD->getTypeSourceInfo()); - } - return base::TraverseDecl(D); - } - - void lookForAttribute(Decl *D, TypeSourceInfo *TInfo) { - if (!TInfo) - return; - TypeLoc TL = TInfo->getTypeLoc(); - while (TL) { - if (QualifiedTypeLoc QL = TL.getAs()) { - TL = QL.getUnqualifiedLoc(); - } else if (AttributedTypeLoc Attr = TL.getAs()) { - if (handleAttr(Attr, D)) - break; - TL = Attr.getModifiedLoc(); - } else if (MacroQualifiedTypeLoc MDTL = - TL.getAs()) { - TL = MDTL.getInnerLoc(); - } else if (ArrayTypeLoc Arr = TL.getAs()) { - TL = Arr.getElementLoc(); - } else if (PointerTypeLoc PT = TL.getAs()) { - TL = PT.getPointeeLoc(); - } else if (ReferenceTypeLoc RT = TL.getAs()) - TL = RT.getPointeeLoc(); - else - break; - } - } - - bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) { - auto *OwnershipAttr = TL.getAttrAs(); - if (!OwnershipAttr) - return false; - - SourceLocation Loc = OwnershipAttr->getLocation(); - SourceLocation OrigLoc = Loc; - if (MigrateCtx.AttrSet.count(OrigLoc)) - return true; - - ASTContext &Ctx = MigrateCtx.Pass.Ctx; - SourceManager &SM = Ctx.getSourceManager(); - if (Loc.isMacroID()) - Loc = SM.getImmediateExpansionRange(Loc).getBegin(); - StringRef Spell = OwnershipAttr->getKind()->getName(); - MigrationContext::GCAttrOccurrence::AttrKind Kind; - if (Spell == "strong") - Kind = MigrationContext::GCAttrOccurrence::Strong; - else if (Spell == "weak") - Kind = MigrationContext::GCAttrOccurrence::Weak; - else - return false; - - MigrateCtx.AttrSet.insert(OrigLoc); - MigrateCtx.GCAttrs.push_back(MigrationContext::GCAttrOccurrence()); - MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs.back(); - - Attr.Kind = Kind; - Attr.Loc = Loc; - Attr.ModifiedType = TL.getModifiedLoc().getType(); - Attr.Dcl = D; - Attr.FullyMigratable = FullyMigratable; - return true; - } - - bool isMigratable(Decl *D) { - if (isa(D)) - return false; - - if (isInMainFile(D)) - return true; - - if (FunctionDecl *FD = dyn_cast(D)) - return FD->hasBody(); - - if (ObjCContainerDecl *ContD = dyn_cast(D)) - return hasObjCImpl(ContD); - - if (CXXRecordDecl *RD = dyn_cast(D)) { - for (const auto *MI : RD->methods()) { - if (MI->isOutOfLine()) - return true; - } - return false; - } - - return isMigratable(cast(D->getDeclContext())); - } - - static bool hasObjCImpl(Decl *D) { - if (!D) - return false; - if (ObjCContainerDecl *ContD = dyn_cast(D)) { - if (ObjCInterfaceDecl *ID = dyn_cast(ContD)) - return ID->getImplementation() != nullptr; - if (ObjCCategoryDecl *CD = dyn_cast(ContD)) - return CD->getImplementation() != nullptr; - return isa(ContD); - } - return false; - } - - bool isInMainFile(Decl *D) { - if (!D) - return false; - - for (auto *I : D->redecls()) - if (!isInMainFile(I->getLocation())) - return false; - - return true; - } - - bool isInMainFile(SourceLocation Loc) { - if (Loc.isInvalid()) - return false; - - SourceManager &SM = MigrateCtx.Pass.Ctx.getSourceManager(); - return SM.isInFileID(SM.getExpansionLoc(Loc), SM.getMainFileID()); - } -}; - -} // anonymous namespace - -static void errorForGCAttrsOnNonObjC(MigrationContext &MigrateCtx) { - TransformActions &TA = MigrateCtx.Pass.TA; - - for (unsigned i = 0, e = MigrateCtx.GCAttrs.size(); i != e; ++i) { - MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs[i]; - if (Attr.FullyMigratable && Attr.Dcl) { - if (Attr.ModifiedType.isNull()) - continue; - if (!Attr.ModifiedType->isObjCRetainableType()) { - TA.reportError("GC managed memory will become unmanaged in ARC", - Attr.Loc); - } - } - } -} - -static void checkWeakGCAttrs(MigrationContext &MigrateCtx) { - TransformActions &TA = MigrateCtx.Pass.TA; - - for (unsigned i = 0, e = MigrateCtx.GCAttrs.size(); i != e; ++i) { - MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs[i]; - if (Attr.Kind == MigrationContext::GCAttrOccurrence::Weak) { - if (Attr.ModifiedType.isNull() || - !Attr.ModifiedType->isObjCRetainableType()) - continue; - if (!canApplyWeak(MigrateCtx.Pass.Ctx, Attr.ModifiedType, - /*AllowOnUnknownClass=*/true)) { - Transaction Trans(TA); - if (!MigrateCtx.RemovedAttrSet.count(Attr.Loc)) - TA.replaceText(Attr.Loc, "__weak", "__unsafe_unretained"); - TA.clearDiagnostic(diag::err_arc_weak_no_runtime, - diag::err_arc_unsupported_weak_class, - Attr.Loc); - } - } - } -} - -typedef llvm::TinyPtrVector IndivPropsTy; - -static void checkAllAtProps(MigrationContext &MigrateCtx, - SourceLocation AtLoc, - IndivPropsTy &IndProps) { - if (IndProps.empty()) - return; - - for (IndivPropsTy::iterator - PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) { - QualType T = (*PI)->getType(); - if (T.isNull() || !T->isObjCRetainableType()) - return; - } - - SmallVector, 4> ATLs; - bool hasWeak = false, hasStrong = false; - ObjCPropertyAttribute::Kind Attrs = ObjCPropertyAttribute::kind_noattr; - for (IndivPropsTy::iterator - PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) { - ObjCPropertyDecl *PD = *PI; - Attrs = PD->getPropertyAttributesAsWritten(); - TypeSourceInfo *TInfo = PD->getTypeSourceInfo(); - if (!TInfo) - return; - TypeLoc TL = TInfo->getTypeLoc(); - if (AttributedTypeLoc ATL = - TL.getAs()) { - ATLs.push_back(std::make_pair(ATL, PD)); - if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Weak) { - hasWeak = true; - } else if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Strong) - hasStrong = true; - else - return; - } - } - if (ATLs.empty()) - return; - if (hasWeak && hasStrong) - return; - - TransformActions &TA = MigrateCtx.Pass.TA; - Transaction Trans(TA); - - if (GCAttrsCollector::hasObjCImpl( - cast(IndProps.front()->getDeclContext()))) { - if (hasWeak) - MigrateCtx.AtPropsWeak.insert(AtLoc); - - } else { - StringRef toAttr = "strong"; - if (hasWeak) { - if (canApplyWeak(MigrateCtx.Pass.Ctx, IndProps.front()->getType(), - /*AllowOnUnknownClass=*/true)) - toAttr = "weak"; - else - toAttr = "unsafe_unretained"; - } - if (Attrs & ObjCPropertyAttribute::kind_assign) - MigrateCtx.rewritePropertyAttribute("assign", toAttr, AtLoc); - else - MigrateCtx.addPropertyAttribute(toAttr, AtLoc); - } - - for (unsigned i = 0, e = ATLs.size(); i != e; ++i) { - SourceLocation Loc = ATLs[i].first.getAttr()->getLocation(); - if (Loc.isMacroID()) - Loc = MigrateCtx.Pass.Ctx.getSourceManager() - .getImmediateExpansionRange(Loc) - .getBegin(); - TA.remove(Loc); - TA.clearDiagnostic(diag::err_objc_property_attr_mutually_exclusive, AtLoc); - TA.clearDiagnostic(diag::err_arc_inconsistent_property_ownership, - ATLs[i].second->getLocation()); - MigrateCtx.RemovedAttrSet.insert(Loc); - } -} - -static void checkAllProps(MigrationContext &MigrateCtx, - std::vector &AllProps) { - typedef llvm::TinyPtrVector IndivPropsTy; - llvm::DenseMap AtProps; - - for (unsigned i = 0, e = AllProps.size(); i != e; ++i) { - ObjCPropertyDecl *PD = AllProps[i]; - if (PD->getPropertyAttributesAsWritten() & - (ObjCPropertyAttribute::kind_assign | - ObjCPropertyAttribute::kind_readonly)) { - SourceLocation AtLoc = PD->getAtLoc(); - if (AtLoc.isInvalid()) - continue; - AtProps[AtLoc].push_back(PD); - } - } - - for (auto I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { - SourceLocation AtLoc = I->first; - IndivPropsTy &IndProps = I->second; - checkAllAtProps(MigrateCtx, AtLoc, IndProps); - } -} - -void GCAttrsTraverser::traverseTU(MigrationContext &MigrateCtx) { - std::vector AllProps; - GCAttrsCollector(MigrateCtx, AllProps).TraverseDecl( - MigrateCtx.Pass.Ctx.getTranslationUnitDecl()); - - errorForGCAttrsOnNonObjC(MigrateCtx); - checkAllProps(MigrateCtx, AllProps); - checkWeakGCAttrs(MigrateCtx); -} - -void MigrationContext::dumpGCAttrs() { - llvm::errs() << "\n################\n"; - for (unsigned i = 0, e = GCAttrs.size(); i != e; ++i) { - GCAttrOccurrence &Attr = GCAttrs[i]; - llvm::errs() << "KIND: " - << (Attr.Kind == GCAttrOccurrence::Strong ? "strong" : "weak"); - llvm::errs() << "\nLOC: "; - Attr.Loc.print(llvm::errs(), Pass.Ctx.getSourceManager()); - llvm::errs() << "\nTYPE: "; - Attr.ModifiedType.dump(); - if (Attr.Dcl) { - llvm::errs() << "DECL:\n"; - Attr.Dcl->dump(); - } else { - llvm::errs() << "DECL: NONE"; - } - llvm::errs() << "\nMIGRATABLE: " << Attr.FullyMigratable; - llvm::errs() << "\n----------------\n"; - } - llvm::errs() << "\n################\n"; -} diff --git a/clang/lib/ARCMigrate/TransGCCalls.cpp b/clang/lib/ARCMigrate/TransGCCalls.cpp deleted file mode 100644 index 43233e2d0b456..0000000000000 --- a/clang/lib/ARCMigrate/TransGCCalls.cpp +++ /dev/null @@ -1,76 +0,0 @@ -//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class GCCollectableCallsChecker : - public RecursiveASTVisitor { - MigrationContext &MigrateCtx; - IdentifierInfo *NSMakeCollectableII; - IdentifierInfo *CFMakeCollectableII; - -public: - GCCollectableCallsChecker(MigrationContext &ctx) - : MigrateCtx(ctx) { - IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents; - NSMakeCollectableII = &Ids.get("NSMakeCollectable"); - CFMakeCollectableII = &Ids.get("CFMakeCollectable"); - } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool VisitCallExpr(CallExpr *E) { - TransformActions &TA = MigrateCtx.Pass.TA; - - if (MigrateCtx.isGCOwnedNonObjC(E->getType())) { - TA.report(E->getBeginLoc(), diag::warn_arcmt_nsalloc_realloc, - E->getSourceRange()); - return true; - } - - Expr *CEE = E->getCallee()->IgnoreParenImpCasts(); - if (DeclRefExpr *DRE = dyn_cast(CEE)) { - if (FunctionDecl *FD = dyn_cast_or_null(DRE->getDecl())) { - if (!FD->getDeclContext()->getRedeclContext()->isFileContext()) - return true; - - if (FD->getIdentifier() == NSMakeCollectableII) { - Transaction Trans(TA); - TA.clearDiagnostic(diag::err_unavailable, - diag::err_unavailable_message, - diag::err_ovl_deleted_call, // ObjC++ - DRE->getSourceRange()); - TA.replace(DRE->getSourceRange(), "CFBridgingRelease"); - - } else if (FD->getIdentifier() == CFMakeCollectableII) { - TA.reportError("CFMakeCollectable will leak the object that it " - "receives in ARC", DRE->getLocation(), - DRE->getSourceRange()); - } - } - } - - return true; - } -}; - -} // anonymous namespace - -void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) { - GCCollectableCallsChecker(BodyCtx.getMigrationContext()) - .TraverseStmt(BodyCtx.getTopStmt()); -} diff --git a/clang/lib/ARCMigrate/TransProperties.cpp b/clang/lib/ARCMigrate/TransProperties.cpp deleted file mode 100644 index 6d1d950821a07..0000000000000 --- a/clang/lib/ARCMigrate/TransProperties.cpp +++ /dev/null @@ -1,379 +0,0 @@ -//===--- TransProperties.cpp - Transformations to ARC mode ----------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteProperties: -// -// - Adds strong/weak/unsafe_unretained ownership specifier to properties that -// are missing one. -// - Migrates properties from (retain) to (strong) and (assign) to -// (unsafe_unretained/weak). -// - If a property is synthesized, adds the ownership specifier in the ivar -// backing the property. -// -// @interface Foo : NSObject { -// NSObject *x; -// } -// @property (assign) id x; -// @end -// ----> -// @interface Foo : NSObject { -// NSObject *__weak x; -// } -// @property (weak) id x; -// @end -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class PropertiesRewriter { - MigrationContext &MigrateCtx; - MigrationPass &Pass; - ObjCImplementationDecl *CurImplD = nullptr; - - enum PropActionKind { - PropAction_None, - PropAction_RetainReplacedWithStrong, - PropAction_AssignRemoved, - PropAction_AssignRewritten, - PropAction_MaybeAddWeakOrUnsafe - }; - - struct PropData { - ObjCPropertyDecl *PropD; - ObjCIvarDecl *IvarD; - ObjCPropertyImplDecl *ImplD; - - PropData(ObjCPropertyDecl *propD) - : PropD(propD), IvarD(nullptr), ImplD(nullptr) {} - }; - - typedef SmallVector PropsTy; - typedef std::map AtPropDeclsTy; - AtPropDeclsTy AtProps; - llvm::DenseMap ActionOnProp; - -public: - explicit PropertiesRewriter(MigrationContext &MigrateCtx) - : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { } - - static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps, - AtPropDeclsTy *PrevAtProps = nullptr) { - for (auto *Prop : D->instance_properties()) { - SourceLocation Loc = Prop->getAtLoc(); - if (Loc.isInvalid()) - continue; - if (PrevAtProps) - if (PrevAtProps->find(Loc) != PrevAtProps->end()) - continue; - PropsTy &props = AtProps[Loc]; - props.push_back(Prop); - } - } - - void doTransform(ObjCImplementationDecl *D) { - CurImplD = D; - ObjCInterfaceDecl *iface = D->getClassInterface(); - if (!iface) - return; - - collectProperties(iface, AtProps); - - // Look through extensions. - for (auto *Ext : iface->visible_extensions()) - collectProperties(Ext, AtProps); - - typedef DeclContext::specific_decl_iterator - prop_impl_iterator; - for (prop_impl_iterator - I = prop_impl_iterator(D->decls_begin()), - E = prop_impl_iterator(D->decls_end()); I != E; ++I) { - ObjCPropertyImplDecl *implD = *I; - if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) - continue; - ObjCPropertyDecl *propD = implD->getPropertyDecl(); - if (!propD || propD->isInvalidDecl()) - continue; - ObjCIvarDecl *ivarD = implD->getPropertyIvarDecl(); - if (!ivarD || ivarD->isInvalidDecl()) - continue; - AtPropDeclsTy::iterator findAtLoc = AtProps.find(propD->getAtLoc()); - if (findAtLoc == AtProps.end()) - continue; - - PropsTy &props = findAtLoc->second; - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (I->PropD == propD) { - I->IvarD = ivarD; - I->ImplD = implD; - break; - } - } - } - - for (AtPropDeclsTy::iterator - I = AtProps.begin(), E = AtProps.end(); I != E; ++I) { - SourceLocation atLoc = I->first; - PropsTy &props = I->second; - if (!getPropertyType(props)->isObjCRetainableType()) - continue; - if (hasIvarWithExplicitARCOwnership(props)) - continue; - - Transaction Trans(Pass.TA); - rewriteProperty(props, atLoc); - } - } - -private: - void doPropAction(PropActionKind kind, - PropsTy &props, SourceLocation atLoc, - bool markAction = true) { - if (markAction) - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) - ActionOnProp[I->PropD->getIdentifier()] = kind; - - switch (kind) { - case PropAction_None: - return; - case PropAction_RetainReplacedWithStrong: { - StringRef toAttr = "strong"; - MigrateCtx.rewritePropertyAttribute("retain", toAttr, atLoc); - return; - } - case PropAction_AssignRemoved: - return removeAssignForDefaultStrong(props, atLoc); - case PropAction_AssignRewritten: - return rewriteAssign(props, atLoc); - case PropAction_MaybeAddWeakOrUnsafe: - return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc); - } - } - - void rewriteProperty(PropsTy &props, SourceLocation atLoc) { - ObjCPropertyAttribute::Kind propAttrs = getPropertyAttrs(props); - - if (propAttrs & - (ObjCPropertyAttribute::kind_copy | - ObjCPropertyAttribute::kind_unsafe_unretained | - ObjCPropertyAttribute::kind_strong | ObjCPropertyAttribute::kind_weak)) - return; - - if (propAttrs & ObjCPropertyAttribute::kind_retain) { - // strong is the default. - return doPropAction(PropAction_RetainReplacedWithStrong, props, atLoc); - } - - bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props); - - if (propAttrs & ObjCPropertyAttribute::kind_assign) { - if (HasIvarAssignedAPlusOneObject) - return doPropAction(PropAction_AssignRemoved, props, atLoc); - return doPropAction(PropAction_AssignRewritten, props, atLoc); - } - - if (HasIvarAssignedAPlusOneObject || - (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) - return; // 'strong' by default. - - return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc); - } - - void removeAssignForDefaultStrong(PropsTy &props, - SourceLocation atLoc) const { - removeAttribute("retain", atLoc); - if (!removeAttribute("assign", atLoc)) - return; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (I->ImplD) - Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, - diag::err_arc_assign_property_ownership, - diag::err_arc_inconsistent_property_ownership, - I->IvarD->getLocation()); - } - } - - void rewriteAssign(PropsTy &props, SourceLocation atLoc) const { - bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), - /*AllowOnUnknownClass=*/Pass.isGCMigration()); - const char *toWhich = - (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "strong" : - (canUseWeak ? "weak" : "unsafe_unretained"); - - bool rewroteAttr = rewriteAttribute("assign", toWhich, atLoc); - if (!rewroteAttr) - canUseWeak = false; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (isUserDeclared(I->IvarD)) { - if (I->IvarD && - I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) { - const char *toWhich = - (Pass.isGCMigration() && !hasGCWeak(props, atLoc)) ? "__strong " : - (canUseWeak ? "__weak " : "__unsafe_unretained "); - Pass.TA.insert(I->IvarD->getLocation(), toWhich); - } - } - if (I->ImplD) - Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, - diag::err_arc_assign_property_ownership, - diag::err_arc_inconsistent_property_ownership, - I->IvarD->getLocation()); - } - } - - void maybeAddWeakOrUnsafeUnretainedAttr(PropsTy &props, - SourceLocation atLoc) const { - bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props), - /*AllowOnUnknownClass=*/Pass.isGCMigration()); - - bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained", - atLoc); - if (!addedAttr) - canUseWeak = false; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (isUserDeclared(I->IvarD)) { - if (I->IvarD && - I->IvarD->getType().getObjCLifetime() != Qualifiers::OCL_Weak) - Pass.TA.insert(I->IvarD->getLocation(), - canUseWeak ? "__weak " : "__unsafe_unretained "); - } - if (I->ImplD) { - Pass.TA.clearDiagnostic(diag::err_arc_strong_property_ownership, - diag::err_arc_assign_property_ownership, - diag::err_arc_inconsistent_property_ownership, - I->IvarD->getLocation()); - Pass.TA.clearDiagnostic( - diag::err_arc_objc_property_default_assign_on_object, - I->ImplD->getLocation()); - } - } - } - - bool removeAttribute(StringRef fromAttr, SourceLocation atLoc) const { - return MigrateCtx.removePropertyAttribute(fromAttr, atLoc); - } - - bool rewriteAttribute(StringRef fromAttr, StringRef toAttr, - SourceLocation atLoc) const { - return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc); - } - - bool addAttribute(StringRef attr, SourceLocation atLoc) const { - return MigrateCtx.addPropertyAttribute(attr, atLoc); - } - - class PlusOneAssign : public RecursiveASTVisitor { - ObjCIvarDecl *Ivar; - public: - PlusOneAssign(ObjCIvarDecl *D) : Ivar(D) {} - - bool VisitBinaryOperator(BinaryOperator *E) { - if (E->getOpcode() != BO_Assign) - return true; - - Expr *lhs = E->getLHS()->IgnoreParenImpCasts(); - if (ObjCIvarRefExpr *RE = dyn_cast(lhs)) { - if (RE->getDecl() != Ivar) - return true; - - if (isPlusOneAssign(E)) - return false; - } - - return true; - } - }; - - bool hasIvarAssignedAPlusOneObject(PropsTy &props) const { - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - PlusOneAssign oneAssign(I->IvarD); - bool notFound = oneAssign.TraverseDecl(CurImplD); - if (!notFound) - return true; - } - - return false; - } - - bool hasIvarWithExplicitARCOwnership(PropsTy &props) const { - if (Pass.isGCMigration()) - return false; - - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) { - if (isUserDeclared(I->IvarD)) { - if (isa(I->IvarD->getType())) - return true; - if (I->IvarD->getType().getLocalQualifiers().getObjCLifetime() - != Qualifiers::OCL_Strong) - return true; - } - } - - return false; - } - - // Returns true if all declarations in the @property have GC __weak. - bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const { - if (!Pass.isGCMigration()) - return false; - if (props.empty()) - return false; - return MigrateCtx.AtPropsWeak.count(atLoc); - } - - bool isUserDeclared(ObjCIvarDecl *ivarD) const { - return ivarD && !ivarD->getSynthesize(); - } - - QualType getPropertyType(PropsTy &props) const { - assert(!props.empty()); - QualType ty = props[0].PropD->getType().getUnqualifiedType(); - -#ifndef NDEBUG - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) - assert(ty == I->PropD->getType().getUnqualifiedType()); -#endif - - return ty; - } - - ObjCPropertyAttribute::Kind getPropertyAttrs(PropsTy &props) const { - assert(!props.empty()); - ObjCPropertyAttribute::Kind attrs = - props[0].PropD->getPropertyAttributesAsWritten(); - -#ifndef NDEBUG - for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) - assert(attrs == I->PropD->getPropertyAttributesAsWritten()); -#endif - - return attrs; - } -}; - -} // anonymous namespace - -void PropertyRewriteTraverser::traverseObjCImplementation( - ObjCImplementationContext &ImplCtx) { - PropertiesRewriter(ImplCtx.getMigrationContext()) - .doTransform(ImplCtx.getImplementationDecl()); -} diff --git a/clang/lib/ARCMigrate/TransProtectedScope.cpp b/clang/lib/ARCMigrate/TransProtectedScope.cpp deleted file mode 100644 index 154e0b54800f9..0000000000000 --- a/clang/lib/ARCMigrate/TransProtectedScope.cpp +++ /dev/null @@ -1,203 +0,0 @@ -//===--- TransProtectedScope.cpp - Transformations to ARC mode ------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Adds brackets in case statements that "contain" initialization of retaining -// variable, thus emitting the "switch case is in protected scope" error. -// -//===----------------------------------------------------------------------===// - -#include "Internals.h" -#include "Transforms.h" -#include "clang/AST/ASTContext.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class LocalRefsCollector : public RecursiveASTVisitor { - SmallVectorImpl &Refs; - -public: - LocalRefsCollector(SmallVectorImpl &refs) - : Refs(refs) { } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - if (ValueDecl *D = E->getDecl()) - if (D->getDeclContext()->getRedeclContext()->isFunctionOrMethod()) - Refs.push_back(E); - return true; - } -}; - -struct CaseInfo { - SwitchCase *SC; - SourceRange Range; - enum { - St_Unchecked, - St_CannotFix, - St_Fixed - } State; - - CaseInfo() : SC(nullptr), State(St_Unchecked) {} - CaseInfo(SwitchCase *S, SourceRange Range) - : SC(S), Range(Range), State(St_Unchecked) {} -}; - -class CaseCollector : public RecursiveASTVisitor { - ParentMap &PMap; - SmallVectorImpl &Cases; - -public: - CaseCollector(ParentMap &PMap, SmallVectorImpl &Cases) - : PMap(PMap), Cases(Cases) { } - - bool VisitSwitchStmt(SwitchStmt *S) { - SwitchCase *Curr = S->getSwitchCaseList(); - if (!Curr) - return true; - Stmt *Parent = getCaseParent(Curr); - Curr = Curr->getNextSwitchCase(); - // Make sure all case statements are in the same scope. - while (Curr) { - if (getCaseParent(Curr) != Parent) - return true; - Curr = Curr->getNextSwitchCase(); - } - - SourceLocation NextLoc = S->getEndLoc(); - Curr = S->getSwitchCaseList(); - // We iterate over case statements in reverse source-order. - while (Curr) { - Cases.push_back( - CaseInfo(Curr, SourceRange(Curr->getBeginLoc(), NextLoc))); - NextLoc = Curr->getBeginLoc(); - Curr = Curr->getNextSwitchCase(); - } - return true; - } - - Stmt *getCaseParent(SwitchCase *S) { - Stmt *Parent = PMap.getParent(S); - while (Parent && (isa(Parent) || isa(Parent))) - Parent = PMap.getParent(Parent); - return Parent; - } -}; - -class ProtectedScopeFixer { - MigrationPass &Pass; - SourceManager &SM; - SmallVector Cases; - SmallVector LocalRefs; - -public: - ProtectedScopeFixer(BodyContext &BodyCtx) - : Pass(BodyCtx.getMigrationContext().Pass), - SM(Pass.Ctx.getSourceManager()) { - - CaseCollector(BodyCtx.getParentMap(), Cases) - .TraverseStmt(BodyCtx.getTopStmt()); - LocalRefsCollector(LocalRefs).TraverseStmt(BodyCtx.getTopStmt()); - - SourceRange BodyRange = BodyCtx.getTopStmt()->getSourceRange(); - const CapturedDiagList &DiagList = Pass.getDiags(); - // Copy the diagnostics so we don't have to worry about invaliding iterators - // from the diagnostic list. - SmallVector StoredDiags; - StoredDiags.append(DiagList.begin(), DiagList.end()); - SmallVectorImpl::iterator - I = StoredDiags.begin(), E = StoredDiags.end(); - while (I != E) { - if (I->getID() == diag::err_switch_into_protected_scope && - isInRange(I->getLocation(), BodyRange)) { - handleProtectedScopeError(I, E); - continue; - } - ++I; - } - } - - void handleProtectedScopeError( - SmallVectorImpl::iterator &DiagI, - SmallVectorImpl::iterator DiagE){ - Transaction Trans(Pass.TA); - assert(DiagI->getID() == diag::err_switch_into_protected_scope); - SourceLocation ErrLoc = DiagI->getLocation(); - bool handledAllNotes = true; - ++DiagI; - for (; DiagI != DiagE && DiagI->getLevel() == DiagnosticsEngine::Note; - ++DiagI) { - if (!handleProtectedNote(*DiagI)) - handledAllNotes = false; - } - - if (handledAllNotes) - Pass.TA.clearDiagnostic(diag::err_switch_into_protected_scope, ErrLoc); - } - - bool handleProtectedNote(const StoredDiagnostic &Diag) { - assert(Diag.getLevel() == DiagnosticsEngine::Note); - - for (unsigned i = 0; i != Cases.size(); i++) { - CaseInfo &info = Cases[i]; - if (isInRange(Diag.getLocation(), info.Range)) { - - if (info.State == CaseInfo::St_Unchecked) - tryFixing(info); - assert(info.State != CaseInfo::St_Unchecked); - - if (info.State == CaseInfo::St_Fixed) { - Pass.TA.clearDiagnostic(Diag.getID(), Diag.getLocation()); - return true; - } - return false; - } - } - - return false; - } - - void tryFixing(CaseInfo &info) { - assert(info.State == CaseInfo::St_Unchecked); - if (hasVarReferencedOutside(info)) { - info.State = CaseInfo::St_CannotFix; - return; - } - - Pass.TA.insertAfterToken(info.SC->getColonLoc(), " {"); - Pass.TA.insert(info.Range.getEnd(), "}\n"); - info.State = CaseInfo::St_Fixed; - } - - bool hasVarReferencedOutside(CaseInfo &info) { - for (unsigned i = 0, e = LocalRefs.size(); i != e; ++i) { - DeclRefExpr *DRE = LocalRefs[i]; - if (isInRange(DRE->getDecl()->getLocation(), info.Range) && - !isInRange(DRE->getLocation(), info.Range)) - return true; - } - return false; - } - - bool isInRange(SourceLocation Loc, SourceRange R) { - if (Loc.isInvalid()) - return false; - return !SM.isBeforeInTranslationUnit(Loc, R.getBegin()) && - SM.isBeforeInTranslationUnit(Loc, R.getEnd()); - } -}; - -} // anonymous namespace - -void ProtectedScopeTraverser::traverseBody(BodyContext &BodyCtx) { - ProtectedScopeFixer Fix(BodyCtx); -} diff --git a/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp deleted file mode 100644 index baa503d8a39dc..0000000000000 --- a/clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp +++ /dev/null @@ -1,459 +0,0 @@ -//===--- TransRetainReleaseDealloc.cpp - Transformations to ARC mode ------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// removeRetainReleaseDealloc: -// -// Removes retain/release/autorelease/dealloc messages. -// -// return [[foo retain] autorelease]; -// ----> -// return foo; -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/ParentMap.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "llvm/ADT/StringSwitch.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class RetainReleaseDeallocRemover : - public RecursiveASTVisitor { - Stmt *Body; - MigrationPass &Pass; - - ExprSet Removables; - std::unique_ptr StmtMap; - - Selector DelegateSel, FinalizeSel; - -public: - RetainReleaseDeallocRemover(MigrationPass &pass) - : Body(nullptr), Pass(pass) { - DelegateSel = - Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("delegate")); - FinalizeSel = - Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); - } - - void transformBody(Stmt *body, Decl *ParentD) { - Body = body; - collectRemovables(body, Removables); - StmtMap.reset(new ParentMap(body)); - TraverseStmt(body); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *E) { - switch (E->getMethodFamily()) { - default: - if (E->isInstanceMessage() && E->getSelector() == FinalizeSel) - break; - return true; - case OMF_autorelease: - if (isRemovable(E)) { - if (!isCommonUnusedAutorelease(E)) { - // An unused autorelease is badness. If we remove it the receiver - // will likely die immediately while previously it was kept alive - // by the autorelease pool. This is bad practice in general, leave it - // and emit an error to force the user to restructure their code. - Pass.TA.reportError( - "it is not safe to remove an unused 'autorelease' " - "message; its receiver may be destroyed immediately", - E->getBeginLoc(), E->getSourceRange()); - return true; - } - } - // Pass through. - [[fallthrough]]; - case OMF_retain: - case OMF_release: - if (E->getReceiverKind() == ObjCMessageExpr::Instance) - if (Expr *rec = E->getInstanceReceiver()) { - rec = rec->IgnoreParenImpCasts(); - if (rec->getType().getObjCLifetime() == Qualifiers::OCL_ExplicitNone && - (E->getMethodFamily() != OMF_retain || isRemovable(E))) { - std::string err = "it is not safe to remove '"; - err += E->getSelector().getAsString() + "' message on " - "an __unsafe_unretained type"; - Pass.TA.reportError(err, rec->getBeginLoc()); - return true; - } - - if (isGlobalVar(rec) && - (E->getMethodFamily() != OMF_retain || isRemovable(E))) { - std::string err = "it is not safe to remove '"; - err += E->getSelector().getAsString() + "' message on " - "a global variable"; - Pass.TA.reportError(err, rec->getBeginLoc()); - return true; - } - - if (E->getMethodFamily() == OMF_release && isDelegateMessage(rec)) { - Pass.TA.reportError( - "it is not safe to remove 'retain' " - "message on the result of a 'delegate' message; " - "the object that was passed to 'setDelegate:' may not be " - "properly retained", - rec->getBeginLoc()); - return true; - } - } - break; - case OMF_dealloc: - break; - } - - switch (E->getReceiverKind()) { - default: - return true; - case ObjCMessageExpr::SuperInstance: { - Transaction Trans(Pass.TA); - clearDiagnostics(E->getSelectorLoc(0)); - if (tryRemoving(E)) - return true; - Pass.TA.replace(E->getSourceRange(), "self"); - return true; - } - case ObjCMessageExpr::Instance: - break; - } - - Expr *rec = E->getInstanceReceiver(); - if (!rec) return true; - - Transaction Trans(Pass.TA); - clearDiagnostics(E->getSelectorLoc(0)); - - ObjCMessageExpr *Msg = E; - Expr *RecContainer = Msg; - SourceRange RecRange = rec->getSourceRange(); - checkForGCDOrXPC(Msg, RecContainer, rec, RecRange); - - if (Msg->getMethodFamily() == OMF_release && - isRemovable(RecContainer) && isInAtFinally(RecContainer)) { - // Change the -release to "receiver = nil" in a finally to avoid a leak - // when an exception is thrown. - Pass.TA.replace(RecContainer->getSourceRange(), RecRange); - std::string str = " = "; - str += getNilString(Pass); - Pass.TA.insertAfterToken(RecRange.getEnd(), str); - return true; - } - - if (hasSideEffects(rec, Pass.Ctx) || !tryRemoving(RecContainer)) - Pass.TA.replace(RecContainer->getSourceRange(), RecRange); - - return true; - } - -private: - /// Checks for idioms where an unused -autorelease is common. - /// - /// Returns true for this idiom which is common in property - /// setters: - /// - /// [backingValue autorelease]; - /// backingValue = [newValue retain]; // in general a +1 assign - /// - /// For these as well: - /// - /// [[var retain] autorelease]; - /// return var; - /// - bool isCommonUnusedAutorelease(ObjCMessageExpr *E) { - return isPlusOneAssignBeforeOrAfterAutorelease(E) || - isReturnedAfterAutorelease(E); - } - - bool isReturnedAfterAutorelease(ObjCMessageExpr *E) { - Expr *Rec = E->getInstanceReceiver(); - if (!Rec) - return false; - - Decl *RefD = getReferencedDecl(Rec); - if (!RefD) - return false; - - Stmt *nextStmt = getNextStmt(E); - if (!nextStmt) - return false; - - // Check for "return ;". - - if (ReturnStmt *RetS = dyn_cast(nextStmt)) - return RefD == getReferencedDecl(RetS->getRetValue()); - - return false; - } - - bool isPlusOneAssignBeforeOrAfterAutorelease(ObjCMessageExpr *E) { - Expr *Rec = E->getInstanceReceiver(); - if (!Rec) - return false; - - Decl *RefD = getReferencedDecl(Rec); - if (!RefD) - return false; - - Stmt *prevStmt, *nextStmt; - std::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E); - - return isPlusOneAssignToVar(prevStmt, RefD) || - isPlusOneAssignToVar(nextStmt, RefD); - } - - bool isPlusOneAssignToVar(Stmt *S, Decl *RefD) { - if (!S) - return false; - - // Check for "RefD = [+1 retained object];". - - if (BinaryOperator *Bop = dyn_cast(S)) { - return (RefD == getReferencedDecl(Bop->getLHS())) && isPlusOneAssign(Bop); - } - - if (DeclStmt *DS = dyn_cast(S)) { - if (DS->isSingleDecl() && DS->getSingleDecl() == RefD) { - if (VarDecl *VD = dyn_cast(RefD)) - return isPlusOne(VD->getInit()); - } - return false; - } - - return false; - } - - Stmt *getNextStmt(Expr *E) { - return getPreviousAndNextStmt(E).second; - } - - std::pair getPreviousAndNextStmt(Expr *E) { - Stmt *prevStmt = nullptr, *nextStmt = nullptr; - if (!E) - return std::make_pair(prevStmt, nextStmt); - - Stmt *OuterS = E, *InnerS; - do { - InnerS = OuterS; - OuterS = StmtMap->getParent(InnerS); - } - while (OuterS && (isa(OuterS) || - isa(OuterS) || - isa(OuterS))); - - if (!OuterS) - return std::make_pair(prevStmt, nextStmt); - - Stmt::child_iterator currChildS = OuterS->child_begin(); - Stmt::child_iterator childE = OuterS->child_end(); - Stmt::child_iterator prevChildS = childE; - for (; currChildS != childE; ++currChildS) { - if (*currChildS == InnerS) - break; - prevChildS = currChildS; - } - - if (prevChildS != childE) { - prevStmt = *prevChildS; - if (auto *E = dyn_cast_or_null(prevStmt)) - prevStmt = E->IgnoreImplicit(); - } - - if (currChildS == childE) - return std::make_pair(prevStmt, nextStmt); - ++currChildS; - if (currChildS == childE) - return std::make_pair(prevStmt, nextStmt); - - nextStmt = *currChildS; - if (auto *E = dyn_cast_or_null(nextStmt)) - nextStmt = E->IgnoreImplicit(); - - return std::make_pair(prevStmt, nextStmt); - } - - Decl *getReferencedDecl(Expr *E) { - if (!E) - return nullptr; - - E = E->IgnoreParenCasts(); - if (ObjCMessageExpr *ME = dyn_cast(E)) { - switch (ME->getMethodFamily()) { - case OMF_copy: - case OMF_autorelease: - case OMF_release: - case OMF_retain: - return getReferencedDecl(ME->getInstanceReceiver()); - default: - return nullptr; - } - } - if (DeclRefExpr *DRE = dyn_cast(E)) - return DRE->getDecl(); - if (MemberExpr *ME = dyn_cast(E)) - return ME->getMemberDecl(); - if (ObjCIvarRefExpr *IRE = dyn_cast(E)) - return IRE->getDecl(); - - return nullptr; - } - - /// Check if the retain/release is due to a GCD/XPC macro that are - /// defined as: - /// - /// #define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; }) - /// #define dispatch_release(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); [_o release]; }) - /// #define xpc_retain(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o retain]; }) - /// #define xpc_release(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o release]; }) - /// - /// and return the top container which is the StmtExpr and the macro argument - /// expression. - void checkForGCDOrXPC(ObjCMessageExpr *Msg, Expr *&RecContainer, - Expr *&Rec, SourceRange &RecRange) { - SourceLocation Loc = Msg->getExprLoc(); - if (!Loc.isMacroID()) - return; - SourceManager &SM = Pass.Ctx.getSourceManager(); - StringRef MacroName = Lexer::getImmediateMacroName(Loc, SM, - Pass.Ctx.getLangOpts()); - bool isGCDOrXPC = llvm::StringSwitch(MacroName) - .Case("dispatch_retain", true) - .Case("dispatch_release", true) - .Case("xpc_retain", true) - .Case("xpc_release", true) - .Default(false); - if (!isGCDOrXPC) - return; - - StmtExpr *StmtE = nullptr; - Stmt *S = Msg; - while (S) { - if (StmtExpr *SE = dyn_cast(S)) { - StmtE = SE; - break; - } - S = StmtMap->getParent(S); - } - - if (!StmtE) - return; - - Stmt::child_range StmtExprChild = StmtE->children(); - if (StmtExprChild.begin() == StmtExprChild.end()) - return; - auto *CompS = dyn_cast_or_null(*StmtExprChild.begin()); - if (!CompS) - return; - - Stmt::child_range CompStmtChild = CompS->children(); - if (CompStmtChild.begin() == CompStmtChild.end()) - return; - auto *DeclS = dyn_cast_or_null(*CompStmtChild.begin()); - if (!DeclS) - return; - if (!DeclS->isSingleDecl()) - return; - VarDecl *VD = dyn_cast_or_null(DeclS->getSingleDecl()); - if (!VD) - return; - Expr *Init = VD->getInit(); - if (!Init) - return; - - RecContainer = StmtE; - Rec = Init->IgnoreParenImpCasts(); - if (FullExpr *FE = dyn_cast(Rec)) - Rec = FE->getSubExpr()->IgnoreParenImpCasts(); - RecRange = Rec->getSourceRange(); - if (SM.isMacroArgExpansion(RecRange.getBegin())) - RecRange.setBegin(SM.getImmediateSpellingLoc(RecRange.getBegin())); - if (SM.isMacroArgExpansion(RecRange.getEnd())) - RecRange.setEnd(SM.getImmediateSpellingLoc(RecRange.getEnd())); - } - - void clearDiagnostics(SourceLocation loc) const { - Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message, - diag::err_unavailable, - diag::err_unavailable_message, - loc); - } - - bool isDelegateMessage(Expr *E) const { - if (!E) return false; - - E = E->IgnoreParenCasts(); - - // Also look through property-getter sugar. - if (PseudoObjectExpr *pseudoOp = dyn_cast(E)) - E = pseudoOp->getResultExpr()->IgnoreImplicit(); - - if (ObjCMessageExpr *ME = dyn_cast(E)) - return (ME->isInstanceMessage() && ME->getSelector() == DelegateSel); - - return false; - } - - bool isInAtFinally(Expr *E) const { - assert(E); - Stmt *S = E; - while (S) { - if (isa(S)) - return true; - S = StmtMap->getParent(S); - } - - return false; - } - - bool isRemovable(Expr *E) const { - return Removables.count(E); - } - - bool tryRemoving(Expr *E) const { - if (isRemovable(E)) { - Pass.TA.removeStmt(E); - return true; - } - - Stmt *parent = StmtMap->getParent(E); - - if (ImplicitCastExpr *castE = dyn_cast_or_null(parent)) - return tryRemoving(castE); - - if (ParenExpr *parenE = dyn_cast_or_null(parent)) - return tryRemoving(parenE); - - if (BinaryOperator * - bopE = dyn_cast_or_null(parent)) { - if (bopE->getOpcode() == BO_Comma && bopE->getLHS() == E && - isRemovable(bopE)) { - Pass.TA.replace(bopE->getSourceRange(), bopE->getRHS()->getSourceRange()); - return true; - } - } - - return false; - } - -}; - -} // anonymous namespace - -void trans::removeRetainReleaseDeallocFinalize(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp b/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp deleted file mode 100644 index 7390ea17c8a4b..0000000000000 --- a/clang/lib/ARCMigrate/TransUnbridgedCasts.cpp +++ /dev/null @@ -1,466 +0,0 @@ -//===--- TransUnbridgedCasts.cpp - Transformations to ARC mode ------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// rewriteUnbridgedCasts: -// -// A cast of non-objc pointer to an objc one is checked. If the non-objc pointer -// is from a file-level variable, __bridge cast is used to convert it. -// For the result of a function call that we know is +1/+0, -// __bridge/CFBridgingRelease is used. -// -// NSString *str = (NSString *)kUTTypePlainText; -// str = b ? kUTTypeRTF : kUTTypePlainText; -// NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, -// _uuid); -// ----> -// NSString *str = (__bridge NSString *)kUTTypePlainText; -// str = (__bridge NSString *)(b ? kUTTypeRTF : kUTTypePlainText); -// NSString *_uuidString = (NSString *) -// CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid)); -// -// For a C pointer to ObjC, for casting 'self', __bridge is used. -// -// CFStringRef str = (CFStringRef)self; -// ----> -// CFStringRef str = (__bridge CFStringRef)self; -// -// Uses of Block_copy/Block_release macros are rewritten: -// -// c = Block_copy(b); -// Block_release(c); -// ----> -// c = [b copy]; -// -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Attr.h" -#include "clang/AST/ParentMap.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "llvm/ADT/SmallString.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class UnbridgedCastRewriter : public RecursiveASTVisitor{ - MigrationPass &Pass; - IdentifierInfo *SelfII; - std::unique_ptr StmtMap; - Decl *ParentD; - Stmt *Body; - mutable std::unique_ptr Removables; - -public: - UnbridgedCastRewriter(MigrationPass &pass) - : Pass(pass), ParentD(nullptr), Body(nullptr) { - SelfII = &Pass.Ctx.Idents.get("self"); - } - - void transformBody(Stmt *body, Decl *ParentD) { - this->ParentD = ParentD; - Body = body; - StmtMap.reset(new ParentMap(body)); - TraverseStmt(body); - } - - bool TraverseBlockDecl(BlockDecl *D) { - // ParentMap does not enter into a BlockDecl to record its stmts, so use a - // new UnbridgedCastRewriter to handle the block. - UnbridgedCastRewriter(Pass).transformBody(D->getBody(), D); - return true; - } - - bool VisitCastExpr(CastExpr *E) { - if (E->getCastKind() != CK_CPointerToObjCPointerCast && - E->getCastKind() != CK_BitCast && - E->getCastKind() != CK_AnyPointerToBlockPointerCast) - return true; - - QualType castType = E->getType(); - Expr *castExpr = E->getSubExpr(); - QualType castExprType = castExpr->getType(); - - if (castType->isObjCRetainableType() == castExprType->isObjCRetainableType()) - return true; - - bool exprRetainable = castExprType->isObjCIndirectLifetimeType(); - bool castRetainable = castType->isObjCIndirectLifetimeType(); - if (exprRetainable == castRetainable) return true; - - if (castExpr->isNullPointerConstant(Pass.Ctx, - Expr::NPC_ValueDependentIsNull)) - return true; - - SourceLocation loc = castExpr->getExprLoc(); - if (loc.isValid() && Pass.Ctx.getSourceManager().isInSystemHeader(loc)) - return true; - - if (castType->isObjCRetainableType()) - transformNonObjCToObjCCast(E); - else - transformObjCToNonObjCCast(E); - - return true; - } - -private: - void transformNonObjCToObjCCast(CastExpr *E) { - if (!E) return; - - // Global vars are assumed that are cast as unretained. - if (isGlobalVar(E)) - if (E->getSubExpr()->getType()->isPointerType()) { - castToObjCObject(E, /*retained=*/false); - return; - } - - // If the cast is directly over the result of a Core Foundation function - // try to figure out whether it should be cast as retained or unretained. - Expr *inner = E->IgnoreParenCasts(); - if (CallExpr *callE = dyn_cast(inner)) { - if (FunctionDecl *FD = callE->getDirectCallee()) { - if (FD->hasAttr()) { - castToObjCObject(E, /*retained=*/true); - return; - } - if (FD->hasAttr()) { - castToObjCObject(E, /*retained=*/false); - return; - } - if (FD->isGlobal() && - FD->getIdentifier() && - ento::cocoa::isRefType(E->getSubExpr()->getType(), "CF", - FD->getIdentifier()->getName())) { - StringRef fname = FD->getIdentifier()->getName(); - if (fname.ends_with("Retain") || fname.contains("Create") || - fname.contains("Copy")) { - // Do not migrate to couple of bridge transfer casts which - // cancel each other out. Leave it unchanged so error gets user - // attention instead. - if (FD->getName() == "CFRetain" && - FD->getNumParams() == 1 && - FD->getParent()->isTranslationUnit() && - FD->isExternallyVisible()) { - Expr *Arg = callE->getArg(0); - if (const ImplicitCastExpr *ICE = dyn_cast(Arg)) { - const Expr *sub = ICE->getSubExpr(); - QualType T = sub->getType(); - if (T->isObjCObjectPointerType()) - return; - } - } - castToObjCObject(E, /*retained=*/true); - return; - } - - if (fname.contains("Get")) { - castToObjCObject(E, /*retained=*/false); - return; - } - } - } - } - - // If returning an ivar or a member of an ivar from a +0 method, use - // a __bridge cast. - Expr *base = inner->IgnoreParenImpCasts(); - while (isa(base)) - base = cast(base)->getBase()->IgnoreParenImpCasts(); - if (isa(base) && - isa(StmtMap->getParentIgnoreParenCasts(E))) { - if (ObjCMethodDecl *method = dyn_cast_or_null(ParentD)) { - if (!method->hasAttr()) { - castToObjCObject(E, /*retained=*/false); - return; - } - } - } - } - - void castToObjCObject(CastExpr *E, bool retained) { - rewriteToBridgedCast(E, retained ? OBC_BridgeTransfer : OBC_Bridge); - } - - void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind) { - Transaction Trans(Pass.TA); - rewriteToBridgedCast(E, Kind, Trans); - } - - void rewriteToBridgedCast(CastExpr *E, ObjCBridgeCastKind Kind, - Transaction &Trans) { - TransformActions &TA = Pass.TA; - - // We will remove the compiler diagnostic. - if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, - E->getBeginLoc())) { - Trans.abort(); - return; - } - - StringRef bridge; - switch(Kind) { - case OBC_Bridge: - bridge = "__bridge "; break; - case OBC_BridgeTransfer: - bridge = "__bridge_transfer "; break; - case OBC_BridgeRetained: - bridge = "__bridge_retained "; break; - } - - TA.clearDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, E->getBeginLoc()); - if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) { - if (CStyleCastExpr *CCE = dyn_cast(E)) { - TA.insertAfterToken(CCE->getLParenLoc(), bridge); - } else { - SourceLocation insertLoc = E->getSubExpr()->getBeginLoc(); - SmallString<128> newCast; - newCast += '('; - newCast += bridge; - newCast += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); - newCast += ')'; - - if (isa(E->getSubExpr())) { - TA.insert(insertLoc, newCast.str()); - } else { - newCast += '('; - TA.insert(insertLoc, newCast.str()); - TA.insertAfterToken(E->getEndLoc(), ")"); - } - } - } else { - assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained); - SmallString<32> BridgeCall; - - Expr *WrapE = E->getSubExpr(); - SourceLocation InsertLoc = WrapE->getBeginLoc(); - - SourceManager &SM = Pass.Ctx.getSourceManager(); - char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1)); - if (Lexer::isAsciiIdentifierContinueChar(PrevChar, - Pass.Ctx.getLangOpts())) - BridgeCall += ' '; - - if (Kind == OBC_BridgeTransfer) - BridgeCall += "CFBridgingRelease"; - else - BridgeCall += "CFBridgingRetain"; - - if (isa(WrapE)) { - TA.insert(InsertLoc, BridgeCall); - } else { - BridgeCall += '('; - TA.insert(InsertLoc, BridgeCall); - TA.insertAfterToken(WrapE->getEndLoc(), ")"); - } - } - } - - void rewriteCastForCFRetain(CastExpr *castE, CallExpr *callE) { - Transaction Trans(Pass.TA); - Pass.TA.replace(callE->getSourceRange(), callE->getArg(0)->getSourceRange()); - rewriteToBridgedCast(castE, OBC_BridgeRetained, Trans); - } - - void getBlockMacroRanges(CastExpr *E, SourceRange &Outer, SourceRange &Inner) { - SourceManager &SM = Pass.Ctx.getSourceManager(); - SourceLocation Loc = E->getExprLoc(); - assert(Loc.isMacroID()); - CharSourceRange MacroRange = SM.getImmediateExpansionRange(Loc); - SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange(); - SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin()); - SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd()); - - Outer = MacroRange.getAsRange(); - Inner = SourceRange(InnerBegin, InnerEnd); - } - - void rewriteBlockCopyMacro(CastExpr *E) { - SourceRange OuterRange, InnerRange; - getBlockMacroRanges(E, OuterRange, InnerRange); - - Transaction Trans(Pass.TA); - Pass.TA.replace(OuterRange, InnerRange); - Pass.TA.insert(InnerRange.getBegin(), "["); - Pass.TA.insertAfterToken(InnerRange.getEnd(), " copy]"); - Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, - OuterRange); - } - - void removeBlockReleaseMacro(CastExpr *E) { - SourceRange OuterRange, InnerRange; - getBlockMacroRanges(E, OuterRange, InnerRange); - - Transaction Trans(Pass.TA); - Pass.TA.clearDiagnostic(diag::err_arc_mismatched_cast, - diag::err_arc_cast_requires_bridge, - OuterRange); - if (!hasSideEffects(E, Pass.Ctx)) { - if (tryRemoving(cast(StmtMap->getParentIgnoreParenCasts(E)))) - return; - } - Pass.TA.replace(OuterRange, InnerRange); - } - - bool tryRemoving(Expr *E) const { - if (!Removables) { - Removables.reset(new ExprSet); - collectRemovables(Body, *Removables); - } - - if (Removables->count(E)) { - Pass.TA.removeStmt(E); - return true; - } - - return false; - } - - void transformObjCToNonObjCCast(CastExpr *E) { - SourceLocation CastLoc = E->getExprLoc(); - if (CastLoc.isMacroID()) { - StringRef MacroName = Lexer::getImmediateMacroName(CastLoc, - Pass.Ctx.getSourceManager(), - Pass.Ctx.getLangOpts()); - if (MacroName == "Block_copy") { - rewriteBlockCopyMacro(E); - return; - } - if (MacroName == "Block_release") { - removeBlockReleaseMacro(E); - return; - } - } - - if (isSelf(E->getSubExpr())) - return rewriteToBridgedCast(E, OBC_Bridge); - - CallExpr *callE; - if (isPassedToCFRetain(E, callE)) - return rewriteCastForCFRetain(E, callE); - - ObjCMethodFamily family = getFamilyOfMessage(E->getSubExpr()); - if (family == OMF_retain) - return rewriteToBridgedCast(E, OBC_BridgeRetained); - - if (family == OMF_autorelease || family == OMF_release) { - std::string err = "it is not safe to cast to '"; - err += E->getType().getAsString(Pass.Ctx.getPrintingPolicy()); - err += "' the result of '"; - err += family == OMF_autorelease ? "autorelease" : "release"; - err += "' message; a __bridge cast may result in a pointer to a " - "destroyed object and a __bridge_retained may leak the object"; - Pass.TA.reportError(err, E->getBeginLoc(), - E->getSubExpr()->getSourceRange()); - Stmt *parent = E; - do { - parent = StmtMap->getParentIgnoreParenImpCasts(parent); - } while (isa_and_nonnull(parent)); - - if (ReturnStmt *retS = dyn_cast_or_null(parent)) { - std::string note = "remove the cast and change return type of function " - "to '"; - note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy()); - note += "' to have the object automatically autoreleased"; - Pass.TA.reportNote(note, retS->getBeginLoc()); - } - } - - Expr *subExpr = E->getSubExpr(); - - // Look through pseudo-object expressions. - if (PseudoObjectExpr *pseudo = dyn_cast(subExpr)) { - subExpr = pseudo->getResultExpr(); - assert(subExpr && "no result for pseudo-object of non-void type?"); - } - - if (ImplicitCastExpr *implCE = dyn_cast(subExpr)) { - if (implCE->getCastKind() == CK_ARCConsumeObject) - return rewriteToBridgedCast(E, OBC_BridgeRetained); - if (implCE->getCastKind() == CK_ARCReclaimReturnedObject) - return rewriteToBridgedCast(E, OBC_Bridge); - } - - bool isConsumed = false; - if (isPassedToCParamWithKnownOwnership(E, isConsumed)) - return rewriteToBridgedCast(E, isConsumed ? OBC_BridgeRetained - : OBC_Bridge); - } - - static ObjCMethodFamily getFamilyOfMessage(Expr *E) { - E = E->IgnoreParenCasts(); - if (ObjCMessageExpr *ME = dyn_cast(E)) - return ME->getMethodFamily(); - - return OMF_None; - } - - bool isPassedToCFRetain(Expr *E, CallExpr *&callE) const { - if ((callE = dyn_cast_or_null( - StmtMap->getParentIgnoreParenImpCasts(E)))) - if (FunctionDecl * - FD = dyn_cast_or_null(callE->getCalleeDecl())) - if (FD->getName() == "CFRetain" && FD->getNumParams() == 1 && - FD->getParent()->isTranslationUnit() && - FD->isExternallyVisible()) - return true; - - return false; - } - - bool isPassedToCParamWithKnownOwnership(Expr *E, bool &isConsumed) const { - if (CallExpr *callE = dyn_cast_or_null( - StmtMap->getParentIgnoreParenImpCasts(E))) - if (FunctionDecl * - FD = dyn_cast_or_null(callE->getCalleeDecl())) { - unsigned i = 0; - for (unsigned e = callE->getNumArgs(); i != e; ++i) { - Expr *arg = callE->getArg(i); - if (arg == E || arg->IgnoreParenImpCasts() == E) - break; - } - if (i < callE->getNumArgs() && i < FD->getNumParams()) { - ParmVarDecl *PD = FD->getParamDecl(i); - if (PD->hasAttr()) { - isConsumed = true; - return true; - } - } - } - - return false; - } - - bool isSelf(Expr *E) const { - E = E->IgnoreParenLValueCasts(); - if (DeclRefExpr *DRE = dyn_cast(E)) - if (ImplicitParamDecl *IPD = dyn_cast(DRE->getDecl())) - if (IPD->getIdentifier() == SelfII) - return true; - - return false; - } -}; - -} // end anonymous namespace - -void trans::rewriteUnbridgedCasts(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp deleted file mode 100644 index bac8dfac9b415..0000000000000 --- a/clang/lib/ARCMigrate/TransUnusedInitDelegate.cpp +++ /dev/null @@ -1,77 +0,0 @@ -//===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// Transformations: -//===----------------------------------------------------------------------===// -// -// rewriteUnusedInitDelegate: -// -// Rewrites an unused result of calling a delegate initialization, to assigning -// the result to self. -// e.g -// [self init]; -// ----> -// self = [self init]; -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/Sema/SemaDiagnostic.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class UnusedInitRewriter : public RecursiveASTVisitor { - Stmt *Body; - MigrationPass &Pass; - - ExprSet Removables; - -public: - UnusedInitRewriter(MigrationPass &pass) - : Body(nullptr), Pass(pass) { } - - void transformBody(Stmt *body, Decl *ParentD) { - Body = body; - collectRemovables(body, Removables); - TraverseStmt(body); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { - if (ME->isDelegateInitCall() && - isRemovable(ME) && - Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message, - ME->getExprLoc())) { - Transaction Trans(Pass.TA); - Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message, - ME->getExprLoc()); - SourceRange ExprRange = ME->getSourceRange(); - Pass.TA.insert(ExprRange.getBegin(), "if (!(self = "); - std::string retStr = ")) return "; - retStr += getNilString(Pass); - Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr); - } - return true; - } - -private: - bool isRemovable(Expr *E) const { - return Removables.count(E); - } -}; - -} // anonymous namespace - -void trans::rewriteUnusedInitDelegate(MigrationPass &pass) { - BodyTransform trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp deleted file mode 100644 index 81e67628fb1f4..0000000000000 --- a/clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp +++ /dev/null @@ -1,224 +0,0 @@ -//===--- TransZeroOutPropsInDealloc.cpp - Transformations to ARC mode -----===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// removeZeroOutPropsInDealloc: -// -// Removes zero'ing out "strong" @synthesized properties in a -dealloc method. -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/AST/ASTContext.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -namespace { - -class ZeroOutInDeallocRemover : - public RecursiveASTVisitor { - typedef RecursiveASTVisitor base; - - MigrationPass &Pass; - - llvm::DenseMap SynthesizedProperties; - ImplicitParamDecl *SelfD; - ExprSet Removables; - Selector FinalizeSel; - -public: - ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(nullptr) { - FinalizeSel = - Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize")); - } - - bool VisitObjCMessageExpr(ObjCMessageExpr *ME) { - ASTContext &Ctx = Pass.Ctx; - TransformActions &TA = Pass.TA; - - if (ME->getReceiverKind() != ObjCMessageExpr::Instance) - return true; - Expr *receiver = ME->getInstanceReceiver(); - if (!receiver) - return true; - - DeclRefExpr *refE = dyn_cast(receiver->IgnoreParenCasts()); - if (!refE || refE->getDecl() != SelfD) - return true; - - bool BackedBySynthesizeSetter = false; - for (llvm::DenseMap::iterator - P = SynthesizedProperties.begin(), - E = SynthesizedProperties.end(); P != E; ++P) { - ObjCPropertyDecl *PropDecl = P->first; - if (PropDecl->getSetterName() == ME->getSelector()) { - BackedBySynthesizeSetter = true; - break; - } - } - if (!BackedBySynthesizeSetter) - return true; - - // Remove the setter message if RHS is null - Transaction Trans(TA); - Expr *RHS = ME->getArg(0); - bool RHSIsNull = - RHS->isNullPointerConstant(Ctx, - Expr::NPC_ValueDependentIsNull); - if (RHSIsNull && isRemovable(ME)) - TA.removeStmt(ME); - - return true; - } - - bool VisitPseudoObjectExpr(PseudoObjectExpr *POE) { - if (isZeroingPropIvar(POE) && isRemovable(POE)) { - Transaction Trans(Pass.TA); - Pass.TA.removeStmt(POE); - } - - return true; - } - - bool VisitBinaryOperator(BinaryOperator *BOE) { - if (isZeroingPropIvar(BOE) && isRemovable(BOE)) { - Transaction Trans(Pass.TA); - Pass.TA.removeStmt(BOE); - } - - return true; - } - - bool TraverseObjCMethodDecl(ObjCMethodDecl *D) { - if (D->getMethodFamily() != OMF_dealloc && - !(D->isInstanceMethod() && D->getSelector() == FinalizeSel)) - return true; - if (!D->hasBody()) - return true; - - ObjCImplDecl *IMD = dyn_cast(D->getDeclContext()); - if (!IMD) - return true; - - SelfD = D->getSelfDecl(); - collectRemovables(D->getBody(), Removables); - - // For a 'dealloc' method use, find all property implementations in - // this class implementation. - for (auto *PID : IMD->property_impls()) { - if (PID->getPropertyImplementation() == - ObjCPropertyImplDecl::Synthesize) { - ObjCPropertyDecl *PD = PID->getPropertyDecl(); - ObjCMethodDecl *setterM = PD->getSetterMethodDecl(); - if (!(setterM && setterM->isDefined())) { - ObjCPropertyAttribute::Kind AttrKind = PD->getPropertyAttributes(); - if (AttrKind & (ObjCPropertyAttribute::kind_retain | - ObjCPropertyAttribute::kind_copy | - ObjCPropertyAttribute::kind_strong)) - SynthesizedProperties[PD] = PID; - } - } - } - - // Now, remove all zeroing of ivars etc. - base::TraverseObjCMethodDecl(D); - - // clear out for next method. - SynthesizedProperties.clear(); - SelfD = nullptr; - Removables.clear(); - return true; - } - - bool TraverseFunctionDecl(FunctionDecl *D) { return true; } - bool TraverseBlockDecl(BlockDecl *block) { return true; } - bool TraverseBlockExpr(BlockExpr *block) { return true; } - -private: - bool isRemovable(Expr *E) const { - return Removables.count(E); - } - - bool isZeroingPropIvar(Expr *E) { - E = E->IgnoreParens(); - if (BinaryOperator *BO = dyn_cast(E)) - return isZeroingPropIvar(BO); - if (PseudoObjectExpr *PO = dyn_cast(E)) - return isZeroingPropIvar(PO); - return false; - } - - bool isZeroingPropIvar(BinaryOperator *BOE) { - if (BOE->getOpcode() == BO_Comma) - return isZeroingPropIvar(BOE->getLHS()) && - isZeroingPropIvar(BOE->getRHS()); - - if (BOE->getOpcode() != BO_Assign) - return false; - - Expr *LHS = BOE->getLHS(); - if (ObjCIvarRefExpr *IV = dyn_cast(LHS)) { - ObjCIvarDecl *IVDecl = IV->getDecl(); - if (!IVDecl->getType()->isObjCObjectPointerType()) - return false; - bool IvarBacksPropertySynthesis = false; - for (llvm::DenseMap::iterator - P = SynthesizedProperties.begin(), - E = SynthesizedProperties.end(); P != E; ++P) { - ObjCPropertyImplDecl *PropImpDecl = P->second; - if (PropImpDecl && PropImpDecl->getPropertyIvarDecl() == IVDecl) { - IvarBacksPropertySynthesis = true; - break; - } - } - if (!IvarBacksPropertySynthesis) - return false; - } - else - return false; - - return isZero(BOE->getRHS()); - } - - bool isZeroingPropIvar(PseudoObjectExpr *PO) { - BinaryOperator *BO = dyn_cast(PO->getSyntacticForm()); - if (!BO) return false; - if (BO->getOpcode() != BO_Assign) return false; - - ObjCPropertyRefExpr *PropRefExp = - dyn_cast(BO->getLHS()->IgnoreParens()); - if (!PropRefExp) return false; - - // TODO: Using implicit property decl. - if (PropRefExp->isImplicitProperty()) - return false; - - if (ObjCPropertyDecl *PDecl = PropRefExp->getExplicitProperty()) { - if (!SynthesizedProperties.count(PDecl)) - return false; - } - - return isZero(cast(BO->getRHS())->getSourceExpr()); - } - - bool isZero(Expr *E) { - if (E->isNullPointerConstant(Pass.Ctx, Expr::NPC_ValueDependentIsNull)) - return true; - - return isZeroingPropIvar(E); - } -}; - -} // anonymous namespace - -void trans::removeZeroOutPropsInDeallocFinalize(MigrationPass &pass) { - ZeroOutInDeallocRemover trans(pass); - trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl()); -} diff --git a/clang/lib/ARCMigrate/TransformActions.cpp b/clang/lib/ARCMigrate/TransformActions.cpp deleted file mode 100644 index 6bc6fed1a9032..0000000000000 --- a/clang/lib/ARCMigrate/TransformActions.cpp +++ /dev/null @@ -1,700 +0,0 @@ -//===-- TransformActions.cpp - Migration to ARC mode ----------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Internals.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/Expr.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/DenseSet.h" -#include -using namespace clang; -using namespace arcmt; - -namespace { - -/// Collects transformations and merges them before applying them with -/// with applyRewrites(). E.g. if the same source range -/// is requested to be removed twice, only one rewriter remove will be invoked. -/// Rewrites happen in "transactions"; if one rewrite in the transaction cannot -/// be done (e.g. it resides in a macro) all rewrites in the transaction are -/// aborted. -/// FIXME: "Transactional" rewrites support should be baked in the Rewriter. -class TransformActionsImpl { - CapturedDiagList &CapturedDiags; - ASTContext &Ctx; - Preprocessor &PP; - - bool IsInTransaction; - - enum ActionKind { - Act_Insert, Act_InsertAfterToken, - Act_Remove, Act_RemoveStmt, - Act_Replace, Act_ReplaceText, - Act_IncreaseIndentation, - Act_ClearDiagnostic - }; - - struct ActionData { - ActionKind Kind; - SourceLocation Loc; - SourceRange R1, R2; - StringRef Text1, Text2; - Stmt *S; - SmallVector DiagIDs; - }; - - std::vector CachedActions; - - enum RangeComparison { - Range_Before, - Range_After, - Range_Contains, - Range_Contained, - Range_ExtendsBegin, - Range_ExtendsEnd - }; - - /// A range to remove. It is a character range. - struct CharRange { - FullSourceLoc Begin, End; - - CharRange(CharSourceRange range, SourceManager &srcMgr, Preprocessor &PP) { - SourceLocation beginLoc = range.getBegin(), endLoc = range.getEnd(); - assert(beginLoc.isValid() && endLoc.isValid()); - if (range.isTokenRange()) { - Begin = FullSourceLoc(srcMgr.getExpansionLoc(beginLoc), srcMgr); - End = FullSourceLoc(getLocForEndOfToken(endLoc, srcMgr, PP), srcMgr); - } else { - Begin = FullSourceLoc(srcMgr.getExpansionLoc(beginLoc), srcMgr); - End = FullSourceLoc(srcMgr.getExpansionLoc(endLoc), srcMgr); - } - assert(Begin.isValid() && End.isValid()); - } - - RangeComparison compareWith(const CharRange &RHS) const { - if (End.isBeforeInTranslationUnitThan(RHS.Begin)) - return Range_Before; - if (RHS.End.isBeforeInTranslationUnitThan(Begin)) - return Range_After; - if (!Begin.isBeforeInTranslationUnitThan(RHS.Begin) && - !RHS.End.isBeforeInTranslationUnitThan(End)) - return Range_Contained; - if (Begin.isBeforeInTranslationUnitThan(RHS.Begin) && - RHS.End.isBeforeInTranslationUnitThan(End)) - return Range_Contains; - if (Begin.isBeforeInTranslationUnitThan(RHS.Begin)) - return Range_ExtendsBegin; - else - return Range_ExtendsEnd; - } - - static RangeComparison compare(SourceRange LHS, SourceRange RHS, - SourceManager &SrcMgr, Preprocessor &PP) { - return CharRange(CharSourceRange::getTokenRange(LHS), SrcMgr, PP) - .compareWith(CharRange(CharSourceRange::getTokenRange(RHS), - SrcMgr, PP)); - } - }; - - typedef SmallVector TextsVec; - typedef std::map - InsertsMap; - InsertsMap Inserts; - /// A list of ranges to remove. They are always sorted and they never - /// intersect with each other. - std::list Removals; - - llvm::DenseSet StmtRemovals; - - std::vector > IndentationRanges; - - /// Keeps text passed to transformation methods. - llvm::StringMap UniqueText; - -public: - TransformActionsImpl(CapturedDiagList &capturedDiags, - ASTContext &ctx, Preprocessor &PP) - : CapturedDiags(capturedDiags), Ctx(ctx), PP(PP), IsInTransaction(false) { } - - ASTContext &getASTContext() { return Ctx; } - - void startTransaction(); - bool commitTransaction(); - void abortTransaction(); - - bool isInTransaction() const { return IsInTransaction; } - - void insert(SourceLocation loc, StringRef text); - void insertAfterToken(SourceLocation loc, StringRef text); - void remove(SourceRange range); - void removeStmt(Stmt *S); - void replace(SourceRange range, StringRef text); - void replace(SourceRange range, SourceRange replacementRange); - void replaceStmt(Stmt *S, StringRef text); - void replaceText(SourceLocation loc, StringRef text, - StringRef replacementText); - void increaseIndentation(SourceRange range, - SourceLocation parentIndent); - - bool clearDiagnostic(ArrayRef IDs, SourceRange range); - - void applyRewrites(TransformActions::RewriteReceiver &receiver); - -private: - bool canInsert(SourceLocation loc); - bool canInsertAfterToken(SourceLocation loc); - bool canRemoveRange(SourceRange range); - bool canReplaceRange(SourceRange range, SourceRange replacementRange); - bool canReplaceText(SourceLocation loc, StringRef text); - - void commitInsert(SourceLocation loc, StringRef text); - void commitInsertAfterToken(SourceLocation loc, StringRef text); - void commitRemove(SourceRange range); - void commitRemoveStmt(Stmt *S); - void commitReplace(SourceRange range, SourceRange replacementRange); - void commitReplaceText(SourceLocation loc, StringRef text, - StringRef replacementText); - void commitIncreaseIndentation(SourceRange range,SourceLocation parentIndent); - void commitClearDiagnostic(ArrayRef IDs, SourceRange range); - - void addRemoval(CharSourceRange range); - void addInsertion(SourceLocation loc, StringRef text); - - /// Stores text passed to the transformation methods to keep the string - /// "alive". Since the vast majority of text will be the same, we also unique - /// the strings using a StringMap. - StringRef getUniqueText(StringRef text); - - /// Computes the source location just past the end of the token at - /// the given source location. If the location points at a macro, the whole - /// macro expansion is skipped. - static SourceLocation getLocForEndOfToken(SourceLocation loc, - SourceManager &SM,Preprocessor &PP); -}; - -} // anonymous namespace - -void TransformActionsImpl::startTransaction() { - assert(!IsInTransaction && - "Cannot start a transaction in the middle of another one"); - IsInTransaction = true; -} - -bool TransformActionsImpl::commitTransaction() { - assert(IsInTransaction && "No transaction started"); - - if (CachedActions.empty()) { - IsInTransaction = false; - return false; - } - - // Verify that all actions are possible otherwise abort the whole transaction. - bool AllActionsPossible = true; - for (unsigned i = 0, e = CachedActions.size(); i != e; ++i) { - ActionData &act = CachedActions[i]; - switch (act.Kind) { - case Act_Insert: - if (!canInsert(act.Loc)) - AllActionsPossible = false; - break; - case Act_InsertAfterToken: - if (!canInsertAfterToken(act.Loc)) - AllActionsPossible = false; - break; - case Act_Remove: - if (!canRemoveRange(act.R1)) - AllActionsPossible = false; - break; - case Act_RemoveStmt: - assert(act.S); - if (!canRemoveRange(act.S->getSourceRange())) - AllActionsPossible = false; - break; - case Act_Replace: - if (!canReplaceRange(act.R1, act.R2)) - AllActionsPossible = false; - break; - case Act_ReplaceText: - if (!canReplaceText(act.Loc, act.Text1)) - AllActionsPossible = false; - break; - case Act_IncreaseIndentation: - // This is not important, we don't care if it will fail. - break; - case Act_ClearDiagnostic: - // We are just checking source rewrites. - break; - } - if (!AllActionsPossible) - break; - } - - if (!AllActionsPossible) { - abortTransaction(); - return true; - } - - for (unsigned i = 0, e = CachedActions.size(); i != e; ++i) { - ActionData &act = CachedActions[i]; - switch (act.Kind) { - case Act_Insert: - commitInsert(act.Loc, act.Text1); - break; - case Act_InsertAfterToken: - commitInsertAfterToken(act.Loc, act.Text1); - break; - case Act_Remove: - commitRemove(act.R1); - break; - case Act_RemoveStmt: - commitRemoveStmt(act.S); - break; - case Act_Replace: - commitReplace(act.R1, act.R2); - break; - case Act_ReplaceText: - commitReplaceText(act.Loc, act.Text1, act.Text2); - break; - case Act_IncreaseIndentation: - commitIncreaseIndentation(act.R1, act.Loc); - break; - case Act_ClearDiagnostic: - commitClearDiagnostic(act.DiagIDs, act.R1); - break; - } - } - - CachedActions.clear(); - IsInTransaction = false; - return false; -} - -void TransformActionsImpl::abortTransaction() { - assert(IsInTransaction && "No transaction started"); - CachedActions.clear(); - IsInTransaction = false; -} - -void TransformActionsImpl::insert(SourceLocation loc, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - ActionData data; - data.Kind = Act_Insert; - data.Loc = loc; - data.Text1 = text; - CachedActions.push_back(data); -} - -void TransformActionsImpl::insertAfterToken(SourceLocation loc, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - ActionData data; - data.Kind = Act_InsertAfterToken; - data.Loc = loc; - data.Text1 = text; - CachedActions.push_back(data); -} - -void TransformActionsImpl::remove(SourceRange range) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_Remove; - data.R1 = range; - CachedActions.push_back(data); -} - -void TransformActionsImpl::removeStmt(Stmt *S) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_RemoveStmt; - if (auto *E = dyn_cast(S)) - S = E->IgnoreImplicit(); // important for uniquing - data.S = S; - CachedActions.push_back(data); -} - -void TransformActionsImpl::replace(SourceRange range, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - remove(range); - insert(range.getBegin(), text); -} - -void TransformActionsImpl::replace(SourceRange range, - SourceRange replacementRange) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_Replace; - data.R1 = range; - data.R2 = replacementRange; - CachedActions.push_back(data); -} - -void TransformActionsImpl::replaceText(SourceLocation loc, StringRef text, - StringRef replacementText) { - text = getUniqueText(text); - replacementText = getUniqueText(replacementText); - ActionData data; - data.Kind = Act_ReplaceText; - data.Loc = loc; - data.Text1 = text; - data.Text2 = replacementText; - CachedActions.push_back(data); -} - -void TransformActionsImpl::replaceStmt(Stmt *S, StringRef text) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - text = getUniqueText(text); - insert(S->getBeginLoc(), text); - removeStmt(S); -} - -void TransformActionsImpl::increaseIndentation(SourceRange range, - SourceLocation parentIndent) { - if (range.isInvalid()) return; - assert(IsInTransaction && "Actions only allowed during a transaction"); - ActionData data; - data.Kind = Act_IncreaseIndentation; - data.R1 = range; - data.Loc = parentIndent; - CachedActions.push_back(data); -} - -bool TransformActionsImpl::clearDiagnostic(ArrayRef IDs, - SourceRange range) { - assert(IsInTransaction && "Actions only allowed during a transaction"); - if (!CapturedDiags.hasDiagnostic(IDs, range)) - return false; - - ActionData data; - data.Kind = Act_ClearDiagnostic; - data.R1 = range; - data.DiagIDs.append(IDs.begin(), IDs.end()); - CachedActions.push_back(data); - return true; -} - -bool TransformActionsImpl::canInsert(SourceLocation loc) { - if (loc.isInvalid()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - if (SM.isInSystemHeader(SM.getExpansionLoc(loc))) - return false; - - if (loc.isFileID()) - return true; - return PP.isAtStartOfMacroExpansion(loc); -} - -bool TransformActionsImpl::canInsertAfterToken(SourceLocation loc) { - if (loc.isInvalid()) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - if (SM.isInSystemHeader(SM.getExpansionLoc(loc))) - return false; - - if (loc.isFileID()) - return true; - return PP.isAtEndOfMacroExpansion(loc); -} - -bool TransformActionsImpl::canRemoveRange(SourceRange range) { - return canInsert(range.getBegin()) && canInsertAfterToken(range.getEnd()); -} - -bool TransformActionsImpl::canReplaceRange(SourceRange range, - SourceRange replacementRange) { - return canRemoveRange(range) && canRemoveRange(replacementRange); -} - -bool TransformActionsImpl::canReplaceText(SourceLocation loc, StringRef text) { - if (!canInsert(loc)) - return false; - - SourceManager &SM = Ctx.getSourceManager(); - loc = SM.getExpansionLoc(loc); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(loc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return false; - - return file.substr(locInfo.second).starts_with(text); -} - -void TransformActionsImpl::commitInsert(SourceLocation loc, StringRef text) { - addInsertion(loc, text); -} - -void TransformActionsImpl::commitInsertAfterToken(SourceLocation loc, - StringRef text) { - addInsertion(getLocForEndOfToken(loc, Ctx.getSourceManager(), PP), text); -} - -void TransformActionsImpl::commitRemove(SourceRange range) { - addRemoval(CharSourceRange::getTokenRange(range)); -} - -void TransformActionsImpl::commitRemoveStmt(Stmt *S) { - assert(S); - if (StmtRemovals.count(S)) - return; // already removed. - - if (Expr *E = dyn_cast(S)) { - commitRemove(E->getSourceRange()); - commitInsert(E->getSourceRange().getBegin(), getARCMTMacroName()); - } else - commitRemove(S->getSourceRange()); - - StmtRemovals.insert(S); -} - -void TransformActionsImpl::commitReplace(SourceRange range, - SourceRange replacementRange) { - RangeComparison comp = CharRange::compare(replacementRange, range, - Ctx.getSourceManager(), PP); - assert(comp == Range_Contained); - if (comp != Range_Contained) - return; // Although we asserted, be extra safe for release build. - if (range.getBegin() != replacementRange.getBegin()) - addRemoval(CharSourceRange::getCharRange(range.getBegin(), - replacementRange.getBegin())); - if (replacementRange.getEnd() != range.getEnd()) - addRemoval(CharSourceRange::getTokenRange( - getLocForEndOfToken(replacementRange.getEnd(), - Ctx.getSourceManager(), PP), - range.getEnd())); -} -void TransformActionsImpl::commitReplaceText(SourceLocation loc, - StringRef text, - StringRef replacementText) { - SourceManager &SM = Ctx.getSourceManager(); - loc = SM.getExpansionLoc(loc); - // canReplaceText already checked if loc points at text. - SourceLocation afterText = loc.getLocWithOffset(text.size()); - - addRemoval(CharSourceRange::getCharRange(loc, afterText)); - commitInsert(loc, replacementText); -} - -void TransformActionsImpl::commitIncreaseIndentation(SourceRange range, - SourceLocation parentIndent) { - SourceManager &SM = Ctx.getSourceManager(); - IndentationRanges.push_back( - std::make_pair(CharRange(CharSourceRange::getTokenRange(range), - SM, PP), - SM.getExpansionLoc(parentIndent))); -} - -void TransformActionsImpl::commitClearDiagnostic(ArrayRef IDs, - SourceRange range) { - CapturedDiags.clearDiagnostic(IDs, range); -} - -void TransformActionsImpl::addInsertion(SourceLocation loc, StringRef text) { - SourceManager &SM = Ctx.getSourceManager(); - loc = SM.getExpansionLoc(loc); - for (const CharRange &I : llvm::reverse(Removals)) { - if (!SM.isBeforeInTranslationUnit(loc, I.End)) - break; - if (I.Begin.isBeforeInTranslationUnitThan(loc)) - return; - } - - Inserts[FullSourceLoc(loc, SM)].push_back(text); -} - -void TransformActionsImpl::addRemoval(CharSourceRange range) { - CharRange newRange(range, Ctx.getSourceManager(), PP); - if (newRange.Begin == newRange.End) - return; - - Inserts.erase(Inserts.upper_bound(newRange.Begin), - Inserts.lower_bound(newRange.End)); - - std::list::iterator I = Removals.end(); - while (I != Removals.begin()) { - std::list::iterator RI = I; - --RI; - RangeComparison comp = newRange.compareWith(*RI); - switch (comp) { - case Range_Before: - --I; - break; - case Range_After: - Removals.insert(I, newRange); - return; - case Range_Contained: - return; - case Range_Contains: - RI->End = newRange.End; - [[fallthrough]]; - case Range_ExtendsBegin: - newRange.End = RI->End; - Removals.erase(RI); - break; - case Range_ExtendsEnd: - RI->End = newRange.End; - return; - } - } - - Removals.insert(Removals.begin(), newRange); -} - -void TransformActionsImpl::applyRewrites( - TransformActions::RewriteReceiver &receiver) { - for (InsertsMap::iterator I = Inserts.begin(), E = Inserts.end(); I!=E; ++I) { - SourceLocation loc = I->first; - for (TextsVec::iterator - TI = I->second.begin(), TE = I->second.end(); TI != TE; ++TI) { - receiver.insert(loc, *TI); - } - } - - for (std::vector >::iterator - I = IndentationRanges.begin(), E = IndentationRanges.end(); I!=E; ++I) { - CharSourceRange range = CharSourceRange::getCharRange(I->first.Begin, - I->first.End); - receiver.increaseIndentation(range, I->second); - } - - for (std::list::iterator - I = Removals.begin(), E = Removals.end(); I != E; ++I) { - CharSourceRange range = CharSourceRange::getCharRange(I->Begin, I->End); - receiver.remove(range); - } -} - -/// Stores text passed to the transformation methods to keep the string -/// "alive". Since the vast majority of text will be the same, we also unique -/// the strings using a StringMap. -StringRef TransformActionsImpl::getUniqueText(StringRef text) { - return UniqueText.insert(std::make_pair(text, false)).first->first(); -} - -/// Computes the source location just past the end of the token at -/// the given source location. If the location points at a macro, the whole -/// macro expansion is skipped. -SourceLocation TransformActionsImpl::getLocForEndOfToken(SourceLocation loc, - SourceManager &SM, - Preprocessor &PP) { - if (loc.isMacroID()) { - CharSourceRange Exp = SM.getExpansionRange(loc); - if (Exp.isCharRange()) - return Exp.getEnd(); - loc = Exp.getEnd(); - } - return PP.getLocForEndOfToken(loc); -} - -TransformActions::RewriteReceiver::~RewriteReceiver() { } - -TransformActions::TransformActions(DiagnosticsEngine &diag, - CapturedDiagList &capturedDiags, - ASTContext &ctx, Preprocessor &PP) - : Diags(diag), CapturedDiags(capturedDiags) { - Impl = new TransformActionsImpl(capturedDiags, ctx, PP); -} - -TransformActions::~TransformActions() { - delete static_cast(Impl); -} - -void TransformActions::startTransaction() { - static_cast(Impl)->startTransaction(); -} - -bool TransformActions::commitTransaction() { - return static_cast(Impl)->commitTransaction(); -} - -void TransformActions::abortTransaction() { - static_cast(Impl)->abortTransaction(); -} - - -void TransformActions::insert(SourceLocation loc, StringRef text) { - static_cast(Impl)->insert(loc, text); -} - -void TransformActions::insertAfterToken(SourceLocation loc, - StringRef text) { - static_cast(Impl)->insertAfterToken(loc, text); -} - -void TransformActions::remove(SourceRange range) { - static_cast(Impl)->remove(range); -} - -void TransformActions::removeStmt(Stmt *S) { - static_cast(Impl)->removeStmt(S); -} - -void TransformActions::replace(SourceRange range, StringRef text) { - static_cast(Impl)->replace(range, text); -} - -void TransformActions::replace(SourceRange range, - SourceRange replacementRange) { - static_cast(Impl)->replace(range, replacementRange); -} - -void TransformActions::replaceStmt(Stmt *S, StringRef text) { - static_cast(Impl)->replaceStmt(S, text); -} - -void TransformActions::replaceText(SourceLocation loc, StringRef text, - StringRef replacementText) { - static_cast(Impl)->replaceText(loc, text, - replacementText); -} - -void TransformActions::increaseIndentation(SourceRange range, - SourceLocation parentIndent) { - static_cast(Impl)->increaseIndentation(range, - parentIndent); -} - -bool TransformActions::clearDiagnostic(ArrayRef IDs, - SourceRange range) { - return static_cast(Impl)->clearDiagnostic(IDs, range); -} - -void TransformActions::applyRewrites(RewriteReceiver &receiver) { - static_cast(Impl)->applyRewrites(receiver); -} - -DiagnosticBuilder TransformActions::report(SourceLocation loc, unsigned diagId, - SourceRange range) { - assert(!static_cast(Impl)->isInTransaction() && - "Errors should be emitted out of a transaction"); - return Diags.Report(loc, diagId) << range; -} - -void TransformActions::reportError(StringRef message, SourceLocation loc, - SourceRange range) { - report(loc, diag::err_mt_message, range) << message; -} - -void TransformActions::reportWarning(StringRef message, SourceLocation loc, - SourceRange range) { - report(loc, diag::warn_mt_message, range) << message; -} - -void TransformActions::reportNote(StringRef message, SourceLocation loc, - SourceRange range) { - report(loc, diag::note_mt_message, range) << message; -} diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp deleted file mode 100644 index fda0e1c932fc0..0000000000000 --- a/clang/lib/ARCMigrate/Transforms.cpp +++ /dev/null @@ -1,594 +0,0 @@ -//===--- Transforms.cpp - Transformations to ARC mode ---------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "Transforms.h" -#include "Internals.h" -#include "clang/ARCMigrate/ARCMT.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Analysis/DomainSpecific/CocoaConventions.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/TargetInfo.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Sema/Sema.h" -#include "clang/Sema/SemaObjC.h" - -using namespace clang; -using namespace arcmt; -using namespace trans; - -ASTTraverser::~ASTTraverser() { } - -bool MigrationPass::CFBridgingFunctionsDefined() { - if (!EnableCFBridgeFns) - EnableCFBridgeFns = SemaRef.ObjC().isKnownName("CFBridgingRetain") && - SemaRef.ObjC().isKnownName("CFBridgingRelease"); - return *EnableCFBridgeFns; -} - -//===----------------------------------------------------------------------===// -// Helpers. -//===----------------------------------------------------------------------===// - -bool trans::canApplyWeak(ASTContext &Ctx, QualType type, - bool AllowOnUnknownClass) { - if (!Ctx.getLangOpts().ObjCWeakRuntime) - return false; - - QualType T = type; - if (T.isNull()) - return false; - - // iOS is always safe to use 'weak'. - if (Ctx.getTargetInfo().getTriple().isiOS() || - Ctx.getTargetInfo().getTriple().isWatchOS()) - AllowOnUnknownClass = true; - - while (const PointerType *ptr = T->getAs()) - T = ptr->getPointeeType(); - if (const ObjCObjectPointerType *ObjT = T->getAs()) { - ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); - if (!AllowOnUnknownClass && (!Class || Class->getName() == "NSObject")) - return false; // id/NSObject is not safe for weak. - if (!AllowOnUnknownClass && !Class->hasDefinition()) - return false; // forward classes are not verifiable, therefore not safe. - if (Class && Class->isArcWeakrefUnavailable()) - return false; - } - - return true; -} - -bool trans::isPlusOneAssign(const BinaryOperator *E) { - if (E->getOpcode() != BO_Assign) - return false; - - return isPlusOne(E->getRHS()); -} - -bool trans::isPlusOne(const Expr *E) { - if (!E) - return false; - if (const FullExpr *FE = dyn_cast(E)) - E = FE->getSubExpr(); - - if (const ObjCMessageExpr * - ME = dyn_cast(E->IgnoreParenCasts())) - if (ME->getMethodFamily() == OMF_retain) - return true; - - if (const CallExpr * - callE = dyn_cast(E->IgnoreParenCasts())) { - if (const FunctionDecl *FD = callE->getDirectCallee()) { - if (FD->hasAttr()) - return true; - - if (FD->isGlobal() && - FD->getIdentifier() && - FD->getParent()->isTranslationUnit() && - FD->isExternallyVisible() && - ento::cocoa::isRefType(callE->getType(), "CF", - FD->getIdentifier()->getName())) { - StringRef fname = FD->getIdentifier()->getName(); - if (fname.ends_with("Retain") || fname.contains("Create") || - fname.contains("Copy")) - return true; - } - } - } - - const ImplicitCastExpr *implCE = dyn_cast(E); - while (implCE && implCE->getCastKind() == CK_BitCast) - implCE = dyn_cast(implCE->getSubExpr()); - - return implCE && implCE->getCastKind() == CK_ARCConsumeObject; -} - -/// 'Loc' is the end of a statement range. This returns the location -/// immediately after the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation trans::findLocationAfterSemi(SourceLocation loc, - ASTContext &Ctx, bool IsDecl) { - SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx, IsDecl); - if (SemiLoc.isInvalid()) - return SourceLocation(); - return SemiLoc.getLocWithOffset(1); -} - -/// \arg Loc is the end of a statement range. This returns the location -/// of the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation trans::findSemiAfterLocation(SourceLocation loc, - ASTContext &Ctx, - bool IsDecl) { - SourceManager &SM = Ctx.getSourceManager(); - if (loc.isMacroID()) { - if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc)) - return SourceLocation(); - } - loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOpts()); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(loc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return SourceLocation(); - - const char *tokenBegin = file.data() + locInfo.second; - - // Lex from the start of the given location. - Lexer lexer(SM.getLocForStartOfFile(locInfo.first), - Ctx.getLangOpts(), - file.begin(), tokenBegin, file.end()); - Token tok; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::semi)) { - if (!IsDecl) - return SourceLocation(); - // Declaration may be followed with other tokens; such as an __attribute, - // before ending with a semicolon. - return findSemiAfterLocation(tok.getLocation(), Ctx, /*IsDecl*/true); - } - - return tok.getLocation(); -} - -bool trans::hasSideEffects(Expr *E, ASTContext &Ctx) { - if (!E || !E->HasSideEffects(Ctx)) - return false; - - E = E->IgnoreParenCasts(); - ObjCMessageExpr *ME = dyn_cast(E); - if (!ME) - return true; - switch (ME->getMethodFamily()) { - case OMF_autorelease: - case OMF_dealloc: - case OMF_release: - case OMF_retain: - switch (ME->getReceiverKind()) { - case ObjCMessageExpr::SuperInstance: - return false; - case ObjCMessageExpr::Instance: - return hasSideEffects(ME->getInstanceReceiver(), Ctx); - default: - break; - } - break; - default: - break; - } - - return true; -} - -bool trans::isGlobalVar(Expr *E) { - E = E->IgnoreParenCasts(); - if (DeclRefExpr *DRE = dyn_cast(E)) - return DRE->getDecl()->getDeclContext()->isFileContext() && - DRE->getDecl()->isExternallyVisible(); - if (ConditionalOperator *condOp = dyn_cast(E)) - return isGlobalVar(condOp->getTrueExpr()) && - isGlobalVar(condOp->getFalseExpr()); - - return false; -} - -StringRef trans::getNilString(MigrationPass &Pass) { - return Pass.SemaRef.PP.isMacroDefined("nil") ? "nil" : "0"; -} - -namespace { - -class ReferenceClear : public RecursiveASTVisitor { - ExprSet &Refs; -public: - ReferenceClear(ExprSet &refs) : Refs(refs) { } - bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; } -}; - -class ReferenceCollector : public RecursiveASTVisitor { - ValueDecl *Dcl; - ExprSet &Refs; - -public: - ReferenceCollector(ValueDecl *D, ExprSet &refs) - : Dcl(D), Refs(refs) { } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - if (E->getDecl() == Dcl) - Refs.insert(E); - return true; - } -}; - -class RemovablesCollector : public RecursiveASTVisitor { - ExprSet &Removables; - -public: - RemovablesCollector(ExprSet &removables) - : Removables(removables) { } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool TraverseStmtExpr(StmtExpr *E) { - CompoundStmt *S = E->getSubStmt(); - for (CompoundStmt::body_iterator - I = S->body_begin(), E = S->body_end(); I != E; ++I) { - if (I != E - 1) - mark(*I); - TraverseStmt(*I); - } - return true; - } - - bool VisitCompoundStmt(CompoundStmt *S) { - for (auto *I : S->body()) - mark(I); - return true; - } - - bool VisitIfStmt(IfStmt *S) { - mark(S->getThen()); - mark(S->getElse()); - return true; - } - - bool VisitWhileStmt(WhileStmt *S) { - mark(S->getBody()); - return true; - } - - bool VisitDoStmt(DoStmt *S) { - mark(S->getBody()); - return true; - } - - bool VisitForStmt(ForStmt *S) { - mark(S->getInit()); - mark(S->getInc()); - mark(S->getBody()); - return true; - } - -private: - void mark(Stmt *S) { - if (!S) return; - - while (auto *Label = dyn_cast(S)) - S = Label->getSubStmt(); - if (auto *E = dyn_cast(S)) - S = E->IgnoreImplicit(); - if (auto *E = dyn_cast(S)) - Removables.insert(E); - } -}; - -} // end anonymous namespace - -void trans::clearRefsIn(Stmt *S, ExprSet &refs) { - ReferenceClear(refs).TraverseStmt(S); -} - -void trans::collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs) { - ReferenceCollector(D, refs).TraverseStmt(S); -} - -void trans::collectRemovables(Stmt *S, ExprSet &exprs) { - RemovablesCollector(exprs).TraverseStmt(S); -} - -//===----------------------------------------------------------------------===// -// MigrationContext -//===----------------------------------------------------------------------===// - -namespace { - -class ASTTransform : public RecursiveASTVisitor { - MigrationContext &MigrateCtx; - typedef RecursiveASTVisitor base; - -public: - ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { } - - bool shouldWalkTypesOfTypeLocs() const { return false; } - - bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) { - ObjCImplementationContext ImplCtx(MigrateCtx, D); - for (MigrationContext::traverser_iterator - I = MigrateCtx.traversers_begin(), - E = MigrateCtx.traversers_end(); I != E; ++I) - (*I)->traverseObjCImplementation(ImplCtx); - - return base::TraverseObjCImplementationDecl(D); - } - - bool TraverseStmt(Stmt *rootS) { - if (!rootS) - return true; - - BodyContext BodyCtx(MigrateCtx, rootS); - for (MigrationContext::traverser_iterator - I = MigrateCtx.traversers_begin(), - E = MigrateCtx.traversers_end(); I != E; ++I) - (*I)->traverseBody(BodyCtx); - - return true; - } -}; - -} - -MigrationContext::~MigrationContext() { - for (traverser_iterator - I = traversers_begin(), E = traversers_end(); I != E; ++I) - delete *I; -} - -bool MigrationContext::isGCOwnedNonObjC(QualType T) { - while (!T.isNull()) { - if (const AttributedType *AttrT = T->getAs()) { - if (AttrT->getAttrKind() == attr::ObjCOwnership) - return !AttrT->getModifiedType()->isObjCRetainableType(); - } - - if (T->isArrayType()) - T = Pass.Ctx.getBaseElementType(T); - else if (const PointerType *PT = T->getAs()) - T = PT->getPointeeType(); - else if (const ReferenceType *RT = T->getAs()) - T = RT->getPointeeType(); - else - break; - } - - return false; -} - -bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr, - StringRef toAttr, - SourceLocation atLoc) { - if (atLoc.isMacroID()) - return false; - - SourceManager &SM = Pass.Ctx.getSourceManager(); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(atLoc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return false; - - const char *tokenBegin = file.data() + locInfo.second; - - // Lex from the start of the given location. - Lexer lexer(SM.getLocForStartOfFile(locInfo.first), - Pass.Ctx.getLangOpts(), - file.begin(), tokenBegin, file.end()); - Token tok; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::at)) return false; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::raw_identifier)) return false; - if (tok.getRawIdentifier() != "property") - return false; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::l_paren)) return false; - - Token BeforeTok = tok; - Token AfterTok; - AfterTok.startToken(); - SourceLocation AttrLoc; - - lexer.LexFromRawLexer(tok); - if (tok.is(tok::r_paren)) - return false; - - while (true) { - if (tok.isNot(tok::raw_identifier)) return false; - if (tok.getRawIdentifier() == fromAttr) { - if (!toAttr.empty()) { - Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr); - return true; - } - // We want to remove the attribute. - AttrLoc = tok.getLocation(); - } - - do { - lexer.LexFromRawLexer(tok); - if (AttrLoc.isValid() && AfterTok.is(tok::unknown)) - AfterTok = tok; - } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren)); - if (tok.is(tok::r_paren)) - break; - if (AttrLoc.isInvalid()) - BeforeTok = tok; - lexer.LexFromRawLexer(tok); - } - - if (toAttr.empty() && AttrLoc.isValid() && AfterTok.isNot(tok::unknown)) { - // We want to remove the attribute. - if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::r_paren)) { - Pass.TA.remove(SourceRange(BeforeTok.getLocation(), - AfterTok.getLocation())); - } else if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::comma)) { - Pass.TA.remove(SourceRange(AttrLoc, AfterTok.getLocation())); - } else { - Pass.TA.remove(SourceRange(BeforeTok.getLocation(), AttrLoc)); - } - - return true; - } - - return false; -} - -bool MigrationContext::addPropertyAttribute(StringRef attr, - SourceLocation atLoc) { - if (atLoc.isMacroID()) - return false; - - SourceManager &SM = Pass.Ctx.getSourceManager(); - - // Break down the source location. - std::pair locInfo = SM.getDecomposedLoc(atLoc); - - // Try to load the file buffer. - bool invalidTemp = false; - StringRef file = SM.getBufferData(locInfo.first, &invalidTemp); - if (invalidTemp) - return false; - - const char *tokenBegin = file.data() + locInfo.second; - - // Lex from the start of the given location. - Lexer lexer(SM.getLocForStartOfFile(locInfo.first), - Pass.Ctx.getLangOpts(), - file.begin(), tokenBegin, file.end()); - Token tok; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::at)) return false; - lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::raw_identifier)) return false; - if (tok.getRawIdentifier() != "property") - return false; - lexer.LexFromRawLexer(tok); - - if (tok.isNot(tok::l_paren)) { - Pass.TA.insert(tok.getLocation(), std::string("(") + attr.str() + ") "); - return true; - } - - lexer.LexFromRawLexer(tok); - if (tok.is(tok::r_paren)) { - Pass.TA.insert(tok.getLocation(), attr); - return true; - } - - if (tok.isNot(tok::raw_identifier)) return false; - - Pass.TA.insert(tok.getLocation(), std::string(attr) + ", "); - return true; -} - -void MigrationContext::traverse(TranslationUnitDecl *TU) { - for (traverser_iterator - I = traversers_begin(), E = traversers_end(); I != E; ++I) - (*I)->traverseTU(*this); - - ASTTransform(*this).TraverseDecl(TU); -} - -static void GCRewriteFinalize(MigrationPass &pass) { - ASTContext &Ctx = pass.Ctx; - TransformActions &TA = pass.TA; - DeclContext *DC = Ctx.getTranslationUnitDecl(); - Selector FinalizeSel = - Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize")); - - typedef DeclContext::specific_decl_iterator - impl_iterator; - for (impl_iterator I = impl_iterator(DC->decls_begin()), - E = impl_iterator(DC->decls_end()); I != E; ++I) { - for (const auto *MD : I->instance_methods()) { - if (!MD->hasBody()) - continue; - - if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) { - const ObjCMethodDecl *FinalizeM = MD; - Transaction Trans(TA); - TA.insert(FinalizeM->getSourceRange().getBegin(), - "#if !__has_feature(objc_arc)\n"); - CharSourceRange::getTokenRange(FinalizeM->getSourceRange()); - const SourceManager &SM = pass.Ctx.getSourceManager(); - const LangOptions &LangOpts = pass.Ctx.getLangOpts(); - bool Invalid; - std::string str = "\n#endif\n"; - str += Lexer::getSourceText( - CharSourceRange::getTokenRange(FinalizeM->getSourceRange()), - SM, LangOpts, &Invalid); - TA.insertAfterToken(FinalizeM->getSourceRange().getEnd(), str); - - break; - } - } - } -} - -//===----------------------------------------------------------------------===// -// getAllTransformations. -//===----------------------------------------------------------------------===// - -static void traverseAST(MigrationPass &pass) { - MigrationContext MigrateCtx(pass); - - if (pass.isGCMigration()) { - MigrateCtx.addTraverser(new GCCollectableCallsTraverser); - MigrateCtx.addTraverser(new GCAttrsTraverser()); - } - MigrateCtx.addTraverser(new PropertyRewriteTraverser()); - MigrateCtx.addTraverser(new BlockObjCVariableTraverser()); - MigrateCtx.addTraverser(new ProtectedScopeTraverser()); - - MigrateCtx.traverse(pass.Ctx.getTranslationUnitDecl()); -} - -static void independentTransforms(MigrationPass &pass) { - rewriteAutoreleasePool(pass); - removeRetainReleaseDeallocFinalize(pass); - rewriteUnusedInitDelegate(pass); - removeZeroOutPropsInDeallocFinalize(pass); - makeAssignARCSafe(pass); - rewriteUnbridgedCasts(pass); - checkAPIUses(pass); - traverseAST(pass); -} - -std::vector arcmt::getAllTransformations( - LangOptions::GCMode OrigGCMode, - bool NoFinalizeRemoval) { - std::vector transforms; - - if (OrigGCMode == LangOptions::GCOnly && NoFinalizeRemoval) - transforms.push_back(GCRewriteFinalize); - transforms.push_back(independentTransforms); - // This depends on previous transformations removing various expressions. - transforms.push_back(removeEmptyStatementsAndDeallocFinalize); - - return transforms; -} diff --git a/clang/lib/ARCMigrate/Transforms.h b/clang/lib/ARCMigrate/Transforms.h deleted file mode 100644 index 37e2d6b2a7e12..0000000000000 --- a/clang/lib/ARCMigrate/Transforms.h +++ /dev/null @@ -1,224 +0,0 @@ -//===-- Transforms.h - Transformations to ARC mode --------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H -#define LLVM_CLANG_LIB_ARCMIGRATE_TRANSFORMS_H - -#include "clang/AST/ParentMap.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/Support/SaveAndRestore.h" - -namespace clang { - class Decl; - class Stmt; - class BlockDecl; - class ObjCMethodDecl; - class FunctionDecl; - -namespace arcmt { - class MigrationPass; - -namespace trans { - - class MigrationContext; - -//===----------------------------------------------------------------------===// -// Transformations. -//===----------------------------------------------------------------------===// - -void rewriteAutoreleasePool(MigrationPass &pass); -void rewriteUnbridgedCasts(MigrationPass &pass); -void makeAssignARCSafe(MigrationPass &pass); -void removeRetainReleaseDeallocFinalize(MigrationPass &pass); -void removeZeroOutPropsInDeallocFinalize(MigrationPass &pass); -void rewriteUnusedInitDelegate(MigrationPass &pass); -void checkAPIUses(MigrationPass &pass); - -void removeEmptyStatementsAndDeallocFinalize(MigrationPass &pass); - -class BodyContext { - MigrationContext &MigrateCtx; - ParentMap PMap; - Stmt *TopStmt; - -public: - BodyContext(MigrationContext &MigrateCtx, Stmt *S) - : MigrateCtx(MigrateCtx), PMap(S), TopStmt(S) {} - - MigrationContext &getMigrationContext() { return MigrateCtx; } - ParentMap &getParentMap() { return PMap; } - Stmt *getTopStmt() { return TopStmt; } -}; - -class ObjCImplementationContext { - MigrationContext &MigrateCtx; - ObjCImplementationDecl *ImpD; - -public: - ObjCImplementationContext(MigrationContext &MigrateCtx, - ObjCImplementationDecl *D) - : MigrateCtx(MigrateCtx), ImpD(D) {} - - MigrationContext &getMigrationContext() { return MigrateCtx; } - ObjCImplementationDecl *getImplementationDecl() { return ImpD; } -}; - -class ASTTraverser { -public: - virtual ~ASTTraverser(); - virtual void traverseTU(MigrationContext &MigrateCtx) { } - virtual void traverseBody(BodyContext &BodyCtx) { } - virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) {} -}; - -class MigrationContext { - std::vector Traversers; - -public: - MigrationPass &Pass; - - struct GCAttrOccurrence { - enum AttrKind { Weak, Strong } Kind; - SourceLocation Loc; - QualType ModifiedType; - Decl *Dcl; - /// true if the attribute is owned, e.g. it is in a body and not just - /// in an interface. - bool FullyMigratable; - }; - std::vector GCAttrs; - llvm::DenseSet AttrSet; - llvm::DenseSet RemovedAttrSet; - - /// Set of raw '@' locations for 'assign' properties group that contain - /// GC __weak. - llvm::DenseSet AtPropsWeak; - - explicit MigrationContext(MigrationPass &pass) : Pass(pass) {} - ~MigrationContext(); - - typedef std::vector::iterator traverser_iterator; - traverser_iterator traversers_begin() { return Traversers.begin(); } - traverser_iterator traversers_end() { return Traversers.end(); } - - void addTraverser(ASTTraverser *traverser) { - Traversers.push_back(traverser); - } - - bool isGCOwnedNonObjC(QualType T); - bool removePropertyAttribute(StringRef fromAttr, SourceLocation atLoc) { - return rewritePropertyAttribute(fromAttr, StringRef(), atLoc); - } - bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr, - SourceLocation atLoc); - bool addPropertyAttribute(StringRef attr, SourceLocation atLoc); - - void traverse(TranslationUnitDecl *TU); - - void dumpGCAttrs(); -}; - -class PropertyRewriteTraverser : public ASTTraverser { -public: - void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) override; -}; - -class BlockObjCVariableTraverser : public ASTTraverser { -public: - void traverseBody(BodyContext &BodyCtx) override; -}; - -class ProtectedScopeTraverser : public ASTTraverser { -public: - void traverseBody(BodyContext &BodyCtx) override; -}; - -// GC transformations - -class GCAttrsTraverser : public ASTTraverser { -public: - void traverseTU(MigrationContext &MigrateCtx) override; -}; - -class GCCollectableCallsTraverser : public ASTTraverser { -public: - void traverseBody(BodyContext &BodyCtx) override; -}; - -//===----------------------------------------------------------------------===// -// Helpers. -//===----------------------------------------------------------------------===// - -/// Determine whether we can add weak to the given type. -bool canApplyWeak(ASTContext &Ctx, QualType type, - bool AllowOnUnknownClass = false); - -bool isPlusOneAssign(const BinaryOperator *E); -bool isPlusOne(const Expr *E); - -/// 'Loc' is the end of a statement range. This returns the location -/// immediately after the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx, - bool IsDecl = false); - -/// 'Loc' is the end of a statement range. This returns the location -/// of the semicolon following the statement. -/// If no semicolon is found or the location is inside a macro, the returned -/// source location will be invalid. -SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx, - bool IsDecl = false); - -bool hasSideEffects(Expr *E, ASTContext &Ctx); -bool isGlobalVar(Expr *E); -/// Returns "nil" or "0" if 'nil' macro is not actually defined. -StringRef getNilString(MigrationPass &Pass); - -template -class BodyTransform : public RecursiveASTVisitor > { - MigrationPass &Pass; - Decl *ParentD; - - typedef RecursiveASTVisitor > base; -public: - BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(nullptr) { } - - bool TraverseStmt(Stmt *rootS) { - if (rootS) - BODY_TRANS(Pass).transformBody(rootS, ParentD); - return true; - } - - bool TraverseObjCMethodDecl(ObjCMethodDecl *D) { - SaveAndRestore SetParent(ParentD, D); - return base::TraverseObjCMethodDecl(D); - } -}; - -typedef llvm::DenseSet ExprSet; - -void clearRefsIn(Stmt *S, ExprSet &refs); -template -void clearRefsIn(iterator begin, iterator end, ExprSet &refs) { - for (; begin != end; ++begin) - clearRefsIn(*begin, refs); -} - -void collectRefs(ValueDecl *D, Stmt *S, ExprSet &refs); - -void collectRemovables(Stmt *S, ExprSet &exprs); - -} // end namespace trans - -} // end namespace arcmt - -} // end namespace clang - -#endif diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a4ba9fd055346..b1b9d56ccca9f 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1055,7 +1055,8 @@ void ASTContext::PrintStats() const { void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M, bool NotifyListeners) { if (NotifyListeners) - if (auto *Listener = getASTMutationListener()) + if (auto *Listener = getASTMutationListener(); + Listener && !ND->isUnconditionallyVisible()) Listener->RedefinedHiddenDefinition(ND, M); MergedDefModules[cast(ND->getCanonicalDecl())].push_back(M); @@ -2269,11 +2270,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Width = 0; \ Align = 16; \ break; -#define AARCH64_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ - ElBits, NF) \ +#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits) \ case BuiltinType::Id: \ - Width = NumEls * ElBits * NF; \ - Align = NumEls * ElBits; \ + Width = Bits; \ + Align = Bits; \ break; #include "clang/Basic/AArch64SVEACLETypes.def" #define PPC_VECTOR_TYPE(Name, Id, Size) \ @@ -3902,7 +3902,7 @@ QualType ASTContext::getArrayParameterType(QualType Ty) const { if (Ty->isArrayParameterType()) return Ty; assert(Ty->isConstantArrayType() && "Ty must be an array type."); - const auto *ATy = cast(Ty); + const auto *ATy = cast(Ty.getDesugaredType(*this)); llvm::FoldingSetNodeID ID; ATy->Profile(ID, *this, ATy->getElementType(), ATy->getZExtSize(), ATy->getSizeExpr(), ATy->getSizeModifier(), @@ -4423,15 +4423,14 @@ ASTContext::getBuiltinVectorTypeInfo(const BuiltinType *Ty) const { ElBits, NF) \ case BuiltinType::Id: \ return {BFloat16Ty, llvm::ElementCount::getScalable(NumEls), NF}; +#define SVE_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ + ElBits, NF) \ + case BuiltinType::Id: \ + return {MFloat8Ty, llvm::ElementCount::getScalable(NumEls), NF}; #define SVE_PREDICATE_TYPE_ALL(Name, MangledName, Id, SingletonId, NumEls, NF) \ case BuiltinType::Id: \ return {BoolTy, llvm::ElementCount::getScalable(NumEls), NF}; -#define AARCH64_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ - ElBits, NF) \ - case BuiltinType::Id: \ - return {getIntTypeForBitwidth(ElBits, false), \ - llvm::ElementCount::getFixed(NumEls), NF}; -#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) +#define SVE_TYPE(Name, Id, SingletonId) #include "clang/Basic/AArch64SVEACLETypes.def" #define RVV_VECTOR_TYPE_INT(Name, Id, SingletonId, NumEls, ElBits, NF, \ @@ -4493,11 +4492,16 @@ QualType ASTContext::getScalableVectorType(QualType EltTy, unsigned NumElts, EltTySize == ElBits && NumElts == (NumEls * NF) && NumFields == 1) { \ return SingletonId; \ } +#define SVE_VECTOR_TYPE_MFLOAT(Name, MangledName, Id, SingletonId, NumEls, \ + ElBits, NF) \ + if (EltTy->isMFloat8Type() && EltTySize == ElBits && \ + NumElts == (NumEls * NF) && NumFields == 1) { \ + return SingletonId; \ + } #define SVE_PREDICATE_TYPE_ALL(Name, MangledName, Id, SingletonId, NumEls, NF) \ if (EltTy->isBooleanType() && NumElts == (NumEls * NF) && NumFields == 1) \ return SingletonId; -#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) -#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) +#define SVE_TYPE(Name, Id, SingletonId) #include "clang/Basic/AArch64SVEACLETypes.def" } else if (Target->hasRISCVVTypes()) { uint64_t EltTySize = getTypeSize(EltTy); @@ -5316,6 +5320,19 @@ bool ASTContext::computeBestEnumTypes(bool IsPacked, unsigned NumNegativeBits, return EnumTooLarge; } +bool ASTContext::isRepresentableIntegerValue(llvm::APSInt &Value, QualType T) { + assert((T->isIntegralType(*this) || T->isEnumeralType()) && + "Integral type required!"); + unsigned BitWidth = getIntWidth(T); + + if (Value.isUnsigned() || Value.isNonNegative()) { + if (T->isSignedIntegerOrEnumerationType()) + --BitWidth; + return Value.getActiveBits() <= BitWidth; + } + return Value.getSignificantBits() <= BitWidth; +} + QualType ASTContext::getUnresolvedUsingType( const UnresolvedUsingTypenameDecl *Decl) const { if (Decl->TypeForDecl) @@ -7221,6 +7238,16 @@ static bool isSameQualifier(const NestedNameSpecifier *X, return !PX && !PY; } +static bool hasSameCudaAttrs(const FunctionDecl *A, const FunctionDecl *B) { + if (!A->getASTContext().getLangOpts().CUDA) + return true; // Target attributes are overloadable in CUDA compilation only. + if (A->hasAttr() != B->hasAttr()) + return false; + if (A->hasAttr() && B->hasAttr()) + return A->hasAttr() == B->hasAttr(); + return true; // unattributed and __host__ functions are the same. +} + /// Determine whether the attributes we can overload on are identical for A and /// B. Will ignore any overloadable attrs represented in the type of A and B. static bool hasSameOverloadableAttrs(const FunctionDecl *A, @@ -7251,7 +7278,7 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A, if (Cand1ID != Cand2ID) return false; } - return true; + return hasSameCudaAttrs(A, B); } bool ASTContext::isSameEntity(const NamedDecl *X, const NamedDecl *Y) const { @@ -10360,7 +10387,8 @@ bool ASTContext::areLaxCompatibleSveTypes(QualType FirstType, /// getRVVTypeSize - Return RVV vector register size. static uint64_t getRVVTypeSize(ASTContext &Context, const BuiltinType *Ty) { assert(Ty->isRVVVLSBuiltinType() && "Invalid RVV Type"); - auto VScale = Context.getTargetInfo().getVScaleRange(Context.getLangOpts()); + auto VScale = + Context.getTargetInfo().getVScaleRange(Context.getLangOpts(), false); if (!VScale) return 0; @@ -12382,6 +12410,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context, case 'p': Type = Context.getProcessIDType(); break; + case 'm': + Type = Context.MFloat8Ty; + break; } // If there are modifiers and if we're allowed to parse them, go for it. @@ -12835,11 +12866,12 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { // Likewise, variables with tuple-like bindings are required if their // bindings have side-effects. - if (const auto *DD = dyn_cast(VD)) - for (const auto *BD : DD->bindings()) + if (const auto *DD = dyn_cast(VD)) { + for (const auto *BD : DD->flat_bindings()) if (const auto *BindingVD = BD->getHoldingVar()) if (DeclMustBeEmitted(BindingVD)) return true; + } return false; } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 0669aa1b809c3..c27ebbf838ad1 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -15,6 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/ASTImporterSharedState.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/ASTStructuralEquivalence.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" @@ -2552,7 +2553,7 @@ ExpectedDecl ASTNodeImporter::VisitBindingDecl(BindingDecl *D) { BindingDecl *ToD; if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, Loc, - Name.getAsIdentifierInfo())) + Name.getAsIdentifierInfo(), D->getType())) return ToD; Error Err = Error::success(); @@ -3729,10 +3730,7 @@ bool ASTNodeImporter::hasReturnTypeDeclaredInside(FunctionDecl *D) { if (Importer.FromContext.getLangOpts().CPlusPlus14) // C++14 or later return false; - if (const auto *MD = dyn_cast(D)) - return cast(MD->getDeclContext())->isLambda(); - - return false; + return isLambdaMethod(D); }; QualType RetT = FromFPT->getReturnType(); @@ -3999,14 +3997,16 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) { importExplicitSpecifier(Err, Guide->getExplicitSpecifier()); CXXConstructorDecl *Ctor = importChecked(Err, Guide->getCorrespondingConstructor()); + const CXXDeductionGuideDecl *SourceDG = + importChecked(Err, Guide->getSourceDeductionGuide()); if (Err) return std::move(Err); if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, ESpec, - NameInfo, T, TInfo, ToEndLoc, Ctor)) + NameInfo, T, TInfo, ToEndLoc, Ctor, + Guide->getDeductionCandidateKind(), TrailingRequiresClause, + SourceDG, Guide->getSourceDeductionGuideKind())) return ToFunction; - cast(ToFunction) - ->setDeductionCandidateKind(Guide->getDeductionCandidateKind()); } else { if (GetImportedOrCreateDecl( ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart, @@ -4701,9 +4701,13 @@ ExpectedDecl ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) { Error ASTNodeImporter::ImportDefaultArgOfParmVarDecl( const ParmVarDecl *FromParam, ParmVarDecl *ToParam) { + + if (auto LocOrErr = import(FromParam->getExplicitObjectParamThisLoc())) + ToParam->setExplicitObjectParameterLoc(*LocOrErr); + else + return LocOrErr.takeError(); + ToParam->setHasInheritedDefaultArg(FromParam->hasInheritedDefaultArg()); - ToParam->setExplicitObjectParameterLoc( - FromParam->getExplicitObjectParamThisLoc()); ToParam->setKNRPromoted(FromParam->isKNRPromoted()); if (FromParam->hasUninstantiatedDefaultArg()) { @@ -6316,10 +6320,10 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl( updateLookupTableForTemplateParameters(*ToTPList); } else { // Not a partial specialization. - if (GetImportedOrCreateDecl( - D2, D, Importer.getToContext(), D->getTagKind(), DC, - *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs, - PrevDecl)) + if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), D->getTagKind(), + DC, *BeginLocOrErr, *IdLocOrErr, ClassTemplate, + TemplateArgs, D->hasStrictPackMatch(), + PrevDecl)) return D2; // Update InsertPos, because preceding import calls may have invalidated @@ -6755,6 +6759,14 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { Params, TemplatedFD)) return ToFunc; + // Fail if TemplatedFD is already part of a template. + // The template should have been found by structural equivalence check before, + // or ToFunc should be already imported. + // If not, there is AST incompatibility that can be caused by previous import + // errors. (NameConflict is not exact here.) + if (TemplatedFD->getDescribedTemplate()) + return make_error(ASTImportError::NameConflict); + TemplatedFD->setDescribedFunctionTemplate(ToFunc); ToFunc->setAccess(D->getAccess()); diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp index 19e2416c4c942..5bd1b73133d65 100644 --- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp +++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp @@ -135,11 +135,9 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { // Create a handle over the emitted code. Function *Func = P.getFunction(FuncDecl); if (!Func) { - unsigned BuiltinID = FuncDecl->getBuiltinID(); - Func = - P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes), - std::move(ParamDescriptors), std::move(ParamOffsets), - HasThisPointer, HasRVO, BuiltinID); + Func = P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes), + std::move(ParamDescriptors), + std::move(ParamOffsets), HasThisPointer, HasRVO); } assert(Func); @@ -212,8 +210,7 @@ Function *ByteCodeEmitter::compileObjCBlock(const BlockExpr *BE) { Function *Func = P.createFunction(BE, ParamOffset, std::move(ParamTypes), std::move(ParamDescriptors), std::move(ParamOffsets), - /*HasThisPointer=*/false, /*HasRVO=*/false, - /*IsUnevaluatedBuiltin=*/false); + /*HasThisPointer=*/false, /*HasRVO=*/false); assert(Func); Func->setDefined(true); diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 66ab27bdd13da..cf39209819ade 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -194,12 +194,12 @@ template class StmtExprScope final { template bool Compiler::VisitCastExpr(const CastExpr *CE) { const Expr *SubExpr = CE->getSubExpr(); - switch (CE->getCastKind()) { - case CK_LValueToRValue: { - if (DiscardResult) - return this->discard(SubExpr); + if (DiscardResult) + return this->delegate(SubExpr); + switch (CE->getCastKind()) { + case CK_LValueToRValue: { std::optional SubExprT = classify(SubExpr->getType()); // Prepare storage for the result. if (!Initializing && !SubExprT) { @@ -253,9 +253,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { case CK_UncheckedDerivedToBase: case CK_DerivedToBase: { - if (DiscardResult) - return this->discard(SubExpr); - if (!this->delegate(SubExpr)) return false; @@ -285,9 +282,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { } case CK_BaseToDerived: { - if (DiscardResult) - return this->discard(SubExpr); - if (!this->delegate(SubExpr)) return false; @@ -302,8 +296,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { if (!SubExpr->getType()->isFloatingType() || !CE->getType()->isFloatingType()) return false; - if (DiscardResult) - return this->discard(SubExpr); if (!this->visit(SubExpr)) return false; const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType()); @@ -311,8 +303,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { } case CK_IntegralToFloating: { - if (DiscardResult) - return this->discard(SubExpr); std::optional FromT = classify(SubExpr->getType()); if (!FromT) return false; @@ -327,8 +317,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { case CK_FloatingToBoolean: case CK_FloatingToIntegral: { - if (DiscardResult) - return this->discard(SubExpr); std::optional ToT = classify(CE->getType()); @@ -352,9 +340,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { case CK_NullToMemberPointer: { if (!this->discard(SubExpr)) return false; - if (DiscardResult) - return true; - const Descriptor *Desc = nullptr; const QualType PointeeType = CE->getType()->getPointeeType(); if (!PointeeType.isNull()) { @@ -371,9 +356,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { } case CK_PointerToIntegral: { - if (DiscardResult) - return this->discard(SubExpr); - if (!this->visit(SubExpr)) return false; @@ -399,8 +381,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { return false; if (!this->emitArrayDecay(CE)) return false; - if (DiscardResult) - return this->emitPopPtr(CE); return true; } @@ -412,9 +392,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { // FIXME: I think the discard is wrong since the int->ptr cast might cause a // diagnostic. PrimType T = classifyPrim(IntType); - if (DiscardResult) - return this->emitPop(T, CE); - QualType PtrType = CE->getType(); const Descriptor *Desc; if (std::optional T = classify(PtrType->getPointeeType())) @@ -454,10 +431,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { return false; return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, CE); } - - if (DiscardResult) - return this->discard(SubExpr); - QualType SubExprTy = SubExpr->getType(); std::optional FromT = classify(SubExprTy); // Casts from integer/vector to vector. @@ -493,8 +466,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { case CK_FixedPointToBoolean: case CK_BooleanToSignedIntegral: case CK_IntegralCast: { - if (DiscardResult) - return this->discard(SubExpr); std::optional FromT = classify(SubExpr->getType()); std::optional ToT = classify(CE->getType()); @@ -546,8 +517,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { case CK_IntegralComplexToBoolean: case CK_FloatingComplexToBoolean: { - if (DiscardResult) - return this->discard(SubExpr); if (!this->visit(SubExpr)) return false; return this->emitComplexBoolCast(SubExpr); @@ -562,8 +531,10 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { // We're creating a complex value here, so we need to // allocate storage for it. if (!Initializing) { - unsigned LocalIndex = allocateTemporary(CE); - if (!this->emitGetPtrLocal(LocalIndex, CE)) + std::optional LocalIndex = allocateTemporary(CE); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, CE)) return false; } @@ -583,9 +554,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { case CK_FloatingComplexToIntegralComplex: { assert(CE->getType()->isAnyComplexType()); assert(SubExpr->getType()->isAnyComplexType()); - if (DiscardResult) - return this->discard(SubExpr); - if (!Initializing) { std::optional LocalIndex = allocateLocal(CE); if (!LocalIndex) @@ -631,9 +599,6 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { assert(classify(SubExpr->getType())); assert(CE->getType()->isVectorType()); - if (DiscardResult) - return this->discard(SubExpr); - if (!Initializing) { std::optional LocalIndex = allocateLocal(CE); if (!LocalIndex) @@ -679,8 +644,10 @@ bool Compiler::VisitCastExpr(const CastExpr *CE) { assert(CE->getType()->isVectorType()); if (!Initializing) { - unsigned LocalIndex = allocateTemporary(CE); - if (!this->emitGetPtrLocal(LocalIndex, CE)) + std::optional LocalIndex = allocateTemporary(CE); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, CE)) return false; } unsigned ToSize = CE->getType()->getAs()->getNumElements(); @@ -759,8 +726,10 @@ bool Compiler::VisitImaginaryLiteral(const ImaginaryLiteral *E) { return true; if (!Initializing) { - unsigned LocalIndex = allocateTemporary(E); - if (!this->emitGetPtrLocal(LocalIndex, E)) + std::optional LocalIndex = allocateTemporary(E); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, E)) return false; } @@ -1118,8 +1087,10 @@ template bool Compiler::VisitComplexBinOp(const BinaryOperator *E) { // Prepare storage for result. if (!Initializing) { - unsigned LocalIndex = allocateTemporary(E); - if (!this->emitGetPtrLocal(LocalIndex, E)) + std::optional LocalIndex = allocateTemporary(E); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, E)) return false; } @@ -1175,7 +1146,10 @@ bool Compiler::VisitComplexBinOp(const BinaryOperator *E) { if (!LHSIsComplex) { // This is using the RHS type for the fake-complex LHS. - LHSOffset = allocateTemporary(RHS); + std::optional LocalIndex = allocateTemporary(RHS); + if (!LocalIndex) + return false; + LHSOffset = *LocalIndex; if (!this->emitGetPtrLocal(LHSOffset, E)) return false; @@ -1347,8 +1321,10 @@ bool Compiler::VisitVectorBinOp(const BinaryOperator *E) { // Prepare storage for result. if (!Initializing && !E->isCompoundAssignmentOp()) { - unsigned LocalIndex = allocateTemporary(E); - if (!this->emitGetPtrLocal(LocalIndex, E)) + std::optional LocalIndex = allocateTemporary(E); + if (!LocalIndex) + return false; + if (!this->emitGetPtrLocal(*LocalIndex, E)) return false; } @@ -3357,15 +3333,23 @@ bool Compiler::VisitCXXNewExpr(const CXXNewExpr *E) { PrimType SizeT = classifyPrim(Stripped->getType()); + // Save evaluated array size to a variable. + unsigned ArrayLen = allocateLocalPrimitive( + Stripped, SizeT, /*IsConst=*/false, /*IsExtended=*/false); + if (!this->visit(Stripped)) + return false; + if (!this->emitSetLocal(SizeT, ArrayLen, E)) + return false; + if (PlacementDest) { if (!this->visit(PlacementDest)) return false; - if (!this->visit(Stripped)) + if (!this->emitGetLocal(SizeT, ArrayLen, E)) return false; if (!this->emitCheckNewTypeMismatchArray(SizeT, E, E)) return false; } else { - if (!this->visit(Stripped)) + if (!this->emitGetLocal(SizeT, ArrayLen, E)) return false; if (ElemT) { @@ -3379,10 +3363,113 @@ bool Compiler::VisitCXXNewExpr(const CXXNewExpr *E) { } } - if (Init && !this->visitInitializer(Init)) - return false; + if (Init) { + QualType InitType = Init->getType(); + size_t StaticInitElems = 0; + const Expr *DynamicInit = nullptr; + if (const ConstantArrayType *CAT = + Ctx.getASTContext().getAsConstantArrayType(InitType)) { + StaticInitElems = CAT->getZExtSize(); + if (!this->visitInitializer(Init)) + return false; - } else { + if (const auto *ILE = dyn_cast(Init); + ILE && ILE->hasArrayFiller()) + DynamicInit = ILE->getArrayFiller(); + } + + // The initializer initializes a certain number of elements, S. + // However, the complete number of elements, N, might be larger than that. + // In this case, we need to get an initializer for the remaining elements. + // There are to cases: + // 1) For the form 'new Struct[n];', the initializer is a + // CXXConstructExpr and its type is an IncompleteArrayType. + // 2) For the form 'new Struct[n]{1,2,3}', the initializer is an + // InitListExpr and the initializer for the remaining elements + // is the array filler. + + if (DynamicInit || InitType->isIncompleteArrayType()) { + const Function *CtorFunc = nullptr; + if (const auto *CE = dyn_cast(Init)) { + CtorFunc = getFunction(CE->getConstructor()); + if (!CtorFunc) + return false; + } + + LabelTy EndLabel = this->getLabel(); + LabelTy StartLabel = this->getLabel(); + + // In the nothrow case, the alloc above might have returned nullptr. + // Don't call any constructors that case. + if (IsNoThrow) { + if (!this->emitDupPtr(E)) + return false; + if (!this->emitNullPtr(0, nullptr, E)) + return false; + if (!this->emitEQPtr(E)) + return false; + if (!this->jumpTrue(EndLabel)) + return false; + } + + // Create loop variables. + unsigned Iter = allocateLocalPrimitive( + Stripped, SizeT, /*IsConst=*/false, /*IsExtended=*/false); + if (!this->emitConst(StaticInitElems, SizeT, E)) + return false; + if (!this->emitSetLocal(SizeT, Iter, E)) + return false; + + this->fallthrough(StartLabel); + this->emitLabel(StartLabel); + // Condition. Iter < ArrayLen? + if (!this->emitGetLocal(SizeT, Iter, E)) + return false; + if (!this->emitGetLocal(SizeT, ArrayLen, E)) + return false; + if (!this->emitLT(SizeT, E)) + return false; + if (!this->jumpFalse(EndLabel)) + return false; + + // Pointer to the allocated array is already on the stack. + if (!this->emitGetLocal(SizeT, Iter, E)) + return false; + if (!this->emitArrayElemPtr(SizeT, E)) + return false; + + if (DynamicInit) { + if (std::optional InitT = classify(DynamicInit)) { + if (!this->visit(DynamicInit)) + return false; + if (!this->emitStorePop(*InitT, E)) + return false; + } else { + if (!this->visitInitializer(DynamicInit)) + return false; + if (!this->emitPopPtr(E)) + return false; + } + } else { + assert(CtorFunc); + if (!this->emitCall(CtorFunc, 0, E)) + return false; + } + + // ++Iter; + if (!this->emitGetPtrLocal(Iter, E)) + return false; + if (!this->emitIncPop(SizeT, E)) + return false; + + if (!this->jump(StartLabel)) + return false; + + this->fallthrough(EndLabel); + this->emitLabel(EndLabel); + } + } + } else { // Non-array. if (PlacementDest) { if (!this->visit(PlacementDest)) return false; @@ -4170,14 +4257,16 @@ Compiler::allocateLocal(DeclTy &&Src, QualType Ty, } template -unsigned Compiler::allocateTemporary(const Expr *E) { +std::optional Compiler::allocateTemporary(const Expr *E) { QualType Ty = E->getType(); assert(!Ty->isRecordType()); Descriptor *D = P.createDescriptor( E, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(), /*IsTemporary=*/true, /*IsMutable=*/false, /*Init=*/nullptr); - assert(D); + + if (!D) + return std::nullopt; Scope::Local Local = this->createLocal(D); VariableScope *S = VarScope; @@ -4661,7 +4750,7 @@ bool Compiler::VisitCallExpr(const CallExpr *E) { OCE && OCE->isAssignmentOp()) { // Just like with regular assignments, we need to special-case assignment // operators here and evaluate the RHS (the second arg) before the LHS (the - // first arg. We fix this by using a Flip op later. + // first arg). We fix this by using a Flip op later. assert(Args.size() == 2); IsAssignmentOperatorCall = true; std::reverse(Args.begin(), Args.end()); @@ -4700,6 +4789,14 @@ bool Compiler::VisitCallExpr(const CallExpr *E) { } else if (!this->visit(MC->getImplicitObjectArgument())) { return false; } + } else if (const auto *PD = + dyn_cast(E->getCallee())) { + const Expr *Base = PD->getBase(); + if (!Base->isGLValue()) + return this->discard(Base); + if (!this->visit(Base)) + return false; + return this->emitKill(E); } else if (!FuncDecl) { const Expr *Callee = E->getCallee(); CalleeOffset = this->allocateLocalPrimitive(Callee, PT_FnPtr, true, false); @@ -4976,8 +5073,8 @@ bool Compiler::visitCompoundStmt(const CompoundStmt *S) { template bool Compiler::visitDeclStmt(const DeclStmt *DS) { for (const auto *D : DS->decls()) { - if (isa(D)) + if (isa(D)) continue; const auto *VD = dyn_cast(D); @@ -5581,6 +5678,22 @@ bool Compiler::compileConstructor(const CXXConstructorDecl *Ctor) { if (!emitFieldInitializer(NestedField, NestedFieldOffset, InitExpr)) return false; + + // Mark all chain links as initialized. + unsigned InitFieldOffset = 0; + for (const NamedDecl *ND : IFD->chain().drop_back()) { + const auto *FD = cast(ND); + const Record *FieldRecord = this->P.getOrCreateRecord(FD->getParent()); + assert(FieldRecord); + NestedField = FieldRecord->getField(FD); + InitFieldOffset += NestedField->Offset; + assert(NestedField); + if (!this->emitGetPtrThisField(InitFieldOffset, InitExpr)) + return false; + if (!this->emitFinishInitPop(InitExpr)) + return false; + } + } else { assert(Init->isDelegatingInitializer()); if (!this->emitThis(InitExpr)) @@ -5649,6 +5762,21 @@ bool Compiler::compileDestructor(const CXXDestructorDecl *Dtor) { return this->emitPopPtr(Dtor) && this->emitRetVoid(Dtor); } +template +bool Compiler::compileUnionAssignmentOperator( + const CXXMethodDecl *MD) { + if (!this->emitThis(MD)) + return false; + + auto PVD = MD->getParamDecl(0); + ParamOffset PO = this->Params[PVD]; // Must exist. + + if (!this->emitGetParam(PT_Ptr, PO.Offset, MD)) + return false; + + return this->emitMemcpy(MD) && this->emitRet(PT_Ptr, MD); +} + template bool Compiler::visitFunc(const FunctionDecl *F) { // Classify the return type. @@ -5660,9 +5788,16 @@ bool Compiler::visitFunc(const FunctionDecl *F) { return this->compileDestructor(Dtor); // Emit custom code if this is a lambda static invoker. - if (const auto *MD = dyn_cast(F); - MD && MD->isLambdaStaticInvoker()) - return this->emitLambdaStaticInvokerBody(MD); + if (const auto *MD = dyn_cast(F)) { + const RecordDecl *RD = MD->getParent(); + + if (RD->isUnion() && + (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())) + return this->compileUnionAssignmentOperator(MD); + + if (MD->isLambdaStaticInvoker()) + return this->emitLambdaStaticInvokerBody(MD); + } // Regular functions. if (const auto *Body = F->getBody()) @@ -6173,9 +6308,6 @@ bool Compiler::visitDeclRef(const ValueDecl *D, const Expr *E) { return this->emitGetPtrParam(It->second.Offset, E); } - - if (D->getType()->isReferenceType()) - return false; // FIXME: Do we need to emit InvalidDeclRef? } // In case we need to re-visit a declaration. diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index f9a597a16ef4a..0a93c46a40ef5 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -309,7 +309,7 @@ class Compiler : public ConstStmtVisitor, bool>, std::optional allocateLocal(DeclTy &&Decl, QualType Ty = QualType(), const ValueDecl *ExtendingDecl = nullptr); - unsigned allocateTemporary(const Expr *E); + std::optional allocateTemporary(const Expr *E); private: friend class VariableScope; @@ -383,6 +383,7 @@ class Compiler : public ConstStmtVisitor, bool>, bool emitBuiltinBitCast(const CastExpr *E); bool compileConstructor(const CXXConstructorDecl *Ctor); bool compileDestructor(const CXXDestructorDecl *Dtor); + bool compileUnionAssignmentOperator(const CXXMethodDecl *MD); bool checkLiteralType(const Expr *E); diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index b52892cf69bfb..aa434d5c85921 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -27,10 +27,7 @@ Context::~Context() {} bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { assert(Stk.empty()); - Function *Func = P->getFunction(FD); - if (!Func || !Func->hasBody()) - Func = Compiler(*this, *P).compileFunc(FD); - + const Function *Func = getOrCreateFunction(FD); if (!Func) return false; @@ -215,14 +212,11 @@ const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const { bool Context::Run(State &Parent, const Function *Func) { { - InterpState State(Parent, *P, Stk, *this); - State.Current = new InterpFrame(State, Func, /*Caller=*/nullptr, CodePtr(), - Func->getArgSize()); + InterpState State(Parent, *P, Stk, *this, Func); if (Interpret(State)) { assert(Stk.empty()); return true; } - // State gets destroyed here, so the Stk.clear() below doesn't accidentally // remove values the State's destructor might access. } @@ -271,6 +265,7 @@ Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl, const Function *Context::getOrCreateFunction(const FunctionDecl *FD) { assert(FD); + FD = FD->getMostRecentDecl(); const Function *Func = P->getFunction(FD); bool IsBeingCompiled = Func && Func->isDefined() && !Func->isFullyCompiled(); bool WasNotDefined = Func && !Func->isConstexpr() && !Func->isDefined(); diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 1c16c2022dd02..319d1690c1cd0 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -409,7 +409,8 @@ QualType Descriptor::getElemQualType() const { assert(isArray()); QualType T = getType(); if (T->isPointerOrReferenceType()) - return T->getPointeeType(); + T = T->getPointeeType(); + if (const auto *AT = T->getAsArrayTypeUnsafe()) { // For primitive arrays, we don't save a QualType at all, // just a PrimType. Try to figure out the QualType here. @@ -424,7 +425,8 @@ QualType Descriptor::getElemQualType() const { return CT->getElementType(); if (const auto *CT = T->getAs()) return CT->getElementType(); - llvm_unreachable("Array that's not an array/complex/vector type?"); + + return T; } SourceLocation Descriptor::getLocation() const { diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h index a73e28d2e600e..96c82a18913e0 100644 --- a/clang/lib/AST/ByteCode/Descriptor.h +++ b/clang/lib/AST/ByteCode/Descriptor.h @@ -61,6 +61,11 @@ struct alignas(void *) GlobalInlineDescriptor { }; static_assert(sizeof(GlobalInlineDescriptor) == sizeof(void *), ""); +enum class Lifetime : uint8_t { + Started, + Ended, +}; + /// Inline descriptor embedded in structures and arrays. /// /// Such descriptors precede all composite array elements and structure fields. @@ -100,12 +105,14 @@ struct InlineDescriptor { LLVM_PREFERRED_TYPE(bool) unsigned IsArrayElement : 1; + Lifetime LifeState; + const Descriptor *Desc; InlineDescriptor(const Descriptor *D) : Offset(sizeof(InlineDescriptor)), IsConst(false), IsInitialized(false), IsBase(false), IsActive(false), IsFieldMutable(false), - IsArrayElement(false), Desc(D) {} + IsArrayElement(false), LifeState(Lifetime::Started), Desc(D) {} void dump() const { dump(llvm::errs()); } void dump(llvm::raw_ostream &OS) const; diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp index 3c55c884a3507..92a169a37c365 100644 --- a/clang/lib/AST/ByteCode/Disasm.cpp +++ b/clang/lib/AST/ByteCode/Disasm.cpp @@ -240,7 +240,7 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const { else if (isRecord()) OS << " record"; else if (isPrimitive()) - OS << " primitive"; + OS << " primitive " << primTypeToString(getPrimType()); if (isZeroSizeArray()) OS << " zero-size-array"; diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp index 9763fe89b7374..95149efbea992 100644 --- a/clang/lib/AST/ByteCode/EvalEmitter.cpp +++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp @@ -17,11 +17,7 @@ using namespace clang::interp; EvalEmitter::EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk) - : Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), EvalResult(&Ctx) { - // Create a dummy frame for the interpreter which does not have locals. - S.Current = - new InterpFrame(S, /*Func=*/nullptr, /*Caller=*/nullptr, CodePtr(), 0); -} + : Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), EvalResult(&Ctx) {} EvalEmitter::~EvalEmitter() { for (auto &[K, V] : Locals) { @@ -174,6 +170,9 @@ template <> bool EvalEmitter::emitRet(const SourceInfo &Info) { return false; } } else { + if (!Ptr.isLive() && !Ptr.isTemporary()) + return false; + EvalResult.setValue(Ptr.toAPValue(Ctx.getASTContext())); } diff --git a/clang/lib/AST/ByteCode/EvalEmitter.h b/clang/lib/AST/ByteCode/EvalEmitter.h index e7c9e80d75d93..2cac2ba2ef221 100644 --- a/clang/lib/AST/ByteCode/EvalEmitter.h +++ b/clang/lib/AST/ByteCode/EvalEmitter.h @@ -17,7 +17,6 @@ #include "InterpState.h" #include "PrimType.h" #include "Source.h" -#include "llvm/Support/Error.h" namespace clang { namespace interp { @@ -42,8 +41,6 @@ class EvalEmitter : public SourceMapper { /// Clean up all resources. void cleanup(); - InterpState &getState() { return S; } - protected: EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk); diff --git a/clang/lib/AST/ByteCode/Function.cpp b/clang/lib/AST/ByteCode/Function.cpp index 896a4fb3f9469..6b892dfd616c1 100644 --- a/clang/lib/AST/ByteCode/Function.cpp +++ b/clang/lib/AST/ByteCode/Function.cpp @@ -19,12 +19,28 @@ Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize, llvm::SmallVectorImpl &&ParamTypes, llvm::DenseMap &&Params, llvm::SmallVectorImpl &&ParamOffsets, - bool HasThisPointer, bool HasRVO, unsigned BuiltinID) - : P(P), Source(Source), ArgSize(ArgSize), ParamTypes(std::move(ParamTypes)), - Params(std::move(Params)), ParamOffsets(std::move(ParamOffsets)), - HasThisPointer(HasThisPointer), HasRVO(HasRVO), BuiltinID(BuiltinID) { - if (const auto *F = Source.dyn_cast()) + bool HasThisPointer, bool HasRVO) + : P(P), Kind(FunctionKind::Normal), Source(Source), ArgSize(ArgSize), + ParamTypes(std::move(ParamTypes)), Params(std::move(Params)), + ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer), + HasRVO(HasRVO) { + if (const auto *F = dyn_cast(Source)) { Variadic = F->isVariadic(); + BuiltinID = F->getBuiltinID(); + if (const auto *CD = dyn_cast(F)) { + Virtual = CD->isVirtual(); + Kind = FunctionKind::Ctor; + } else if (const auto *CD = dyn_cast(F)) { + Virtual = CD->isVirtual(); + Kind = FunctionKind::Dtor; + } else if (const auto *MD = dyn_cast(F)) { + Virtual = MD->isVirtual(); + if (MD->isLambdaStaticInvoker()) + Kind = FunctionKind::LambdaStaticInvoker; + else if (clang::isLambdaCallOperator(F)) + Kind = FunctionKind::LambdaCallOperator; + } + } } Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const { @@ -45,13 +61,6 @@ SourceInfo Function::getSource(CodePtr PC) const { return It->second; } -bool Function::isVirtual() const { - if (const auto *M = dyn_cast_if_present( - Source.dyn_cast())) - return M->isVirtual(); - return false; -} - /// Unevaluated builtins don't get their arguments put on the stack /// automatically. They instead operate on the AST of their Call /// Expression. diff --git a/clang/lib/AST/ByteCode/Function.h b/clang/lib/AST/ByteCode/Function.h index 409a80f59f1e9..e17183eef9eac 100644 --- a/clang/lib/AST/ByteCode/Function.h +++ b/clang/lib/AST/ByteCode/Function.h @@ -51,6 +51,11 @@ class Scope final { return llvm::make_range(Descriptors.begin(), Descriptors.end()); } + llvm::iterator_range + locals_reverse() const { + return llvm::reverse(Descriptors); + } + private: /// Object descriptors in this block. LocalVectorTy Descriptors; @@ -80,6 +85,13 @@ using FunctionDeclTy = /// class Function final { public: + enum class FunctionKind { + Normal, + Ctor, + Dtor, + LambdaStaticInvoker, + LambdaCallOperator, + }; using ParamDescriptor = std::pair; /// Returns the size of the function's local stack. @@ -141,43 +153,31 @@ class Function final { bool isConstexpr() const { return IsValid || isLambdaStaticInvoker(); } /// Checks if the function is virtual. - bool isVirtual() const; + bool isVirtual() const { return Virtual; }; /// Checks if the function is a constructor. - bool isConstructor() const { - return isa_and_nonnull( - dyn_cast(Source)); - } + bool isConstructor() const { return Kind == FunctionKind::Ctor; } /// Checks if the function is a destructor. - bool isDestructor() const { - return isa_and_nonnull( - dyn_cast(Source)); - } - - /// Returns the parent record decl, if any. - const CXXRecordDecl *getParentDecl() const { - if (const auto *MD = dyn_cast_if_present( - dyn_cast(Source))) - return MD->getParent(); - return nullptr; - } + bool isDestructor() const { return Kind == FunctionKind::Dtor; } /// Returns whether this function is a lambda static invoker, /// which we generate custom byte code for. bool isLambdaStaticInvoker() const { - if (const auto *MD = dyn_cast_if_present( - dyn_cast(Source))) - return MD->isLambdaStaticInvoker(); - return false; + return Kind == FunctionKind::LambdaStaticInvoker; } /// Returns whether this function is the call operator /// of a lambda record decl. bool isLambdaCallOperator() const { + return Kind == FunctionKind::LambdaCallOperator; + } + + /// Returns the parent record decl, if any. + const CXXRecordDecl *getParentDecl() const { if (const auto *MD = dyn_cast_if_present( dyn_cast(Source))) - return clang::isLambdaCallOperator(MD); - return false; + return MD->getParent(); + return nullptr; } /// Checks if the function is fully done compiling. @@ -213,7 +213,7 @@ class Function final { bool isThisPointerExplicit() const { if (const auto *MD = dyn_cast_if_present( - Source.dyn_cast())) + dyn_cast(Source))) return MD->isExplicitObjectMemberFunction(); return false; } @@ -232,7 +232,7 @@ class Function final { llvm::SmallVectorImpl &&ParamTypes, llvm::DenseMap &&Params, llvm::SmallVectorImpl &&ParamOffsets, bool HasThisPointer, - bool HasRVO, unsigned BuiltinID); + bool HasRVO); /// Sets the code of a function. void setCode(unsigned NewFrameSize, std::vector &&NewCode, @@ -255,6 +255,8 @@ class Function final { /// Program reference. Program &P; + /// Function Kind. + FunctionKind Kind; /// Declaration this function was compiled from. FunctionDeclTy Source; /// Local area size: storage + metadata. @@ -289,6 +291,7 @@ class Function final { bool HasBody = false; bool Defined = false; bool Variadic = false; + bool Virtual = false; unsigned BuiltinID = 0; public: diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 40fe7147a18a3..c80be094856b0 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -65,14 +65,17 @@ static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, const ValueDecl *VD); static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC, const ValueDecl *D) { - const SourceInfo &E = S.Current->getSource(OpPC); if (isa(D)) { + if (D->getType()->isReferenceType()) + return false; + + const SourceInfo &Loc = S.Current->getSource(OpPC); if (S.getLangOpts().CPlusPlus11) { - S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D; + S.FFDiag(Loc, diag::note_constexpr_function_param_value_unknown) << D; S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange(); } else { - S.FFDiag(E); + S.FFDiag(Loc); } return false; } @@ -558,6 +561,18 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return false; } +static bool CheckLifetime(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + AccessKinds AK) { + if (Ptr.getLifetime() == Lifetime::Started) + return true; + + if (!S.checkingPotentialConstantExpression()) { + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_uninit) + << AK << /*uninitialized=*/false << S.Current->getRange(OpPC); + } + return false; +} + bool CheckGlobalInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (Ptr.isInitialized()) return true; @@ -602,6 +617,8 @@ bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return false; if (!CheckActive(S, OpPC, Ptr, AK)) return false; + if (!CheckLifetime(S, OpPC, Ptr, AK)) + return false; if (!CheckInitialized(S, OpPC, Ptr, AK)) return false; if (!CheckTemporary(S, OpPC, Ptr, AK)) @@ -631,6 +648,8 @@ bool CheckFinalLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return false; if (!CheckActive(S, OpPC, Ptr, AK_Read)) return false; + if (!CheckLifetime(S, OpPC, Ptr, AK_Read)) + return false; if (!CheckInitialized(S, OpPC, Ptr, AK_Read)) return false; if (!CheckTemporary(S, OpPC, Ptr, AK_Read)) @@ -647,6 +666,8 @@ bool CheckStore(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return false; if (!CheckDummy(S, OpPC, Ptr, AK_Assign)) return false; + if (!CheckLifetime(S, OpPC, Ptr, AK_Assign)) + return false; if (!CheckExtern(S, OpPC, Ptr)) return false; if (!CheckRange(S, OpPC, Ptr, AK_Assign)) @@ -1287,6 +1308,12 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func, const Pointer &ThisPtr = S.Stk.peek(ThisOffset); + // C++23 [expr.const]p5.6 + // an invocation of a virtual function ([class.virtual]) for an object whose + // dynamic type is constexpr-unknown; + if (ThisPtr.isDummy() && Func->isVirtual()) + return false; + // If the current function is a lambda static invoker and // the function we're about to call is a lambda call operator, // skip the CheckInvoke, since the ThisPtr is a null pointer @@ -1537,34 +1564,38 @@ bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E, bool InvalidNewDeleteExpr(InterpState &S, CodePtr OpPC, const Expr *E) { assert(E); - if (S.getLangOpts().CPlusPlus26) - return true; - - const auto &Loc = S.Current->getSource(OpPC); - if (const auto *NewExpr = dyn_cast(E)) { const FunctionDecl *OperatorNew = NewExpr->getOperatorNew(); - if (!S.getLangOpts().CPlusPlus26 && NewExpr->getNumPlacementArgs() > 0) { + if (NewExpr->getNumPlacementArgs() > 0) { // This is allowed pre-C++26, but only an std function. - if (S.Current->isStdFunction()) + if (S.getLangOpts().CPlusPlus26 || S.Current->isStdFunction()) return true; - S.FFDiag(Loc, diag::note_constexpr_new_placement) + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_placement) << /*C++26 feature*/ 1 << E->getSourceRange(); - } else if (NewExpr->getNumPlacementArgs() == 1 && - !OperatorNew->isReservedGlobalPlacementOperator()) { - S.FFDiag(Loc, diag::note_constexpr_new_placement) - << /*Unsupported*/ 0 << E->getSourceRange(); } else if (!OperatorNew->isReplaceableGlobalAllocationFunction()) { - S.FFDiag(Loc, diag::note_constexpr_new_non_replaceable) + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_new_non_replaceable) << isa(OperatorNew) << OperatorNew; + return false; + } else if (!S.getLangOpts().CPlusPlus26 && + NewExpr->getNumPlacementArgs() == 1 && + !OperatorNew->isReservedGlobalPlacementOperator()) { + if (!S.getLangOpts().CPlusPlus26) { + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_new_placement) + << /*Unsupported*/ 0 << E->getSourceRange(); + return false; + } + return true; } } else { const auto *DeleteExpr = cast(E); const FunctionDecl *OperatorDelete = DeleteExpr->getOperatorDelete(); if (!OperatorDelete->isReplaceableGlobalAllocationFunction()) { - S.FFDiag(Loc, diag::note_constexpr_new_non_replaceable) + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_new_non_replaceable) << isa(OperatorDelete) << OperatorDelete; + return false; } } @@ -1661,17 +1692,6 @@ bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType) { if (!P.isBlockPointer()) return false; - if (P.isDummy()) { - QualType StarThisType = - S.getASTContext().getLValueReferenceType(P.getType()); - S.FFDiag(S.Current->getSource(OpPC), - diag::note_constexpr_polymorphic_unknown_dynamic_type) - << AK_TypeId - << P.toAPValue(S.getASTContext()) - .getAsString(S.getASTContext(), StarThisType); - return false; - } - S.Stk.push(P.getType().getTypePtr(), TypeInfoType); return true; } diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 063970afec9e3..5cc371c7ee495 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -325,11 +325,11 @@ bool Ret(InterpState &S, CodePtr &PC) { if (InterpFrame *Caller = S.Current->Caller) { PC = S.Current->getRetPC(); - delete S.Current; + InterpFrame::free(S.Current); S.Current = Caller; S.Stk.push(Ret); } else { - delete S.Current; + InterpFrame::free(S.Current); S.Current = nullptr; // The topmost frame should come from an EvalEmitter, // which has its own implementation of the Ret<> instruction. @@ -345,10 +345,10 @@ inline bool RetVoid(InterpState &S, CodePtr &PC) { if (InterpFrame *Caller = S.Current->Caller) { PC = S.Current->getRetPC(); - delete S.Current; + InterpFrame::free(S.Current); S.Current = Caller; } else { - delete S.Current; + InterpFrame::free(S.Current); S.Current = nullptr; } return true; @@ -379,15 +379,14 @@ bool AddSubMulHelper(InterpState &S, CodePtr OpPC, unsigned Bits, const T &LHS, APSInt Value = OpAP()(LHS.toAPSInt(Bits), RHS.toAPSInt(Bits)); // Report undefined behaviour, stopping if required. - const Expr *E = S.Current->getExpr(OpPC); - QualType Type = E->getType(); if (S.checkingForUndefinedBehavior()) { + const Expr *E = S.Current->getExpr(OpPC); + QualType Type = E->getType(); SmallString<32> Trunc; Value.trunc(Result.bitWidth()) .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false, /*UpperCase=*/true, /*InsertSeparators=*/true); - auto Loc = E->getExprLoc(); - S.report(Loc, diag::warn_integer_constant_overflow) + S.report(E->getExprLoc(), diag::warn_integer_constant_overflow) << Trunc << Type << E->getSourceRange(); } @@ -737,16 +736,14 @@ bool Neg(InterpState &S, CodePtr OpPC) { S.Stk.push(Result); APSInt NegatedValue = -Value.toAPSInt(Value.bitWidth() + 1); - const Expr *E = S.Current->getExpr(OpPC); - QualType Type = E->getType(); - if (S.checkingForUndefinedBehavior()) { + const Expr *E = S.Current->getExpr(OpPC); + QualType Type = E->getType(); SmallString<32> Trunc; NegatedValue.trunc(Result.bitWidth()) .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false, /*UpperCase=*/true, /*InsertSeparators=*/true); - auto Loc = E->getExprLoc(); - S.report(Loc, diag::warn_integer_constant_overflow) + S.report(E->getExprLoc(), diag::warn_integer_constant_overflow) << Trunc << Type << E->getSourceRange(); return true; } @@ -800,15 +797,14 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { APResult = --Value.toAPSInt(Bits); // Report undefined behaviour, stopping if required. - const Expr *E = S.Current->getExpr(OpPC); - QualType Type = E->getType(); if (S.checkingForUndefinedBehavior()) { + const Expr *E = S.Current->getExpr(OpPC); + QualType Type = E->getType(); SmallString<32> Trunc; APResult.trunc(Result.bitWidth()) .toString(Trunc, 10, Result.isSigned(), /*formatAsCLiteral=*/false, /*UpperCase=*/true, /*InsertSeparators=*/true); - auto Loc = E->getExprLoc(); - S.report(Loc, diag::warn_integer_constant_overflow) + S.report(E->getExprLoc(), diag::warn_integer_constant_overflow) << Trunc << Type << E->getSourceRange(); return true; } @@ -1258,6 +1254,12 @@ bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I) { return true; } +static inline bool Kill(InterpState &S, CodePtr OpPC) { + const auto &Ptr = S.Stk.pop(); + Ptr.endLifetime(); + return true; +} + /// 1) Pops the value from the stack. /// 2) Writes the value to the local variable with the /// given offset. @@ -1482,7 +1484,10 @@ bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F, template ::T> bool InitField(InterpState &S, CodePtr OpPC, uint32_t I) { const T &Value = S.Stk.pop(); - const Pointer &Field = S.Stk.peek().atField(I); + const Pointer &Ptr = S.Stk.peek(); + if (!CheckRange(S, OpPC, Ptr, CSK_Field)) + return false; + const Pointer &Field = Ptr.atField(I); Field.deref() = Value; Field.activate(); Field.initialize(); diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index e657dbd2f9c73..0e586725b5869 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -1538,9 +1538,12 @@ static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC, if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() || ArgType->isAnyComplexType() || ArgType->isPointerType() || ArgType->isNullPtrType()) { + auto PrevDiags = S.getEvalStatus().Diag; + S.getEvalStatus().Diag = nullptr; InterpStack Stk; Compiler C(S.Ctx, S.P, S, Stk); auto Res = C.interpretExpr(Arg, /*ConvertResultToRValue=*/Arg->isGLValue()); + S.getEvalStatus().Diag = PrevDiags; if (Res.isInvalid()) { C.cleanup(); Stk.clear(); diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp index 20f67d9b1fd42..c383b2bc7f95c 100644 --- a/clang/lib/AST/ByteCode/InterpFrame.cpp +++ b/clang/lib/AST/ByteCode/InterpFrame.cpp @@ -23,11 +23,15 @@ using namespace clang; using namespace clang::interp; +InterpFrame::InterpFrame(InterpState &S) + : Caller(nullptr), S(S), Depth(0), Func(nullptr), RetPC(CodePtr()), + ArgSize(0), Args(nullptr), FrameOffset(0), IsBottom(true) {} + InterpFrame::InterpFrame(InterpState &S, const Function *Func, InterpFrame *Caller, CodePtr RetPC, unsigned ArgSize) : Caller(Caller), S(S), Depth(Caller ? Caller->Depth + 1 : 0), Func(Func), RetPC(RetPC), ArgSize(ArgSize), Args(static_cast(S.Stk.top())), - FrameOffset(S.Stk.size()) { + FrameOffset(S.Stk.size()), IsBottom(!Caller) { if (!Func) return; @@ -73,11 +77,15 @@ InterpFrame::~InterpFrame() { // When destroying the InterpFrame, call the Dtor for all block // that haven't been destroyed via a destroy() op yet. // This happens when the execution is interruped midway-through. - if (Func) { - for (auto &Scope : Func->scopes()) { - for (auto &Local : Scope.locals()) { - S.deallocate(localBlock(Local.Offset)); - } + destroyScopes(); +} + +void InterpFrame::destroyScopes() { + if (!Func) + return; + for (auto &Scope : Func->scopes()) { + for (auto &Local : Scope.locals()) { + S.deallocate(localBlock(Local.Offset)); } } } @@ -91,7 +99,7 @@ void InterpFrame::initScope(unsigned Idx) { } void InterpFrame::destroy(unsigned Idx) { - for (auto &Local : Func->getScope(Idx).locals()) { + for (auto &Local : Func->getScope(Idx).locals_reverse()) { S.deallocate(localBlock(Local.Offset)); } } @@ -244,7 +252,7 @@ SourceInfo InterpFrame::getSource(CodePtr PC) const { const Expr *InterpFrame::getExpr(CodePtr PC) const { if (Func && !funcHasUsableBody(Func) && Caller) - return Caller->getExpr(PC); + return Caller->getExpr(RetPC); return S.getExpr(Func, PC); } diff --git a/clang/lib/AST/ByteCode/InterpFrame.h b/clang/lib/AST/ByteCode/InterpFrame.h index 7cfc3ac68b4f3..360e6bff12327 100644 --- a/clang/lib/AST/ByteCode/InterpFrame.h +++ b/clang/lib/AST/ByteCode/InterpFrame.h @@ -28,6 +28,9 @@ class InterpFrame final : public Frame { /// The frame of the previous function. InterpFrame *Caller; + /// Bottom Frame. + InterpFrame(InterpState &S); + /// Creates a new frame for a method call. InterpFrame(InterpState &S, const Function *Func, InterpFrame *Caller, CodePtr RetPC, unsigned ArgSize); @@ -42,9 +45,15 @@ class InterpFrame final : public Frame { /// Destroys the frame, killing all live pointers to stack slots. ~InterpFrame(); + static void free(InterpFrame *F) { + if (!F->isBottomFrame()) + delete F; + } + /// Invokes the destructors for a scope. void destroy(unsigned Idx); void initScope(unsigned Idx); + void destroyScopes(); /// Describes the frame with arguments for diagnostic purposes. void describe(llvm::raw_ostream &OS) const override; @@ -119,6 +128,8 @@ class InterpFrame final : public Frame { bool isStdFunction() const; + bool isBottomFrame() const { return IsBottom; } + void dump() const { dump(llvm::errs(), 0); } void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const; @@ -167,6 +178,7 @@ class InterpFrame final : public Frame { const size_t FrameOffset; /// Mapping from arg offsets to their argument blocks. llvm::DenseMap> Params; + bool IsBottom = false; }; } // namespace interp diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp index 287c3bd3bca3a..70a2e9b62fc3a 100644 --- a/clang/lib/AST/ByteCode/InterpState.cpp +++ b/clang/lib/AST/ByteCode/InterpState.cpp @@ -17,7 +17,14 @@ using namespace clang::interp; InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx, SourceMapper *M) - : Parent(Parent), M(M), P(P), Stk(Stk), Ctx(Ctx), Current(nullptr) {} + : Parent(Parent), M(M), P(P), Stk(Stk), Ctx(Ctx), BottomFrame(*this), + Current(&BottomFrame) {} + +InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk, + Context &Ctx, const Function *Func) + : Parent(Parent), M(nullptr), P(P), Stk(Stk), Ctx(Ctx), + BottomFrame(*this, Func, nullptr, CodePtr(), Func->getArgSize()), + Current(&BottomFrame) {} bool InterpState::inConstantContext() const { if (ConstantContextOverride) @@ -27,11 +34,12 @@ bool InterpState::inConstantContext() const { } InterpState::~InterpState() { - while (Current) { + while (Current && !Current->isBottomFrame()) { InterpFrame *Next = Current->Caller; delete Current; Current = Next; } + BottomFrame.destroyScopes(); while (DeadBlocks) { DeadBlock *Next = DeadBlocks->Next; diff --git a/clang/lib/AST/ByteCode/InterpState.h b/clang/lib/AST/ByteCode/InterpState.h index 2a1311c86a2f2..d6adfff1a713a 100644 --- a/clang/lib/AST/ByteCode/InterpState.h +++ b/clang/lib/AST/ByteCode/InterpState.h @@ -37,6 +37,8 @@ class InterpState final : public State, public SourceMapper { public: InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx, SourceMapper *M = nullptr); + InterpState(State &Parent, Program &P, InterpStack &Stk, Context &Ctx, + const Function *Func); ~InterpState(); @@ -134,6 +136,8 @@ class InterpState final : public State, public SourceMapper { InterpStack &Stk; /// Interpreter Context. Context &Ctx; + /// Bottom function frame. + InterpFrame BottomFrame; /// The current frame. InterpFrame *Current = nullptr; /// Source location of the evaluating expression diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 4b0c902ab2926..088a3e40fe2a7 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -394,6 +394,11 @@ def GetLocal : AccessOpcode { let HasCustomEval = 1; } // [] -> [Pointer] def SetLocal : AccessOpcode { let HasCustomEval = 1; } +def Kill : Opcode { + let Types = []; + let Args = []; +} + def CheckDecl : Opcode { let Args = [ArgVarDecl]; } diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index ec4756fe4f87d..3033bd47adf75 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -209,6 +209,10 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { return ASTCtx.toCharUnitsFromBits(Layout.getFieldOffset(FieldIndex)); }; + bool UsePath = true; + if (getType()->isLValueReferenceType()) + UsePath = false; + // Build the path into the object. Pointer Ptr = *this; while (Ptr.isField() || Ptr.isArrayElement()) { @@ -217,38 +221,42 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { // An array root may still be an array element itself. if (Ptr.isArrayElement()) { Ptr = Ptr.expand(); + const Descriptor *Desc = Ptr.getFieldDesc(); unsigned Index = Ptr.getIndex(); - Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index)); - QualType ElemType = Ptr.getFieldDesc()->getElemQualType(); + QualType ElemType = Desc->getElemQualType(); Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType)); + if (Ptr.getArray().getType()->isArrayType()) + Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index)); Ptr = Ptr.getArray(); } else { - Path.push_back(APValue::LValuePathEntry( - {Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false})); + const Descriptor *Desc = Ptr.getFieldDesc(); + const auto *Dcl = Desc->asDecl(); + Path.push_back(APValue::LValuePathEntry({Dcl, /*IsVirtual=*/false})); - if (const auto *FD = - dyn_cast_if_present(Ptr.getFieldDesc()->asDecl())) + if (const auto *FD = dyn_cast_if_present(Dcl)) Offset += getFieldOffset(FD); Ptr = Ptr.getBase(); } } else if (Ptr.isArrayElement()) { Ptr = Ptr.expand(); + const Descriptor *Desc = Ptr.getFieldDesc(); unsigned Index; if (Ptr.isOnePastEnd()) Index = Ptr.getArray().getNumElems(); else Index = Ptr.getIndex(); - QualType ElemType = Ptr.getFieldDesc()->getElemQualType(); + QualType ElemType = Desc->getElemQualType(); Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType)); - Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index)); + if (Ptr.getArray().getType()->isArrayType()) + Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index)); Ptr = Ptr.getArray(); } else { + const Descriptor *Desc = Ptr.getFieldDesc(); bool IsVirtual = false; // Create a path entry for the field. - const Descriptor *Desc = Ptr.getFieldDesc(); if (const auto *BaseOrMember = Desc->asDecl()) { if (const auto *FD = dyn_cast(BaseOrMember)) { Ptr = Ptr.getBase(); @@ -281,8 +289,11 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { // Just invert the order of the elements. std::reverse(Path.begin(), Path.end()); - return APValue(Base, Offset, Path, /*IsOnePastEnd=*/isOnePastEnd(), - /*IsNullPtr=*/false); + if (UsePath) + return APValue(Base, Offset, Path, + /*IsOnePastEnd=*/!isElementPastEnd() && isOnePastEnd()); + + return APValue(Base, Offset, APValue::NoLValuePath()); } void Pointer::print(llvm::raw_ostream &OS) const { diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index ef03c12e86c10..3970d5833fcdc 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -630,8 +630,7 @@ class Pointer { if (isUnknownSizeArray()) return false; - return isElementPastEnd() || isPastEnd() || - (getSize() == getOffset() && !isZeroSizeArray()); + return isPastEnd() || (getSize() == getOffset() && !isZeroSizeArray()); } /// Checks if the pointer points past the end of the object. @@ -688,6 +687,22 @@ class Pointer { /// Deactivates an entire strurcutre. void deactivate() const; + Lifetime getLifetime() const { + if (!isBlockPointer()) + return Lifetime::Started; + if (asBlockPointer().Base < sizeof(InlineDescriptor)) + return Lifetime::Started; + return getInlineDesc()->LifeState; + } + + void endLifetime() const { + if (!isBlockPointer()) + return; + if (asBlockPointer().Base < sizeof(InlineDescriptor)) + return; + getInlineDesc()->LifeState = Lifetime::Ended; + } + /// Compare two pointers. ComparisonCategoryResult compare(const Pointer &Other) const { if (!hasSameBase(*this, Other)) diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index 7d8862d606ba3..833c9ef88d770 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -18,14 +18,12 @@ using namespace clang; using namespace clang::interp; unsigned Program::getOrCreateNativePointer(const void *Ptr) { - auto It = NativePointerIndices.find(Ptr); - if (It != NativePointerIndices.end()) - return It->second; + auto [It, Inserted] = + NativePointerIndices.try_emplace(Ptr, NativePointers.size()); + if (Inserted) + NativePointers.push_back(Ptr); - unsigned Idx = NativePointers.size(); - NativePointers.push_back(Ptr); - NativePointerIndices[Ptr] = Idx; - return Idx; + return It->second; } const void *Program::getNativePointer(unsigned Idx) { @@ -35,6 +33,7 @@ const void *Program::getNativePointer(unsigned Idx) { unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) { const size_t CharWidth = S->getCharByteWidth(); const size_t BitWidth = CharWidth * Ctx.getCharBit(); + unsigned StringLength = S->getLength(); PrimType CharType; switch (CharWidth) { @@ -55,15 +54,15 @@ unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) { Base = S; // Create a descriptor for the string. - Descriptor *Desc = allocateDescriptor(Base, CharType, Descriptor::GlobalMD, - S->getLength() + 1, - /*isConst=*/true, - /*isTemporary=*/false, - /*isMutable=*/false); + Descriptor *Desc = + allocateDescriptor(Base, CharType, Descriptor::GlobalMD, StringLength + 1, + /*isConst=*/true, + /*isTemporary=*/false, + /*isMutable=*/false); // Allocate storage for the string. // The byte length does not include the null terminator. - unsigned I = Globals.size(); + unsigned GlobalIndex = Globals.size(); unsigned Sz = Desc->getAllocSize(); auto *G = new (Allocator, Sz) Global(Ctx.getEvalID(), Desc, /*isStatic=*/true, /*isExtern=*/false); @@ -74,33 +73,32 @@ unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) { // Construct the string in storage. const Pointer Ptr(G->block()); - for (unsigned I = 0, N = S->getLength(); I <= N; ++I) { - Pointer Field = Ptr.atIndex(I).narrow(); - const uint32_t CodePoint = I == N ? 0 : S->getCodeUnit(I); + for (unsigned I = 0; I <= StringLength; ++I) { + Pointer Field = Ptr.atIndex(I); + const uint32_t CodePoint = I == StringLength ? 0 : S->getCodeUnit(I); switch (CharType) { case PT_Sint8: { using T = PrimConv::T; Field.deref() = T::from(CodePoint, BitWidth); - Field.initialize(); break; } case PT_Uint16: { using T = PrimConv::T; Field.deref() = T::from(CodePoint, BitWidth); - Field.initialize(); break; } case PT_Uint32: { using T = PrimConv::T; Field.deref() = T::from(CodePoint, BitWidth); - Field.initialize(); break; } default: llvm_unreachable("unsupported character type"); } } - return I; + Ptr.initialize(); + + return GlobalIndex; } Pointer Program::getPtrGlobal(unsigned Idx) const { @@ -453,15 +451,21 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty, // Complex types - represented as arrays of elements. if (const auto *CT = Ty->getAs()) { - PrimType ElemTy = *Ctx.classify(CT->getElementType()); - return allocateDescriptor(D, ElemTy, MDSize, 2, IsConst, IsTemporary, + std::optional ElemTy = Ctx.classify(CT->getElementType()); + if (!ElemTy) + return nullptr; + + return allocateDescriptor(D, *ElemTy, MDSize, 2, IsConst, IsTemporary, IsMutable); } // Same with vector types. if (const auto *VT = Ty->getAs()) { - PrimType ElemTy = *Ctx.classify(VT->getElementType()); - return allocateDescriptor(D, ElemTy, MDSize, VT->getNumElements(), IsConst, + std::optional ElemTy = Ctx.classify(VT->getElementType()); + if (!ElemTy) + return nullptr; + + return allocateDescriptor(D, *ElemTy, MDSize, VT->getNumElements(), IsConst, IsTemporary, IsMutable); } diff --git a/clang/lib/AST/CommentLexer.cpp b/clang/lib/AST/CommentLexer.cpp index ec9a5b480aa29..804be89a8d4dd 100644 --- a/clang/lib/AST/CommentLexer.cpp +++ b/clang/lib/AST/CommentLexer.cpp @@ -196,6 +196,15 @@ const char *skipWhitespace(const char *BufferPtr, const char *BufferEnd) { return BufferEnd; } +const char *skipHorizontalWhitespace(const char *BufferPtr, + const char *BufferEnd) { + for (; BufferPtr != BufferEnd; ++BufferPtr) { + if (!isHorizontalWhitespace(*BufferPtr)) + return BufferPtr; + } + return BufferEnd; +} + bool isWhitespace(const char *BufferPtr, const char *BufferEnd) { return skipWhitespace(BufferPtr, BufferEnd) == BufferEnd; } @@ -637,17 +646,41 @@ void Lexer::setupAndLexHTMLStartTag(Token &T) { formTokenWithChars(T, TagNameEnd, tok::html_start_tag); T.setHTMLTagStartName(Name); - BufferPtr = skipWhitespace(BufferPtr, CommentEnd); + BufferPtr = skipHorizontalWhitespace(BufferPtr, CommentEnd); + if (BufferPtr == CommentEnd) { // in BCPL comments + State = LS_HTMLStartTag; + return; + } const char C = *BufferPtr; if (BufferPtr != CommentEnd && - (C == '>' || C == '/' || isHTMLIdentifierStartingCharacter(C))) + (C == '>' || C == '/' || isVerticalWhitespace(C) || + isHTMLIdentifierStartingCharacter(C))) State = LS_HTMLStartTag; } void Lexer::lexHTMLStartTag(Token &T) { assert(State == LS_HTMLStartTag); + // Skip leading whitespace and comment decorations + while (isVerticalWhitespace(*BufferPtr)) { + BufferPtr = skipNewline(BufferPtr, CommentEnd); + + if (CommentState == LCS_InsideCComment) + skipLineStartingDecorations(); + + BufferPtr = skipHorizontalWhitespace(BufferPtr, CommentEnd); + if (BufferPtr == CommentEnd) { + // HTML starting tags must be defined in a single comment block. + // It's likely a user-error where they forgot to terminate the comment. + State = LS_Normal; + // Since at least one newline was skipped and one token needs to be lexed, + // return a newline. + formTokenWithChars(T, BufferPtr, tok::newline); + return; + } + } + const char *TokenPtr = BufferPtr; char C = *TokenPtr; if (isHTMLIdentifierCharacter(C)) { @@ -693,14 +726,13 @@ void Lexer::lexHTMLStartTag(Token &T) { // Now look ahead and return to normal state if we don't see any HTML tokens // ahead. - BufferPtr = skipWhitespace(BufferPtr, CommentEnd); + BufferPtr = skipHorizontalWhitespace(BufferPtr, CommentEnd); if (BufferPtr == CommentEnd) { - State = LS_Normal; return; } C = *BufferPtr; - if (!isHTMLIdentifierStartingCharacter(C) && + if (!isHTMLIdentifierStartingCharacter(C) && !isVerticalWhitespace(C) && C != '=' && C != '\"' && C != '\'' && C != '>' && C != '/') { State = LS_Normal; return; @@ -774,8 +806,17 @@ void Lexer::lex(Token &T) { BufferPtr++; CommentState = LCS_InsideBCPLComment; - if (State != LS_VerbatimBlockBody && State != LS_VerbatimBlockFirstLine) + switch (State) { + case LS_VerbatimBlockFirstLine: + case LS_VerbatimBlockBody: + break; + case LS_HTMLStartTag: + BufferPtr = skipHorizontalWhitespace(BufferPtr, BufferEnd); + break; + default: State = LS_Normal; + break; + } CommentEnd = findBCPLCommentEnd(BufferPtr, BufferEnd); goto again; } @@ -807,6 +848,14 @@ void Lexer::lex(Token &T) { while(EndWhitespace != BufferEnd && *EndWhitespace != '/') EndWhitespace++; + // When lexing the start of an HTML tag (i.e. going through the attributes) + // there won't be any newlines generated. + if (State == LS_HTMLStartTag && EndWhitespace != BufferEnd) { + CommentState = LCS_BeforeComment; + BufferPtr = EndWhitespace; + goto again; + } + // Turn any whitespace between comments (and there is only whitespace // between them -- guaranteed by comment extraction) into a newline. We // have two newlines between C comments in total (first one was synthesized @@ -829,6 +878,14 @@ void Lexer::lex(Token &T) { BufferPtr += 2; assert(BufferPtr <= BufferEnd); + // When lexing the start of an HTML tag (i.e. going through the + // attributes) there won't be any newlines generated - whitespace still + // needs to be skipped. + if (State == LS_HTMLStartTag && BufferPtr != BufferEnd) { + CommentState = LCS_BetweenComments; + goto again; + } + // Synthenize newline just after the C comment, regardless if there is // actually a newline. formTokenWithChars(T, BufferPtr, tok::newline); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 5ce03ce20d284..610207cf8b9a4 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2447,7 +2447,7 @@ bool VarDecl::isOutOfLine() const { } void VarDecl::setInit(Expr *I) { - if (auto *Eval = Init.dyn_cast()) { + if (auto *Eval = dyn_cast_if_present(Init)) { Eval->~EvaluatedStmt(); getASTContext().Deallocate(Eval); } @@ -2527,7 +2527,7 @@ bool VarDecl::isUsableInConstantExpressions(const ASTContext &Context) const { /// form, which contains extra information on the evaluated value of the /// initializer. EvaluatedStmt *VarDecl::ensureEvaluatedStmt() const { - auto *Eval = Init.dyn_cast(); + auto *Eval = dyn_cast_if_present(Init); if (!Eval) { // Note: EvaluatedStmt contains an APValue, which usually holds // resources not allocated from the ASTContext. We need to do some @@ -2541,7 +2541,7 @@ EvaluatedStmt *VarDecl::ensureEvaluatedStmt() const { } EvaluatedStmt *VarDecl::getEvaluatedStmt() const { - return Init.dyn_cast(); + return dyn_cast_if_present(Init); } APValue *VarDecl::evaluateValue() const { @@ -2659,10 +2659,6 @@ bool VarDecl::checkForConstantInitialization( return Eval->HasConstantInitialization; } -bool VarDecl::isParameterPack() const { - return isa(getType()); -} - template static DeclT *getDefinitionOrSelf(DeclT *D) { assert(D); @@ -2784,8 +2780,8 @@ SourceLocation VarDecl::getPointOfInstantiation() const { } VarTemplateDecl *VarDecl::getDescribedVarTemplate() const { - return getASTContext().getTemplateOrSpecializationInfo(this) - .dyn_cast(); + return dyn_cast_if_present( + getASTContext().getTemplateOrSpecializationInfo(this)); } void VarDecl::setDescribedVarTemplate(VarTemplateDecl *Template) { @@ -2875,8 +2871,8 @@ MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const { if (isStaticDataMember()) // FIXME: Remove ? // return getASTContext().getInstantiatedFromStaticDataMember(this); - return getASTContext().getTemplateOrSpecializationInfo(this) - .dyn_cast(); + return dyn_cast_if_present( + getASTContext().getTemplateOrSpecializationInfo(this)); return nullptr; } @@ -3069,6 +3065,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, FunctionDeclBits.IsIneligibleOrNotSelected = false; FunctionDeclBits.HasImplicitReturnZero = false; FunctionDeclBits.IsLateTemplateParsed = false; + FunctionDeclBits.IsInstantiatedFromMemberTemplate = false; FunctionDeclBits.ConstexprKind = static_cast(ConstexprKind); FunctionDeclBits.BodyContainsImmediateEscalatingExpression = false; FunctionDeclBits.InstantiationIsPending = false; @@ -3314,6 +3311,10 @@ bool FunctionDecl::isImmediateFunction() const { .getConstructor() ->isImmediateFunction(); + if (FunctionDecl *P = getTemplateInstantiationPattern(); + P && P->isImmediateFunction()) + return true; + if (const auto *MD = dyn_cast(this); MD && MD->isLambdaStaticInvoker()) return MD->getParent()->getLambdaCallOperator()->isImmediateFunction(); @@ -4040,11 +4041,11 @@ FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const { } MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const { - if (auto *MSI = - TemplateOrSpecialization.dyn_cast()) + if (auto *MSI = dyn_cast_if_present( + TemplateOrSpecialization)) return MSI; - if (auto *FTSI = TemplateOrSpecialization - .dyn_cast()) + if (auto *FTSI = dyn_cast_if_present( + TemplateOrSpecialization)) return FTSI->getMemberSpecializationInfo(); return nullptr; } @@ -4062,7 +4063,7 @@ FunctionDecl::setInstantiationOfMemberFunction(ASTContext &C, FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const { return dyn_cast_if_present( - TemplateOrSpecialization.dyn_cast()); + dyn_cast_if_present(TemplateOrSpecialization)); } void FunctionDecl::setDescribedFunctionTemplate( @@ -4181,9 +4182,9 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const { } FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { - if (FunctionTemplateSpecializationInfo *Info - = TemplateOrSpecialization - .dyn_cast()) { + if (FunctionTemplateSpecializationInfo *Info = + dyn_cast_if_present( + TemplateOrSpecialization)) { return Info->getTemplate(); } return nullptr; @@ -4191,15 +4192,15 @@ FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { FunctionTemplateSpecializationInfo * FunctionDecl::getTemplateSpecializationInfo() const { - return TemplateOrSpecialization - .dyn_cast(); + return dyn_cast_if_present( + TemplateOrSpecialization); } const TemplateArgumentList * FunctionDecl::getTemplateSpecializationArgs() const { - if (FunctionTemplateSpecializationInfo *Info - = TemplateOrSpecialization - .dyn_cast()) { + if (FunctionTemplateSpecializationInfo *Info = + dyn_cast_if_present( + TemplateOrSpecialization)) { return Info->TemplateArguments; } return nullptr; @@ -4207,14 +4208,14 @@ FunctionDecl::getTemplateSpecializationArgs() const { const ASTTemplateArgumentListInfo * FunctionDecl::getTemplateSpecializationArgsAsWritten() const { - if (FunctionTemplateSpecializationInfo *Info - = TemplateOrSpecialization - .dyn_cast()) { + if (FunctionTemplateSpecializationInfo *Info = + dyn_cast_if_present( + TemplateOrSpecialization)) { return Info->TemplateArgumentsAsWritten; } if (DependentFunctionTemplateSpecializationInfo *Info = - TemplateOrSpecialization - .dyn_cast()) { + dyn_cast_if_present( + TemplateOrSpecialization)) { return Info->TemplateArgumentsAsWritten; } return nullptr; @@ -4239,7 +4240,8 @@ void FunctionDecl::setFunctionTemplateSpecialization( FunctionTemplateSpecializationInfo::Create( C, this, Template, TSK, TemplateArgs, TemplateArgsAsWritten, PointOfInstantiation, - TemplateOrSpecialization.dyn_cast()); + dyn_cast_if_present( + TemplateOrSpecialization)); TemplateOrSpecialization = Info; Template->addSpecialization(Info, InsertPos); } @@ -4256,8 +4258,8 @@ void FunctionDecl::setDependentTemplateSpecialization( DependentFunctionTemplateSpecializationInfo * FunctionDecl::getDependentSpecializationInfo() const { - return TemplateOrSpecialization - .dyn_cast(); + return dyn_cast_if_present( + TemplateOrSpecialization); } DependentFunctionTemplateSpecializationInfo * @@ -4288,12 +4290,13 @@ TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const { // For a function template specialization, query the specialization // information object. if (FunctionTemplateSpecializationInfo *FTSInfo = - TemplateOrSpecialization - .dyn_cast()) + dyn_cast_if_present( + TemplateOrSpecialization)) return FTSInfo->getTemplateSpecializationKind(); if (MemberSpecializationInfo *MSInfo = - TemplateOrSpecialization.dyn_cast()) + dyn_cast_if_present( + TemplateOrSpecialization)) return MSInfo->getTemplateSpecializationKind(); // A dependent function template specialization is an explicit specialization, @@ -4331,15 +4334,16 @@ FunctionDecl::getTemplateSpecializationKindForInstantiation() const { // of A::f, and that A::f should be implicitly instantiated // from A::f if a definition is needed. if (FunctionTemplateSpecializationInfo *FTSInfo = - TemplateOrSpecialization - .dyn_cast()) { + dyn_cast_if_present( + TemplateOrSpecialization)) { if (auto *MSInfo = FTSInfo->getMemberSpecializationInfo()) return MSInfo->getTemplateSpecializationKind(); return FTSInfo->getTemplateSpecializationKind(); } if (MemberSpecializationInfo *MSInfo = - TemplateOrSpecialization.dyn_cast()) + dyn_cast_if_present( + TemplateOrSpecialization)) return MSInfo->getTemplateSpecializationKind(); if (isa( @@ -4353,9 +4357,9 @@ FunctionDecl::getTemplateSpecializationKindForInstantiation() const { void FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation) { - if (FunctionTemplateSpecializationInfo *FTSInfo - = TemplateOrSpecialization.dyn_cast< - FunctionTemplateSpecializationInfo*>()) { + if (FunctionTemplateSpecializationInfo *FTSInfo = + dyn_cast( + TemplateOrSpecialization)) { FTSInfo->setTemplateSpecializationKind(TSK); if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() && @@ -4364,8 +4368,9 @@ FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, if (ASTMutationListener *L = getASTContext().getASTMutationListener()) L->InstantiationRequested(this); } - } else if (MemberSpecializationInfo *MSInfo - = TemplateOrSpecialization.dyn_cast()) { + } else if (MemberSpecializationInfo *MSInfo = + dyn_cast( + TemplateOrSpecialization)) { MSInfo->setTemplateSpecializationKind(TSK); if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() && @@ -5412,6 +5417,13 @@ bool ValueDecl::isInitCapture() const { return false; } +bool ValueDecl::isParameterPack() const { + if (const auto *NTTP = dyn_cast(this)) + return NTTP->isParameterPack(); + + return isa_and_nonnull(getType().getTypePtrOrNull()); +} + void ImplicitParamDecl::anchor() {} ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, @@ -5837,3 +5849,17 @@ bool clang::IsArmStreamingFunction(const FunctionDecl *FD, return false; } + +bool clang::hasArmZAState(const FunctionDecl *FD) { + const auto *T = FD->getType()->getAs(); + return (T && FunctionType::getArmZAState(T->getAArch64SMEAttributes()) != + FunctionType::ARM_None) || + (FD->hasAttr() && FD->getAttr()->isNewZA()); +} + +bool clang::hasArmZT0State(const FunctionDecl *FD) { + const auto *T = FD->getType()->getAs(); + return (T && FunctionType::getArmZT0State(T->getAArch64SMEAttributes()) != + FunctionType::ARM_None) || + (FD->hasAttr() && FD->getAttr()->isNewZT0()); +} diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 8506b95f761fe..fc16448cf9e90 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -245,7 +245,7 @@ bool Decl::isTemplateParameterPack() const { } bool Decl::isParameterPack() const { - if (const auto *Var = dyn_cast(this)) + if (const auto *Var = dyn_cast(this)) return Var->isParameterPack(); return isTemplateParameterPack(); @@ -1203,6 +1203,8 @@ const FunctionType *Decl::getFunctionType(bool BlocksToo) const { if (Ty->isFunctionPointerType()) Ty = Ty->castAs()->getPointeeType(); + else if (Ty->isMemberFunctionPointerType()) + Ty = Ty->castAs()->getPointeeType(); else if (Ty->isFunctionReferenceType()) Ty = Ty->castAs()->getPointeeType(); else if (BlocksToo && Ty->isBlockPointerType()) diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 44f45898fb483..e394e0515e599 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1987,7 +1987,8 @@ CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const { } MemberSpecializationInfo *CXXRecordDecl::getMemberSpecializationInfo() const { - return TemplateOrInstantiation.dyn_cast(); + return dyn_cast_if_present( + TemplateOrInstantiation); } void @@ -2001,7 +2002,7 @@ CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD, } ClassTemplateDecl *CXXRecordDecl::getDescribedClassTemplate() const { - return TemplateOrInstantiation.dyn_cast(); + return dyn_cast_if_present(TemplateOrInstantiation); } void CXXRecordDecl::setDescribedClassTemplate(ClassTemplateDecl *Template) { @@ -2045,7 +2046,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { // specialization from which it was instantiated. if (auto *TD = dyn_cast(this)) { auto From = TD->getInstantiatedFrom(); - if (auto *CTD = From.dyn_cast()) { + if (auto *CTD = dyn_cast_if_present(From)) { while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) { if (NewCTD->isMemberSpecialization()) break; @@ -2054,7 +2055,8 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { return GetDefinitionOrSelf(CTD->getTemplatedDecl()); } if (auto *CTPSD = - From.dyn_cast()) { + dyn_cast_if_present( + From)) { while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) { if (NewCTPSD->isMemberSpecialization()) break; @@ -2290,18 +2292,22 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( ASTContext &C, DeclContext *DC, SourceLocation StartLoc, ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, SourceLocation EndLocation, CXXConstructorDecl *Ctor, - DeductionCandidate Kind, Expr *TrailingRequiresClause) { - return new (C, DC) - CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T, TInfo, - EndLocation, Ctor, Kind, TrailingRequiresClause); + DeductionCandidate Kind, Expr *TrailingRequiresClause, + const CXXDeductionGuideDecl *GeneratedFrom, + SourceDeductionGuideKind SourceKind) { + return new (C, DC) CXXDeductionGuideDecl( + C, DC, StartLoc, ES, NameInfo, T, TInfo, EndLocation, Ctor, Kind, + TrailingRequiresClause, GeneratedFrom, SourceKind); } CXXDeductionGuideDecl * CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) CXXDeductionGuideDecl( - C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), - QualType(), nullptr, SourceLocation(), nullptr, - DeductionCandidate::Normal, nullptr); + C, /*DC=*/nullptr, SourceLocation(), ExplicitSpecifier(), + DeclarationNameInfo(), QualType(), /*TInfo=*/nullptr, SourceLocation(), + /*Ctor=*/nullptr, DeductionCandidate::Normal, + /*TrailingRequiresClause=*/nullptr, + /*GeneratedFrom=*/nullptr, SourceDeductionGuideKind::None); } RequiresExprBodyDecl *RequiresExprBodyDecl::Create( @@ -3456,19 +3462,21 @@ VarDecl *ValueDecl::getPotentiallyDecomposedVarDecl() { if (auto *Var = llvm::dyn_cast(this)) return Var; if (auto *BD = llvm::dyn_cast(this)) - return llvm::dyn_cast(BD->getDecomposedDecl()); + return llvm::dyn_cast_if_present(BD->getDecomposedDecl()); return nullptr; } void BindingDecl::anchor() {} BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation IdLoc, IdentifierInfo *Id) { - return new (C, DC) BindingDecl(DC, IdLoc, Id); + SourceLocation IdLoc, IdentifierInfo *Id, + QualType T) { + return new (C, DC) BindingDecl(DC, IdLoc, Id, T); } BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { - return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); + return new (C, ID) + BindingDecl(nullptr, SourceLocation(), nullptr, QualType()); } VarDecl *BindingDecl::getHoldingVar() const { @@ -3484,6 +3492,12 @@ VarDecl *BindingDecl::getHoldingVar() const { return VD; } +llvm::ArrayRef BindingDecl::getBindingPackExprs() const { + assert(Binding && "expecting a pack expr"); + auto *RP = cast(Binding); + return RP->getExprs(); +} + void DecompositionDecl::anchor() {} DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 40ee3753c2422..7fb89bf5b499f 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -957,18 +957,17 @@ FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create( // ClassTemplateSpecializationDecl Implementation //===----------------------------------------------------------------------===// -ClassTemplateSpecializationDecl:: -ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, - DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, - ClassTemplateDecl *SpecializedTemplate, - ArrayRef Args, - ClassTemplateSpecializationDecl *PrevDecl) +ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl( + ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, + bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl) : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), PrevDecl), - SpecializedTemplate(SpecializedTemplate), - TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), - SpecializationKind(TSK_Undeclared) { + SpecializedTemplate(SpecializedTemplate), + TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), + SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) { + assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false); } ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, @@ -977,18 +976,14 @@ ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, SourceLocation(), nullptr, nullptr), SpecializationKind(TSK_Undeclared) {} -ClassTemplateSpecializationDecl * -ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, - DeclContext *DC, - SourceLocation StartLoc, - SourceLocation IdLoc, - ClassTemplateDecl *SpecializedTemplate, - ArrayRef Args, - ClassTemplateSpecializationDecl *PrevDecl) { - auto *Result = - new (Context, DC) ClassTemplateSpecializationDecl( - Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, - SpecializedTemplate, Args, PrevDecl); +ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create( + ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, + ArrayRef Args, bool StrictPackMatch, + ClassTemplateSpecializationDecl *PrevDecl) { + auto *Result = new (Context, DC) ClassTemplateSpecializationDecl( + Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, + SpecializedTemplate, Args, StrictPackMatch, PrevDecl); Result->setMayHaveOutOfDateDef(false); // If the template decl is incomplete, copy the external lexical storage from @@ -1049,7 +1044,7 @@ ClassTemplateSpecializationDecl::getSourceRange() const { assert(!Pattern.isNull() && "Class template specialization without pattern?"); if (const auto *CTPSD = - Pattern.dyn_cast()) + dyn_cast(Pattern)) return CTPSD->getSourceRange(); return cast(Pattern)->getSourceRange(); } @@ -1077,7 +1072,7 @@ ClassTemplateSpecializationDecl::getSourceRange() const { } void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast(); + auto *Info = dyn_cast_if_present(ExplicitInfo); if (!Info) { // Don't allocate if the location is invalid. if (Loc.isInvalid()) @@ -1091,7 +1086,7 @@ void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { void ClassTemplateSpecializationDecl::setTemplateKeywordLoc( SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast(); + auto *Info = dyn_cast_if_present(ExplicitInfo); if (!Info) { // Don't allocate if the location is invalid. if (Loc.isInvalid()) @@ -1175,7 +1170,9 @@ ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *PrevDecl) : ClassTemplateSpecializationDecl( Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc, - SpecializedTemplate, Args, PrevDecl), + // Tracking StrictPackMatch for Partial + // Specializations is not needed. + SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl), TemplateParams(Params), InstantiatedFromMember(nullptr, false) { if (AdoptTemplateParameterList(Params, this)) setInvalidDecl(); @@ -1463,7 +1460,7 @@ SourceRange VarTemplateSpecializationDecl::getSourceRange() const { assert(!Pattern.isNull() && "Variable template specialization without pattern?"); if (const auto *VTPSD = - Pattern.dyn_cast()) + dyn_cast(Pattern)) return VTPSD->getSourceRange(); VarTemplateDecl *VTD = cast(Pattern); if (hasInit()) { @@ -1496,7 +1493,7 @@ SourceRange VarTemplateSpecializationDecl::getSourceRange() const { } void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast(); + auto *Info = dyn_cast_if_present(ExplicitInfo); if (!Info) { // Don't allocate if the location is invalid. if (Loc.isInvalid()) @@ -1509,7 +1506,7 @@ void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { } void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast(); + auto *Info = dyn_cast_if_present(ExplicitInfo); if (!Info) { // Don't allocate if the location is invalid. if (Loc.isInvalid()) @@ -1773,7 +1770,7 @@ TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) { const auto *CTSD = cast(D); auto P = CTSD->getSpecializedTemplateOrPartial(); if (const auto *CTPSD = - P.dyn_cast()) + dyn_cast(P)) return CTPSD->getTemplateParameters(); return cast(P)->getTemplateParameters(); } @@ -1801,8 +1798,7 @@ TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) { case Decl::Kind::VarTemplateSpecialization: { const auto *VTSD = cast(D); auto P = VTSD->getSpecializedTemplateOrPartial(); - if (const auto *VTPSD = - P.dyn_cast()) + if (const auto *VTPSD = dyn_cast(P)) return VTPSD->getTemplateParameters(); return cast(P)->getTemplateParameters(); } diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp index 8cfabd9f3e93f..b478e7a39ea18 100644 --- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp +++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp @@ -89,9 +89,9 @@ using namespace clang; // // End result: RAV::TraverseCallExpr() is executed, namespace { -struct Impl : RecursiveASTVisitor { - DynamicRecursiveASTVisitor &Visitor; - Impl(DynamicRecursiveASTVisitor &Visitor) : Visitor(Visitor) {} +template struct Impl : RecursiveASTVisitor> { + DynamicRecursiveASTVisitorBase &Visitor; + Impl(DynamicRecursiveASTVisitorBase &Visitor) : Visitor(Visitor) {} bool shouldVisitTemplateInstantiations() const { return Visitor.ShouldVisitTemplateInstantiations; @@ -189,8 +189,10 @@ struct Impl : RecursiveASTVisitor { // TraverseStmt() always passes in a queue, so we have no choice but to // accept it as a parameter here. - bool dataTraverseNode(Stmt *S, DataRecursionQueue * = nullptr) { - // But since don't support postorder traversal, we don't need it, so + bool dataTraverseNode( + Stmt *S, + typename RecursiveASTVisitor::DataRecursionQueue * = nullptr) { + // But since we don't support postorder traversal, we don't need it, so // simply discard it here. This way, derived classes don't need to worry // about including it as a parameter that they never use. return Visitor.dataTraverseNode(S); @@ -266,187 +268,106 @@ struct Impl : RecursiveASTVisitor { }; } // namespace -void DynamicRecursiveASTVisitor::anchor() {} - -bool DynamicRecursiveASTVisitor::TraverseAST(ASTContext &AST) { - return Impl(*this).RecursiveASTVisitor::TraverseAST(AST); -} - -bool DynamicRecursiveASTVisitor::TraverseAttr(Attr *At) { - return Impl(*this).RecursiveASTVisitor::TraverseAttr(At); -} - -bool DynamicRecursiveASTVisitor::TraverseConstructorInitializer( - CXXCtorInitializer *Init) { - return Impl(*this).RecursiveASTVisitor::TraverseConstructorInitializer( - Init); -} - -bool DynamicRecursiveASTVisitor::TraverseDecl(Decl *D) { - return Impl(*this).RecursiveASTVisitor::TraverseDecl(D); -} - -bool DynamicRecursiveASTVisitor::TraverseLambdaCapture(LambdaExpr *LE, - const LambdaCapture *C, - Expr *Init) { - return Impl(*this).RecursiveASTVisitor::TraverseLambdaCapture(LE, C, - Init); -} - -bool DynamicRecursiveASTVisitor::TraverseStmt(Stmt *S) { - return Impl(*this).RecursiveASTVisitor::TraverseStmt(S); -} - -bool DynamicRecursiveASTVisitor::TraverseTemplateArgument( - const TemplateArgument &Arg) { - return Impl(*this).RecursiveASTVisitor::TraverseTemplateArgument(Arg); -} - -bool DynamicRecursiveASTVisitor::TraverseTemplateArguments( - ArrayRef Args) { - return Impl(*this).RecursiveASTVisitor::TraverseTemplateArguments(Args); -} - -bool DynamicRecursiveASTVisitor::TraverseTemplateArgumentLoc( - const TemplateArgumentLoc &ArgLoc) { - return Impl(*this).RecursiveASTVisitor::TraverseTemplateArgumentLoc( - ArgLoc); -} - -bool DynamicRecursiveASTVisitor::TraverseTemplateName(TemplateName Template) { - return Impl(*this).RecursiveASTVisitor::TraverseTemplateName(Template); -} - -bool DynamicRecursiveASTVisitor::TraverseType(QualType T) { - return Impl(*this).RecursiveASTVisitor::TraverseType(T); -} - -bool DynamicRecursiveASTVisitor::TraverseTypeLoc(TypeLoc TL) { - return Impl(*this).RecursiveASTVisitor::TraverseTypeLoc(TL); -} - -bool DynamicRecursiveASTVisitor::TraverseTypeConstraint( - const TypeConstraint *C) { - return Impl(*this).RecursiveASTVisitor::TraverseTypeConstraint(C); -} -bool DynamicRecursiveASTVisitor::TraverseObjCProtocolLoc( - ObjCProtocolLoc ProtocolLoc) { - return Impl(*this).RecursiveASTVisitor::TraverseObjCProtocolLoc( - ProtocolLoc); -} - -bool DynamicRecursiveASTVisitor::TraverseConceptRequirement( - concepts::Requirement *R) { - return Impl(*this).RecursiveASTVisitor::TraverseConceptRequirement(R); -} -bool DynamicRecursiveASTVisitor::TraverseConceptTypeRequirement( - concepts::TypeRequirement *R) { - return Impl(*this).RecursiveASTVisitor::TraverseConceptTypeRequirement( - R); -} -bool DynamicRecursiveASTVisitor::TraverseConceptExprRequirement( - concepts::ExprRequirement *R) { - return Impl(*this).RecursiveASTVisitor::TraverseConceptExprRequirement( - R); -} -bool DynamicRecursiveASTVisitor::TraverseConceptNestedRequirement( - concepts::NestedRequirement *R) { - return Impl(*this) - .RecursiveASTVisitor::TraverseConceptNestedRequirement(R); -} - -bool DynamicRecursiveASTVisitor::TraverseConceptReference( - ConceptReference *CR) { - return Impl(*this).RecursiveASTVisitor::TraverseConceptReference(CR); -} - -bool DynamicRecursiveASTVisitor::TraverseCXXBaseSpecifier( - const CXXBaseSpecifier &Base) { - return Impl(*this).RecursiveASTVisitor::TraverseCXXBaseSpecifier(Base); -} - -bool DynamicRecursiveASTVisitor::TraverseDeclarationNameInfo( - DeclarationNameInfo NameInfo) { - return Impl(*this).RecursiveASTVisitor::TraverseDeclarationNameInfo( - NameInfo); -} - -bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifier( - NestedNameSpecifier *NNS) { - return Impl(*this).RecursiveASTVisitor::TraverseNestedNameSpecifier( - NNS); -} - -bool DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc( - NestedNameSpecifierLoc NNS) { - return Impl(*this).RecursiveASTVisitor::TraverseNestedNameSpecifierLoc( - NNS); +template void DynamicRecursiveASTVisitorBase::anchor() {} + +// Helper macros to forward a call to the base implementation since that +// ends up getting very verbose otherwise. + +// This calls the RecursiveASTVisitor implementation of the same function, +// stripping any 'const' that the DRAV implementation may have added since +// the RAV implementation largely doesn't use 'const'. +#define FORWARD_TO_BASE(Function, Type, RefOrPointer) \ + template \ + bool DynamicRecursiveASTVisitorBase::Function( \ + MaybeConst RefOrPointer Param) { \ + return Impl(*this).RecursiveASTVisitor>::Function( \ + const_cast(Param)); \ + } + +// Same as 'FORWARD_TO_BASE', but doesn't change the parameter type in any way. +#define FORWARD_TO_BASE_EXACT(Function, Type) \ + template \ + bool DynamicRecursiveASTVisitorBase::Function(Type Param) { \ + return Impl(*this).RecursiveASTVisitor>::Function( \ + Param); \ + } + +FORWARD_TO_BASE(TraverseAST, ASTContext, &) +FORWARD_TO_BASE(TraverseAttr, Attr, *) +FORWARD_TO_BASE(TraverseConstructorInitializer, CXXCtorInitializer, *) +FORWARD_TO_BASE(TraverseDecl, Decl, *) +FORWARD_TO_BASE(TraverseStmt, Stmt, *) +FORWARD_TO_BASE(TraverseNestedNameSpecifier, NestedNameSpecifier, *) +FORWARD_TO_BASE(TraverseTemplateInstantiations, ClassTemplateDecl, *) +FORWARD_TO_BASE(TraverseTemplateInstantiations, VarTemplateDecl, *) +FORWARD_TO_BASE(TraverseTemplateInstantiations, FunctionTemplateDecl, *) +FORWARD_TO_BASE(TraverseConceptRequirement, concepts::Requirement, *) +FORWARD_TO_BASE(TraverseConceptTypeRequirement, concepts::TypeRequirement, *) +FORWARD_TO_BASE(TraverseConceptExprRequirement, concepts::ExprRequirement, *) +FORWARD_TO_BASE(TraverseConceptReference, ConceptReference, *) +FORWARD_TO_BASE(TraverseConceptNestedRequirement, + concepts::NestedRequirement, *) + +FORWARD_TO_BASE_EXACT(TraverseCXXBaseSpecifier, const CXXBaseSpecifier &) +FORWARD_TO_BASE_EXACT(TraverseDeclarationNameInfo, DeclarationNameInfo) +FORWARD_TO_BASE_EXACT(TraverseTemplateArgument, const TemplateArgument &) +FORWARD_TO_BASE_EXACT(TraverseTemplateArguments, ArrayRef) +FORWARD_TO_BASE_EXACT(TraverseTemplateArgumentLoc, const TemplateArgumentLoc &) +FORWARD_TO_BASE_EXACT(TraverseTemplateName, TemplateName) +FORWARD_TO_BASE_EXACT(TraverseType, QualType) +FORWARD_TO_BASE_EXACT(TraverseTypeLoc, TypeLoc) +FORWARD_TO_BASE_EXACT(TraverseTypeConstraint, const TypeConstraint *) +FORWARD_TO_BASE_EXACT(TraverseObjCProtocolLoc, ObjCProtocolLoc) +FORWARD_TO_BASE_EXACT(TraverseNestedNameSpecifierLoc, NestedNameSpecifierLoc) + +template +bool DynamicRecursiveASTVisitorBase::TraverseLambdaCapture( + MaybeConst *LE, const LambdaCapture *C, + MaybeConst *Init) { + return Impl(*this) + .RecursiveASTVisitor>::TraverseLambdaCapture( + const_cast(LE), C, const_cast(Init)); } -bool DynamicRecursiveASTVisitor::dataTraverseNode(Stmt *S) { - return Impl(*this).RecursiveASTVisitor::dataTraverseNode(S, nullptr); +template +bool DynamicRecursiveASTVisitorBase::dataTraverseNode( + MaybeConst *S) { + return Impl(*this).RecursiveASTVisitor>::dataTraverseNode( + const_cast(S), nullptr); } -#define DEF_TRAVERSE_TMPL_INST(kind) \ - bool DynamicRecursiveASTVisitor::TraverseTemplateInstantiations( \ - kind##TemplateDecl *D) { \ - return Impl(*this) \ - .RecursiveASTVisitor::TraverseTemplateInstantiations(D); \ - } -DEF_TRAVERSE_TMPL_INST(Class) -DEF_TRAVERSE_TMPL_INST(Var) -DEF_TRAVERSE_TMPL_INST(Function) -#undef DEF_TRAVERSE_TMPL_INST - // Declare Traverse*() for and friends all concrete Decl classes. #define ABSTRACT_DECL(DECL) #define DECL(CLASS, BASE) \ - bool DynamicRecursiveASTVisitor::Traverse##CLASS##Decl(CLASS##Decl *D) { \ - return Impl(*this).RecursiveASTVisitor::Traverse##CLASS##Decl(D); \ - } \ - bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \ - return Impl(*this).RecursiveASTVisitor::WalkUpFrom##CLASS##Decl(D); \ - } + FORWARD_TO_BASE(Traverse##CLASS##Decl, CLASS##Decl, *) \ + FORWARD_TO_BASE(WalkUpFrom##CLASS##Decl, CLASS##Decl, *) #include "clang/AST/DeclNodes.inc" // Declare Traverse*() and friends for all concrete Stmt classes. #define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) \ - bool DynamicRecursiveASTVisitor::Traverse##CLASS(CLASS *S) { \ - return Impl(*this).RecursiveASTVisitor::Traverse##CLASS(S); \ - } +#define STMT(CLASS, PARENT) FORWARD_TO_BASE(Traverse##CLASS, CLASS, *) #include "clang/AST/StmtNodes.inc" -#define STMT(CLASS, PARENT) \ - bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS(CLASS *S) { \ - return Impl(*this).RecursiveASTVisitor::WalkUpFrom##CLASS(S); \ - } +#define STMT(CLASS, PARENT) FORWARD_TO_BASE(WalkUpFrom##CLASS, CLASS, *) #include "clang/AST/StmtNodes.inc" -// Declare Traverse*() and friends for all concrete Typeclasses. +// Declare Traverse*() and friends for all concrete Type classes. #define ABSTRACT_TYPE(CLASS, BASE) #define TYPE(CLASS, BASE) \ - bool DynamicRecursiveASTVisitor::Traverse##CLASS##Type(CLASS##Type *T) { \ - return Impl(*this).RecursiveASTVisitor::Traverse##CLASS##Type(T); \ - } \ - bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##Type(CLASS##Type *T) { \ - return Impl(*this).RecursiveASTVisitor::WalkUpFrom##CLASS##Type(T); \ - } + FORWARD_TO_BASE(Traverse##CLASS##Type, CLASS##Type, *) \ + FORWARD_TO_BASE(WalkUpFrom##CLASS##Type, CLASS##Type, *) #include "clang/AST/TypeNodes.inc" #define ABSTRACT_TYPELOC(CLASS, BASE) #define TYPELOC(CLASS, BASE) \ - bool DynamicRecursiveASTVisitor::Traverse##CLASS##TypeLoc( \ - CLASS##TypeLoc TL) { \ - return Impl(*this).RecursiveASTVisitor::Traverse##CLASS##TypeLoc( \ - TL); \ - } + FORWARD_TO_BASE_EXACT(Traverse##CLASS##TypeLoc, CLASS##TypeLoc) #include "clang/AST/TypeLocNodes.def" #define TYPELOC(CLASS, BASE) \ - bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##TypeLoc( \ - CLASS##TypeLoc TL) { \ - return Impl(*this).RecursiveASTVisitor::WalkUpFrom##CLASS##TypeLoc( \ - TL); \ - } + FORWARD_TO_BASE_EXACT(WalkUpFrom##CLASS##TypeLoc, CLASS##TypeLoc) #include "clang/AST/TypeLocNodes.def" + +namespace clang { +template class DynamicRecursiveASTVisitorBase; +template class DynamicRecursiveASTVisitorBase; +} // namespace clang diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 31b95bca613c2..c22aa66ba2cfb 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -895,8 +895,7 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK, // type deduction and lambdas. For trailing return types resolve the // decltype expression. Otherwise print the real type when this is // not a constructor or destructor. - if (isa(FD) && - cast(FD)->getParent()->isLambda()) + if (isLambdaMethod(FD)) Proto = "auto " + Proto; else if (FT && FT->getReturnType()->getAs()) FT->getReturnType() @@ -1957,6 +1956,7 @@ bool CastExpr::CastConsistency() const { case CK_FixedPointToBoolean: case CK_HLSLArrayRValue: case CK_HLSLVectorTruncation: + case CK_HLSLElementwiseCast: CheckNoBasePath: assert(path_empty() && "Cast kind should not have a base path!"); break; @@ -3660,6 +3660,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case PackIndexingExprClass: case HLSLOutArgExprClass: case OpenACCAsteriskSizeExprClass: + case ResolvedUnexpandedPackExprClass: // These never have a side-effect. return false; diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 5bf5d6adf525a..d900af895b42a 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1965,3 +1965,52 @@ CXXFoldExpr::CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee, SubExprs[SubExpr::RHS] = RHS; setDependence(computeDependence(this)); } + +ResolvedUnexpandedPackExpr::ResolvedUnexpandedPackExpr(SourceLocation BL, + QualType QT, + unsigned NumExprs) + : Expr(ResolvedUnexpandedPackExprClass, QT, VK_PRValue, OK_Ordinary), + BeginLoc(BL), NumExprs(NumExprs) { + // C++ [temp.dep.expr]p3 + // An id-expression is type-dependent if it is + // - associated by name lookup with a pack + setDependence(ExprDependence::TypeValueInstantiation | + ExprDependence::UnexpandedPack); +} + +ResolvedUnexpandedPackExpr * +ResolvedUnexpandedPackExpr::CreateDeserialized(ASTContext &Ctx, + unsigned NumExprs) { + void *Mem = Ctx.Allocate(totalSizeToAlloc(NumExprs), + alignof(ResolvedUnexpandedPackExpr)); + return new (Mem) + ResolvedUnexpandedPackExpr(SourceLocation(), QualType(), NumExprs); +} + +ResolvedUnexpandedPackExpr * +ResolvedUnexpandedPackExpr::Create(ASTContext &Ctx, SourceLocation BL, + QualType T, unsigned NumExprs) { + void *Mem = Ctx.Allocate(totalSizeToAlloc(NumExprs), + alignof(ResolvedUnexpandedPackExpr)); + ResolvedUnexpandedPackExpr *New = + new (Mem) ResolvedUnexpandedPackExpr(BL, T, NumExprs); + + auto Exprs = New->getExprs(); + std::uninitialized_fill(Exprs.begin(), Exprs.end(), nullptr); + + return New; +} + +ResolvedUnexpandedPackExpr * +ResolvedUnexpandedPackExpr::Create(ASTContext &Ctx, SourceLocation BL, + QualType T, ArrayRef Exprs) { + auto *New = Create(Ctx, BL, T, Exprs.size()); + std::uninitialized_copy(Exprs.begin(), Exprs.end(), New->getExprs().begin()); + return New; +} + +ResolvedUnexpandedPackExpr *ResolvedUnexpandedPackExpr::getFromDecl(Decl *D) { + if (auto *BD = dyn_cast(D)) + return dyn_cast_if_present(BD->getBinding()); + return nullptr; +} diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 3f37d06cc8f3a..5225c3ca773ad 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -451,6 +451,13 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::PackExpansionExprClass: return ClassifyInternal(Ctx, cast(E)->getPattern()); + case Expr::ResolvedUnexpandedPackExprClass: { + if (cast(E)->getNumExprs() > 0) + return ClassifyInternal( + Ctx, cast(E)->getExpansion(0)); + return Cl::CL_LValue; + } + case Expr::MaterializeTemporaryExprClass: return cast(E)->isBoundToLvalueReference() ? Cl::CL_LValue diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 3b5ab839c6cf7..5c6ca4c9ee4de 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1961,7 +1961,7 @@ APValue & CallStackFrame::createConstexprUnknownAPValues(const VarDecl *Key, APValue::LValueBase Base) { APValue &Result = ConstexprUnknownAPValues[MapKeyTy(Key, Base.getVersion())]; - Result = APValue(Base, CharUnits::One(), APValue::ConstexprUnknown{}); + Result = APValue(Base, CharUnits::Zero(), APValue::ConstexprUnknown{}); return Result; } @@ -3600,8 +3600,12 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, VD->mightBeUsableInConstantExpressions(Info.Ctx)) || ((Info.getLangOpts().CPlusPlus || Info.getLangOpts().OpenCL) && !Info.getLangOpts().CPlusPlus11 && !VD->hasICEInitializer(Info.Ctx))) { - Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD; - NoteLValueLocation(Info, Base); + if (Init) { + Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant, 1) << VD; + NoteLValueLocation(Info, Base); + } else { + Info.CCEDiag(E); + } } // Never use the initializer of a weak variable, not even for constant @@ -5221,7 +5225,7 @@ static bool EvaluateDecl(EvalInfo &Info, const Decl *D) { OK &= EvaluateVarDecl(Info, VD); if (const DecompositionDecl *DD = dyn_cast(D)) - for (auto *BD : DD->bindings()) + for (auto *BD : DD->flat_bindings()) if (auto *VD = BD->getHoldingVar()) OK &= EvaluateDecl(Info, VD); @@ -12532,10 +12536,9 @@ static const Expr *ignorePointerCastsAndParens(const Expr *E) { static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { assert(!LVal.Designator.Invalid); - auto IsLastOrInvalidFieldDecl = [&Ctx](const FieldDecl *FD, bool &Invalid) { + auto IsLastOrInvalidFieldDecl = [&Ctx](const FieldDecl *FD) { const RecordDecl *Parent = FD->getParent(); - Invalid = Parent->isInvalidDecl(); - if (Invalid || Parent->isUnion()) + if (Parent->isInvalidDecl() || Parent->isUnion()) return true; const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Parent); return FD->getFieldIndex() + 1 == Layout.getFieldCount(); @@ -12544,14 +12547,12 @@ static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { auto &Base = LVal.getLValueBase(); if (auto *ME = dyn_cast_or_null(Base.dyn_cast())) { if (auto *FD = dyn_cast(ME->getMemberDecl())) { - bool Invalid; - if (!IsLastOrInvalidFieldDecl(FD, Invalid)) - return Invalid; + if (!IsLastOrInvalidFieldDecl(FD)) + return false; } else if (auto *IFD = dyn_cast(ME->getMemberDecl())) { for (auto *FD : IFD->chain()) { - bool Invalid; - if (!IsLastOrInvalidFieldDecl(cast(FD), Invalid)) - return Invalid; + if (!IsLastOrInvalidFieldDecl(cast(FD))) + return false; } } } @@ -12587,9 +12588,8 @@ static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { return false; BaseType = CT->getElementType(); } else if (auto *FD = getAsField(Entry)) { - bool Invalid; - if (!IsLastOrInvalidFieldDecl(FD, Invalid)) - return Invalid; + if (!IsLastOrInvalidFieldDecl(FD)) + return false; BaseType = FD->getType(); } else { assert(getAsBaseClass(Entry) && "Expecting cast to a base class"); @@ -15043,6 +15043,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_NoOp: case CK_LValueToRValueBitCast: case CK_HLSLArrayRValue: + case CK_HLSLElementwiseCast: return ExprEvaluatorBaseTy::VisitCastExpr(E); case CK_MemberPointerToBoolean: @@ -15901,6 +15902,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) { case CK_IntegralToFixedPoint: case CK_MatrixCast: case CK_HLSLVectorTruncation: + case CK_HLSLElementwiseCast: llvm_unreachable("invalid cast kind for complex value"); case CK_LValueToRValue: @@ -17249,6 +17251,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::SYCLUniqueStableNameExprClass: case Expr::CXXParenListInitExprClass: case Expr::HLSLOutArgExprClass: + case Expr::ResolvedUnexpandedPackExprClass: return ICEDiag(IK_NotICE, E->getBeginLoc()); case Expr::InitListExprClass: { diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 1dd936cf4fb51..e5eb22eae7dd1 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3419,24 +3419,24 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { /* Prior to Clang 18.0 we used this incorrect mangled name */ \ mangleVendorType("__SVBFloat16_t"); \ } else { \ - type_name = MangledName; \ - Out << (type_name == Name ? "u" : "") << type_name.size() << type_name; \ + type_name = #MangledName; \ + Out << (type_name == #Name ? "u" : "") << type_name.size() << type_name; \ } \ break; #define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \ case BuiltinType::Id: \ - type_name = MangledName; \ - Out << (type_name == Name ? "u" : "") << type_name.size() << type_name; \ + type_name = #MangledName; \ + Out << (type_name == #Name ? "u" : "") << type_name.size() << type_name; \ break; #define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) \ case BuiltinType::Id: \ - type_name = MangledName; \ - Out << (type_name == Name ? "u" : "") << type_name.size() << type_name; \ + type_name = #MangledName; \ + Out << (type_name == #Name ? "u" : "") << type_name.size() << type_name; \ break; -#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ +#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits) \ case BuiltinType::Id: \ - type_name = MangledName; \ - Out << (type_name == Name ? "u" : "") << type_name.size() << type_name; \ + type_name = #MangledName; \ + Out << (type_name == #Name ? "u" : "") << type_name.size() << type_name; \ break; #include "clang/Basic/AArch64SVEACLETypes.def" #define PPC_VECTOR_TYPE(Name, Id, Size) \ @@ -3919,6 +3919,9 @@ void CXXNameMangler::mangleNeonVectorType(const VectorType *T) { case BuiltinType::Float: EltName = "float32_t"; break; case BuiltinType::Half: EltName = "float16_t"; break; case BuiltinType::BFloat16: EltName = "bfloat16_t"; break; + case BuiltinType::MFloat8: + EltName = "mfloat8_t"; + break; default: llvm_unreachable("unexpected Neon vector element type"); } @@ -3972,6 +3975,8 @@ static StringRef mangleAArch64VectorBase(const BuiltinType *EltType) { return "Float64"; case BuiltinType::BFloat16: return "Bfloat16"; + case BuiltinType::MFloat8: + return "Mfloat8"; default: llvm_unreachable("Unexpected vector element base type"); } @@ -4193,7 +4198,7 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { // Apend the LMUL suffix. auto VScale = getASTContext().getTargetInfo().getVScaleRange( - getASTContext().getLangOpts()); + getASTContext().getLangOpts(), false); unsigned VLen = VScale->first * llvm::RISCV::RVVBitsPerBlock; if (T->getVectorKind() == VectorKind::RVVFixedLengthData) { @@ -4928,7 +4933,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, case Expr::SourceLocExprClass: case Expr::EmbedExprClass: case Expr::BuiltinBitCastExprClass: - { + case Expr::ResolvedUnexpandedPackExprClass: { NotPrimaryExpr(); if (!NullOut) { // As bad as this diagnostic is, it's better than crashing. diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 36ef1fc8c79db..169e3ee94c221 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -1003,6 +1003,11 @@ void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) { void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) { VisitRecordDecl(RD); + if (const auto *CTSD = dyn_cast(RD)) { + if (CTSD->hasStrictPackMatch()) + JOS.attribute("strict-pack-match", true); + } + // All other information requires a complete definition. if (!RD->isCompleteDefinition()) return; diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index edeeaeaa9ae17..fe34251688a98 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -2792,6 +2792,10 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, mangleArtificialTagType(TagTypeKind::Struct, "__bf16", {"__clang"}); break; + case BuiltinType::MFloat8: + mangleArtificialTagType(TagTypeKind::Struct, "__mfp8", {"__clang"}); + break; + #define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \ case BuiltinType::Id: \ mangleArtificialTagType(TagTypeKind::Struct, MangledName); \ @@ -2806,48 +2810,13 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, break; #include "clang/Basic/HLSLIntangibleTypes.def" -#define SVE_TYPE(Name, Id, SingletonId) \ - case BuiltinType::Id: -#include "clang/Basic/AArch64SVEACLETypes.def" -#define PPC_VECTOR_TYPE(Name, Id, Size) \ - case BuiltinType::Id: -#include "clang/Basic/PPCTypes.def" -#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id: -#include "clang/Basic/RISCVVTypes.def" -#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id: -#include "clang/Basic/AMDGPUTypes.def" - case BuiltinType::ShortAccum: - case BuiltinType::Accum: - case BuiltinType::LongAccum: - case BuiltinType::UShortAccum: - case BuiltinType::UAccum: - case BuiltinType::ULongAccum: - case BuiltinType::ShortFract: - case BuiltinType::Fract: - case BuiltinType::LongFract: - case BuiltinType::UShortFract: - case BuiltinType::UFract: - case BuiltinType::ULongFract: - case BuiltinType::SatShortAccum: - case BuiltinType::SatAccum: - case BuiltinType::SatLongAccum: - case BuiltinType::SatUShortAccum: - case BuiltinType::SatUAccum: - case BuiltinType::SatULongAccum: - case BuiltinType::SatShortFract: - case BuiltinType::SatFract: - case BuiltinType::SatLongFract: - case BuiltinType::SatUShortFract: - case BuiltinType::SatUFract: - case BuiltinType::SatULongFract: - case BuiltinType::Ibm128: - case BuiltinType::Float128: { + // Issue an error for any type not explicitly handled. + default: Error(Range.getBegin(), "built-in type: ", T->getName(Context.getASTContext().getPrintingPolicy())) << Range; break; } - } } // ::= diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 532933d6183ce..424cab3a7de35 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -2073,6 +2073,11 @@ void OMPClausePrinter::VisitOMPNoOpenMPRoutinesClause( OS << "no_openmp_routines"; } +void OMPClausePrinter::VisitOMPNoOpenMPConstructsClause( + OMPNoOpenMPConstructsClause *) { + OS << "no_openmp_constructs"; +} + void OMPClausePrinter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) { OS << "no_parallelism"; } @@ -2927,9 +2932,13 @@ llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS, TargetOMPContext::TargetOMPContext( ASTContext &ASTCtx, std::function &&DiagUnknownTrait, const FunctionDecl *CurrentFunctionDecl, - ArrayRef ConstructTraits) + ArrayRef ConstructTraits, int DeviceNum) : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice, - ASTCtx.getTargetInfo().getTriple()), + ASTCtx.getTargetInfo().getTriple(), + ASTCtx.getLangOpts().OMPTargetTriples.empty() + ? llvm::Triple() + : ASTCtx.getLangOpts().OMPTargetTriples[0], + DeviceNum), FeatureValidityCheck([&](StringRef FeatureName) { return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName); }), diff --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp index af7d9fcdc638b..e9387ec79c373 100644 --- a/clang/lib/AST/ParentMapContext.cpp +++ b/clang/lib/AST/ParentMapContext.cpp @@ -103,9 +103,9 @@ class ParentMapContext::ParentMap { static DynTypedNode getSingleDynTypedNodeFromParentMap(ParentMapPointers::mapped_type U) { - if (const auto *D = U.dyn_cast()) + if (const auto *D = dyn_cast(U)) return DynTypedNode::create(*D); - if (const auto *S = U.dyn_cast()) + if (const auto *S = dyn_cast(U)) return DynTypedNode::create(*S); return *cast(U); } @@ -117,7 +117,7 @@ class ParentMapContext::ParentMap { if (I == Map.end()) { return llvm::ArrayRef(); } - if (const auto *V = I->second.template dyn_cast()) { + if (const auto *V = dyn_cast(I->second)) { return V->view(); } return getSingleDynTypedNodeFromParentMap(I->second); @@ -268,9 +268,9 @@ class ParentMapContext::ParentMap { auto It = PointerParents.find(E); if (It == PointerParents.end()) break; - const auto *S = It->second.dyn_cast(); + const auto *S = dyn_cast(It->second); if (!S) { - if (auto *Vec = It->second.dyn_cast()) + if (auto *Vec = dyn_cast(It->second)) return Vec->view(); return getSingleDynTypedNodeFromParentMap(It->second); } @@ -395,7 +395,7 @@ class ParentMapContext::ParentMap::ASTVisitor if (!isa(NodeOrVector)) { auto *Vector = new ParentVector( 1, getSingleDynTypedNodeFromParentMap(NodeOrVector)); - delete NodeOrVector.template dyn_cast(); + delete dyn_cast(NodeOrVector); NodeOrVector = Vector; } diff --git a/clang/lib/AST/RawCommentList.cpp b/clang/lib/AST/RawCommentList.cpp index fddedd3a31856..9658c6ab3d39d 100644 --- a/clang/lib/AST/RawCommentList.cpp +++ b/clang/lib/AST/RawCommentList.cpp @@ -287,13 +287,13 @@ void RawCommentList::addComment(const RawComment &RC, // If this is the first Doxygen comment, save it (because there isn't // anything to merge it with). - if (OrderedComments[CommentFile].empty()) { - OrderedComments[CommentFile][CommentOffset] = - new (Allocator) RawComment(RC); + auto &OC = OrderedComments[CommentFile]; + if (OC.empty()) { + OC[CommentOffset] = new (Allocator) RawComment(RC); return; } - const RawComment &C1 = *OrderedComments[CommentFile].rbegin()->second; + const RawComment &C1 = *OC.rbegin()->second; const RawComment &C2 = RC; // Merge comments only if there is only whitespace between them. diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp index 2b0ac716bab56..11eab0c27579d 100644 --- a/clang/lib/AST/StmtOpenACC.cpp +++ b/clang/lib/AST/StmtOpenACC.cpp @@ -305,3 +305,19 @@ OpenACCUpdateConstruct::Create(const ASTContext &C, SourceLocation Start, new (Mem) OpenACCUpdateConstruct(Start, DirectiveLoc, End, Clauses); return Inst; } + +OpenACCAtomicConstruct * +OpenACCAtomicConstruct::CreateEmpty(const ASTContext &C) { + void *Mem = C.Allocate(sizeof(OpenACCAtomicConstruct)); + auto *Inst = new (Mem) OpenACCAtomicConstruct(EmptyShell{}); + return Inst; +} + +OpenACCAtomicConstruct *OpenACCAtomicConstruct::Create( + const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + OpenACCAtomicKind AtKind, SourceLocation End, Stmt *AssociatedStmt) { + void *Mem = C.Allocate(sizeof(OpenACCAtomicConstruct)); + auto *Inst = new (Mem) + OpenACCAtomicConstruct(Start, DirectiveLoc, AtKind, End, AssociatedStmt); + return Inst; +} diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index b5def6fbe525c..3ce932a9dd352 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -45,9 +45,11 @@ #include "clang/Basic/TypeTraits.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -1240,6 +1242,16 @@ void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) { OS << '\n'; } +void StmtPrinter::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) { + Indent() << "#pragma acc atomic"; + + if (S->getAtomicKind() != OpenACCAtomicKind::None) + OS << " " << S->getAtomicKind(); + + OS << '\n'; + PrintStmt(S->getAssociatedStmt()); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// @@ -1257,11 +1269,12 @@ void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) { } void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { - if (const auto *OCED = dyn_cast(Node->getDecl())) { + ValueDecl *VD = Node->getDecl(); + if (const auto *OCED = dyn_cast(VD)) { OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy); return; } - if (const auto *TPOD = dyn_cast(Node->getDecl())) { + if (const auto *TPOD = dyn_cast(VD)) { TPOD->printAsExpr(OS, Policy); return; } @@ -1269,16 +1282,41 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { Qualifier->print(OS, Policy); if (Node->hasTemplateKeyword()) OS << "template "; - if (Policy.CleanUglifiedParameters && - isa(Node->getDecl()) && - Node->getDecl()->getIdentifier()) - OS << Node->getDecl()->getIdentifier()->deuglifiedName(); - else - Node->getNameInfo().printName(OS, Policy); + DeclarationNameInfo NameInfo = Node->getNameInfo(); + if (IdentifierInfo *ID = NameInfo.getName().getAsIdentifierInfo(); + ID || NameInfo.getName().getNameKind() != DeclarationName::Identifier) { + if (Policy.CleanUglifiedParameters && + isa(VD) && ID) + OS << ID->deuglifiedName(); + else + NameInfo.printName(OS, Policy); + } else { + switch (VD->getKind()) { + case Decl::NonTypeTemplateParm: { + auto *TD = cast(VD); + OS << "value-parameter-" << TD->getDepth() << '-' << TD->getIndex() << ""; + break; + } + case Decl::ParmVar: { + auto *PD = cast(VD); + OS << "function-parameter-" << PD->getFunctionScopeDepth() << '-' + << PD->getFunctionScopeIndex(); + break; + } + case Decl::Decomposition: + OS << "decomposition"; + for (const auto &I : cast(VD)->bindings()) + OS << '-' << I->getName(); + break; + default: + OS << "unhandled-anonymous-" << VD->getDeclKindName(); + break; + } + } if (Node->hasExplicitTemplateArgs()) { const TemplateParameterList *TPL = nullptr; if (!Node->hadMultipleCandidates()) - if (auto *TD = dyn_cast(Node->getDecl())) + if (auto *TD = dyn_cast(VD)) TPL = TD->getTemplateParameters(); printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL); } @@ -1939,7 +1977,6 @@ void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) { void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { const char *Name = nullptr; switch (Node->getOp()) { -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case AtomicExpr::AO ## ID: \ Name = #ID "("; \ @@ -2567,6 +2604,15 @@ void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) { OS << "]"; } +void StmtPrinter::VisitResolvedUnexpandedPackExpr( + ResolvedUnexpandedPackExpr *E) { + OS << "<getExprs().begin(), E->getExprs().end(), + [this](auto *X) { PrintExpr(X); }, [this] { OS << ", "; }); + OS << ")>>"; +} + void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( SubstNonTypeTemplateParmPackExpr *Node) { OS << *Node->getParameterPack(); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 85b59f714ba84..8b4b8ba19f75b 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -606,6 +606,9 @@ void OMPClauseProfiler::VisitOMPNoOpenMPClause(const OMPNoOpenMPClause *) {} void OMPClauseProfiler::VisitOMPNoOpenMPRoutinesClause( const OMPNoOpenMPRoutinesClause *) {} +void OMPClauseProfiler::VisitOMPNoOpenMPConstructsClause( + const OMPNoOpenMPConstructsClause *) {} + void OMPClauseProfiler::VisitOMPNoParallelismClause( const OMPNoParallelismClause *) {} @@ -2270,16 +2273,20 @@ void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) { void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) { VisitExpr(S); - VisitDecl(S->getPack()); if (S->isPartiallySubstituted()) { auto Args = S->getPartialArguments(); ID.AddInteger(Args.size()); for (const auto &TA : Args) VisitTemplateArgument(TA); } else { + VisitDecl(S->getPack()); ID.AddInteger(0); } } +void StmtProfiler::VisitResolvedUnexpandedPackExpr( + const ResolvedUnexpandedPackExpr *S) { + VisitExpr(S); +} void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) { VisitExpr(E); @@ -2805,6 +2812,11 @@ void StmtProfiler::VisitOpenACCUpdateConstruct( P.VisitOpenACCClauseList(S->clauses()); } +void StmtProfiler::VisitOpenACCAtomicConstruct( + const OpenACCAtomicConstruct *S) { + VisitStmt(S); +} + void StmtProfiler::VisitHLSLOutArgExpr(const HLSLOutArgExpr *S) { VisitStmt(S); } diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 3625b6e435a55..0eef8f305fcb3 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -515,19 +515,17 @@ void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, } case Declaration: { - NamedDecl *ND = getAsDecl(); + ValueDecl *VD = getAsDecl(); if (getParamTypeForDecl()->isRecordType()) { - if (auto *TPO = dyn_cast(ND)) { + if (auto *TPO = dyn_cast(VD)) { TPO->getType().getUnqualifiedType().print(Out, Policy); TPO->printAsInit(Out, Policy); break; } } - if (auto *VD = dyn_cast(ND)) { - if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType())) - Out << "&"; - } - ND->printQualifiedName(Out); + if (needsAmpersandOnTemplateArg(getParamTypeForDecl(), VD->getType())) + Out << "&"; + VD->printQualifiedName(Out); break; } diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 7d6275caedc4f..9e0a7dc2b8cdc 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -144,7 +144,7 @@ TemplateName::TemplateName(DeducedTemplateStorage *Deduced) bool TemplateName::isNull() const { return Storage.isNull(); } TemplateName::NameKind TemplateName::getKind() const { - if (auto *ND = Storage.dyn_cast()) { + if (auto *ND = dyn_cast(Storage)) { if (isa(ND)) return UsingTemplate; assert(isa(ND)); @@ -182,7 +182,8 @@ TemplateDecl *TemplateName::getAsTemplateDecl(bool IgnoreDeduced) const { "Unexpected canonical DeducedTemplateName; Did you mean to use " "getTemplateDeclAndDefaultArgs instead?"); - return cast_if_present(Name.Storage.dyn_cast()); + return cast_if_present( + dyn_cast_if_present(Name.Storage)); } std::pair @@ -208,7 +209,7 @@ TemplateName::getTemplateDeclAndDefaultArgs() const { } std::optional TemplateName::desugar(bool IgnoreDeduced) const { - if (Decl *D = Storage.dyn_cast()) { + if (Decl *D = dyn_cast_if_present(Storage)) { if (auto *USD = dyn_cast(D)) return TemplateName(USD->getTargetDecl()); return std::nullopt; @@ -242,7 +243,7 @@ AssumedTemplateStorage *TemplateName::getAsAssumedTemplateName() const { SubstTemplateTemplateParmStorage * TemplateName::getAsSubstTemplateTemplateParm() const { if (UncommonTemplateNameStorage *uncommon = - Storage.dyn_cast()) + dyn_cast_if_present(Storage)) return uncommon->getAsSubstTemplateTemplateParm(); return nullptr; @@ -258,7 +259,7 @@ TemplateName::getAsSubstTemplateTemplateParmPack() const { } QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const { - return Storage.dyn_cast(); + return dyn_cast_if_present(Storage); } DependentTemplateName *TemplateName::getAsDependentTemplateName() const { @@ -276,7 +277,7 @@ UsingShadowDecl *TemplateName::getAsUsingShadowDecl() const { DeducedTemplateStorage *TemplateName::getAsDeducedTemplateName() const { if (UncommonTemplateNameStorage *Uncommon = - Storage.dyn_cast()) + dyn_cast_if_present(Storage)) return Uncommon->getAsDeducedTemplateName(); return nullptr; diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 670641242cae2..6da1f776b4b63 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -710,10 +710,36 @@ void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { << GetApproxValue(Value.getComplexFloatImag()) << 'i'; } return; - case APValue::LValue: + case APValue::LValue: { (void)Context; - OS << "LValue "; + OS << "LValue Base="; + APValue::LValueBase B = Value.getLValueBase(); + if (B.isNull()) + OS << "null"; + else if (const auto *BE = B.dyn_cast()) { + OS << BE->getStmtClassName() << ' '; + dumpPointer(BE); + } else { + const auto *VDB = B.get(); + OS << VDB->getDeclKindName() << "Decl"; + dumpPointer(VDB); + } + OS << ", Null=" << Value.isNullPointer() + << ", Offset=" << Value.getLValueOffset().getQuantity() + << ", HasPath=" << Value.hasLValuePath(); + if (Value.hasLValuePath()) { + OS << ", PathLength=" << Value.getLValuePath().size(); + OS << ", Path=("; + llvm::ListSeparator Sep; + for (const auto &PathEntry : Value.getLValuePath()) { + // We're printing all entries as array indices because don't have the + // type information here to do anything else. + OS << Sep << PathEntry.getAsArrayIndex(); + } + OS << ")"; + } return; + } case APValue::Array: { unsigned ArraySize = Value.getArraySize(); unsigned NumInitializedElements = Value.getArrayInitializedElts(); @@ -875,7 +901,41 @@ void TextNodeDumper::dumpBareDeclRef(const Decl *D) { if (const NamedDecl *ND = dyn_cast(D)) { ColorScope Color(OS, ShowColors, DeclNameColor); - OS << " '" << ND->getDeclName() << '\''; + if (DeclarationName Name = ND->getDeclName()) + OS << " '" << Name << '\''; + else + switch (ND->getKind()) { + case Decl::Decomposition: { + auto *DD = cast(ND); + OS << " first_binding '" << DD->bindings()[0]->getDeclName() << '\''; + break; + } + case Decl::Field: { + auto *FD = cast(ND); + OS << " field_index " << FD->getFieldIndex(); + break; + } + case Decl::ParmVar: { + auto *PD = cast(ND); + OS << " depth " << PD->getFunctionScopeDepth() << " index " + << PD->getFunctionScopeIndex(); + break; + } + case Decl::TemplateTypeParm: { + auto *TD = cast(ND); + OS << " depth " << TD->getDepth() << " index " << TD->getIndex(); + break; + } + case Decl::NonTypeTemplateParm: { + auto *TD = cast(ND); + OS << " depth " << TD->getDepth() << " index " << TD->getIndex(); + break; + } + default: + // Var, Namespace, (CXX)Record: Nothing else besides source location. + dumpSourceRange(ND->getSourceRange()); + break; + } } if (const ValueDecl *VD = dyn_cast(D)) @@ -898,9 +958,9 @@ void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) { void TextNodeDumper::dumpCleanupObject( const ExprWithCleanups::CleanupObject &C) { - if (auto *BD = C.dyn_cast()) + if (auto *BD = dyn_cast(C)) dumpDeclRef(BD, "cleanup"); - else if (auto *CLE = C.dyn_cast()) + else if (auto *CLE = dyn_cast(C)) AddChild([=] { OS << "cleanup "; { @@ -2465,8 +2525,11 @@ void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { OS << " instantiated_from"; dumpPointer(Instance); } - if (const auto *CTSD = dyn_cast(D)) + if (const auto *CTSD = dyn_cast(D)) { dumpTemplateSpecializationKind(CTSD->getSpecializationKind()); + if (CTSD->hasStrictPackMatch()) + OS << " strict-pack-match"; + } dumpNestedNameSpecifier(D->getQualifier()); @@ -2981,6 +3044,12 @@ void TextNodeDumper::VisitOpenACCUpdateConstruct( VisitOpenACCConstructStmt(S); } +void TextNodeDumper::VisitOpenACCAtomicConstruct( + const OpenACCAtomicConstruct *S) { + VisitOpenACCConstructStmt(S); + OS << ' ' << S->getAtomicKind(); +} + void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) { AddChild("begin", [=] { OS << S->getStartingElementPos(); }); AddChild("number of elements", [=] { OS << S->getDataElementCount(); }); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index caa0ac858a1be..8c11ec2e1fe24 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2527,9 +2527,7 @@ bool Type::isSVESizelessBuiltinType() const { #define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \ case BuiltinType::Id: \ return true; -#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ - case BuiltinType::Id: \ - return false; +#define SVE_TYPE(Name, Id, SingletonId) #include "clang/Basic/AArch64SVEACLETypes.def" default: return false; @@ -3482,9 +3480,9 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { case Id: \ return #ExtType; #include "clang/Basic/OpenCLExtensionTypes.def" -#define SVE_TYPE(Name, Id, SingletonId) \ - case Id: \ - return Name; +#define SVE_TYPE(Name, Id, SingletonId) \ + case Id: \ + return #Name; #include "clang/Basic/AArch64SVEACLETypes.def" #define PPC_VECTOR_TYPE(Name, Id, Size) \ case Id: \ diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index a850410ffc846..31695374cb52b 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2552,10 +2552,12 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "__uptr __ptr32"; case LangAS::ptr64: return "__ptr64"; - case LangAS::wasm_funcref: - return "__funcref"; case LangAS::hlsl_groupshared: return "groupshared"; + case LangAS::hlsl_constant: + return "hlsl_constant"; + case LangAS::wasm_funcref: + return "__funcref"; default: return std::to_string(toTargetAddressSpace(AS)); } diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp index fa3055dd1206f..19d76df99dbe3 100644 --- a/clang/lib/AST/VTableBuilder.cpp +++ b/clang/lib/AST/VTableBuilder.cpp @@ -1169,12 +1169,13 @@ void ItaniumVTableBuilder::ComputeThisAdjustments() { // // Do not set ThunkInfo::Method if Idx is already in VTableThunks. This // can happen when covariant return adjustment is required too. - if (!VTableThunks.count(Idx)) { + auto [It, Inserted] = VTableThunks.try_emplace(Idx); + if (Inserted) { const CXXMethodDecl *Method = VTables.findOriginalMethodInMap(MD); - VTableThunks[Idx].Method = Method; - VTableThunks[Idx].ThisType = Method->getThisType().getTypePtr(); + It->second.Method = Method; + It->second.ThisType = Method->getThisType().getTypePtr(); } - VTableThunks[Idx].This = ThisAdjustment; + It->second.This = ThisAdjustment; }; SetThisAdjustmentThunk(VTableIndex); @@ -1653,8 +1654,9 @@ void ItaniumVTableBuilder::AddMethods( // findOriginalMethod to find the method that created the entry if the // method in the entry requires adjustment. if (!ReturnAdjustment.isEmpty()) { - VTableThunks[Components.size()].Method = MD; - VTableThunks[Components.size()].ThisType = MD->getThisType().getTypePtr(); + auto &VTT = VTableThunks[Components.size()]; + VTT.Method = MD; + VTT.ThisType = MD->getThisType().getTypePtr(); } AddMethod(Overrider.Method, ReturnAdjustment); diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 304bbb2b422c6..3e144395cffc6 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2041,6 +2041,8 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) { } // First destroy member objects. + if (RD->isUnion()) + return; for (auto *FI : RD->fields()) { // Check for constant size array. Set type to array element type. QualType QT = FI->getType(); diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index d7b44149d0fc4..8944343484e58 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -806,17 +806,15 @@ FunctionParmMutationAnalyzer::FunctionParmMutationAnalyzer( const Stmt * FunctionParmMutationAnalyzer::findMutation(const ParmVarDecl *Parm) { - const auto Memoized = Results.find(Parm); - if (Memoized != Results.end()) - return Memoized->second; + auto [Place, Inserted] = Results.try_emplace(Parm); + if (!Inserted) + return Place->second; + // To handle call A -> call B -> call A. Assume parameters of A is not mutated // before analyzing parameters of A. Then when analyzing the second "call A", // FunctionParmMutationAnalyzer can use this memoized value to avoid infinite // recursion. - Results[Parm] = nullptr; - if (const Stmt *S = BodyAnalyzer.findMutation(Parm)) - return Results[Parm] = S; - return Results[Parm]; + return Place->second = BodyAnalyzer.findMutation(Parm); } } // namespace clang diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index 4b86daa56d7b5..1c4fe5c6d5019 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -160,8 +160,9 @@ Atom DataflowAnalysisContext::joinFlowConditions(Atom FirstToken, Atom SecondToken) { Atom Token = arena().makeFlowConditionToken(); - FlowConditionDeps[Token].insert(FirstToken); - FlowConditionDeps[Token].insert(SecondToken); + auto &TokenDeps = FlowConditionDeps[Token]; + TokenDeps.insert(FirstToken); + TokenDeps.insert(SecondToken); addFlowConditionConstraint(Token, arena().makeOr(arena().makeAtomRef(FirstToken), arena().makeAtomRef(SecondToken))); diff --git a/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp b/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp index c58bd309545db..4f5d18225c414 100644 --- a/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp +++ b/clang/lib/Analysis/FlowSensitive/SmartPointerAccessorCaching.cpp @@ -14,6 +14,7 @@ using ast_matchers::callee; using ast_matchers::cxxMemberCallExpr; using ast_matchers::cxxMethodDecl; using ast_matchers::cxxOperatorCallExpr; +using ast_matchers::hasCanonicalType; using ast_matchers::hasName; using ast_matchers::hasOverloadedOperatorName; using ast_matchers::ofClass; @@ -41,7 +42,8 @@ bool hasSmartPointerClassShape(const CXXRecordDecl &RD, bool &HasGet, HasStar = true; StarReturnType = MD->getReturnType() .getNonReferenceType() - ->getCanonicalTypeUnqualified(); + ->getCanonicalTypeUnqualified() + .getUnqualifiedType(); } break; case OO_Arrow: @@ -49,7 +51,8 @@ bool hasSmartPointerClassShape(const CXXRecordDecl &RD, bool &HasGet, HasArrow = true; ArrowReturnType = MD->getReturnType() ->getPointeeType() - ->getCanonicalTypeUnqualified(); + ->getCanonicalTypeUnqualified() + .getUnqualifiedType(); } break; case OO_None: { @@ -61,14 +64,16 @@ bool hasSmartPointerClassShape(const CXXRecordDecl &RD, bool &HasGet, HasGet = true; GetReturnType = MD->getReturnType() ->getPointeeType() - ->getCanonicalTypeUnqualified(); + ->getCanonicalTypeUnqualified() + .getUnqualifiedType(); } } else if (II->isStr("value")) { if (MD->getReturnType()->isReferenceType()) { HasValue = true; ValueReturnType = MD->getReturnType() .getNonReferenceType() - ->getCanonicalTypeUnqualified(); + ->getCanonicalTypeUnqualified() + .getUnqualifiedType(); } } } break; @@ -122,27 +127,29 @@ namespace clang::dataflow { ast_matchers::StatementMatcher isSmartPointerLikeOperatorStar() { return cxxOperatorCallExpr( hasOverloadedOperatorName("*"), - callee(cxxMethodDecl(parameterCountIs(0), returns(referenceType()), + callee(cxxMethodDecl(parameterCountIs(0), + returns(hasCanonicalType(referenceType())), ofClass(smartPointerClassWithGetOrValue())))); } ast_matchers::StatementMatcher isSmartPointerLikeOperatorArrow() { return cxxOperatorCallExpr( hasOverloadedOperatorName("->"), - callee(cxxMethodDecl(parameterCountIs(0), returns(pointerType()), + callee(cxxMethodDecl(parameterCountIs(0), + returns(hasCanonicalType(pointerType())), ofClass(smartPointerClassWithGetOrValue())))); } ast_matchers::StatementMatcher isSmartPointerLikeValueMethodCall() { - return cxxMemberCallExpr(callee( - cxxMethodDecl(parameterCountIs(0), returns(referenceType()), - hasName("value"), ofClass(smartPointerClassWithValue())))); + return cxxMemberCallExpr(callee(cxxMethodDecl( + parameterCountIs(0), returns(hasCanonicalType(referenceType())), + hasName("value"), ofClass(smartPointerClassWithValue())))); } ast_matchers::StatementMatcher isSmartPointerLikeGetMethodCall() { - return cxxMemberCallExpr(callee( - cxxMethodDecl(parameterCountIs(0), returns(pointerType()), hasName("get"), - ofClass(smartPointerClassWithGet())))); + return cxxMemberCallExpr(callee(cxxMethodDecl( + parameterCountIs(0), returns(hasCanonicalType(pointerType())), + hasName("get"), ofClass(smartPointerClassWithGet())))); } const FunctionDecl * diff --git a/clang/lib/Analysis/ProgramPoint.cpp b/clang/lib/Analysis/ProgramPoint.cpp index 7945c5c2fc27f..e508681410b0b 100644 --- a/clang/lib/Analysis/ProgramPoint.cpp +++ b/clang/lib/Analysis/ProgramPoint.cpp @@ -49,6 +49,121 @@ LLVM_DUMP_METHOD void ProgramPoint::dump() const { return printJson(llvm::errs()); } +StringRef ProgramPoint::getProgramPointKindName(Kind K) { + switch (K) { + case BlockEdgeKind: + return "BlockEdge"; + case BlockEntranceKind: + return "BlockEntrance"; + case BlockExitKind: + return "BlockExit"; + case PreStmtKind: + return "PreStmt"; + case PreStmtPurgeDeadSymbolsKind: + return "PreStmtPurgeDeadSymbols"; + case PostStmtPurgeDeadSymbolsKind: + return "PostStmtPurgeDeadSymbols"; + case PostStmtKind: + return "PostStmt"; + case PreLoadKind: + return "PreLoad"; + case PostLoadKind: + return "PostLoad"; + case PreStoreKind: + return "PreStore"; + case PostStoreKind: + return "PostStore"; + case PostConditionKind: + return "PostCondition"; + case PostLValueKind: + return "PostLValue"; + case PostAllocatorCallKind: + return "PostAllocatorCall"; + case PostInitializerKind: + return "PostInitializer"; + case CallEnterKind: + return "CallEnter"; + case CallExitBeginKind: + return "CallExitBegin"; + case CallExitEndKind: + return "CallExitEnd"; + case FunctionExitKind: + return "FunctionExit"; + case PreImplicitCallKind: + return "PreImplicitCall"; + case PostImplicitCallKind: + return "PostImplicitCall"; + case LoopExitKind: + return "LoopExit"; + case EpsilonKind: + return "Epsilon"; + } + llvm_unreachable("Unknown ProgramPoint kind"); +} + +std::optional ProgramPoint::getSourceLocation() const { + switch (getKind()) { + case BlockEdgeKind: + // If needed, the source and or destination beginning can be used to get + // source location. + return std::nullopt; + case BlockEntranceKind: + // If needed, first statement of the block can be used. + return std::nullopt; + case BlockExitKind: + if (const auto *B = castAs().getBlock()) { + if (const auto *T = B->getTerminatorStmt()) { + return T->getBeginLoc(); + } + } + return std::nullopt; + case PreStmtKind: + case PreStmtPurgeDeadSymbolsKind: + case PostStmtPurgeDeadSymbolsKind: + case PostStmtKind: + case PreLoadKind: + case PostLoadKind: + case PreStoreKind: + case PostStoreKind: + case PostConditionKind: + case PostLValueKind: + case PostAllocatorCallKind: + if (const Stmt *S = castAs().getStmt()) + return S->getBeginLoc(); + return std::nullopt; + case PostInitializerKind: + if (const auto *Init = castAs().getInitializer()) + return Init->getSourceLocation(); + return std::nullopt; + case CallEnterKind: + if (const Stmt *S = castAs().getCallExpr()) + return S->getBeginLoc(); + return std::nullopt; + case CallExitBeginKind: + if (const Stmt *S = castAs().getReturnStmt()) + return S->getBeginLoc(); + return std::nullopt; + case CallExitEndKind: + return std::nullopt; + case FunctionExitKind: + if (const auto *B = castAs().getBlock(); + B && B->getTerminatorStmt()) + return B->getTerminatorStmt()->getBeginLoc(); + return std::nullopt; + case PreImplicitCallKind: + return castAs().getLocation(); + case PostImplicitCallKind: + return castAs().getLocation(); + case LoopExitKind: + if (const Stmt *S = castAs().getLoopStmt()) + return S->getBeginLoc(); + return std::nullopt; + case EpsilonKind: + return std::nullopt; + } + llvm_unreachable("Unknown ProgramPoint kind"); +} + void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const { const ASTContext &Context = getLocationContext()->getAnalysisDeclContext()->getASTContext(); diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index bf2f730618650..3a052eb27a444 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -379,8 +379,10 @@ void ClassifyRefs::classify(const Expr *E, Class C) { } FindVarResult Var = findVar(E, DC); - if (const DeclRefExpr *DRE = Var.getDeclRefExpr()) - Classification[DRE] = std::max(Classification[DRE], C); + if (const DeclRefExpr *DRE = Var.getDeclRefExpr()) { + auto &Class = Classification[DRE]; + Class = std::max(Class, C); + } } void ClassifyRefs::VisitDeclStmt(DeclStmt *DS) { diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index c064aa30e8aed..c51398698922b 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -930,7 +930,7 @@ AST_MATCHER(CallExpr, hasUnsafeSnprintfBuffer) { // The array element type must be compatible with `char` otherwise an // explicit cast will be needed, which will make this check unreachable. // Therefore, the array extent is same as its' bytewise size. - if (Size->EvaluateAsConstantExpr(ER, Ctx)) { + if (Size->EvaluateAsInt(ER, Ctx)) { APSInt EVal = ER.Val.getInt(); // Size must have integer type return APSInt::compareValues(EVal, APSInt(CAT->getSize(), true)) != 0; diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 588183788de32..e7829a461bbc5 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -29,54 +29,120 @@ const char *HeaderDesc::getName() const { llvm_unreachable("Unknown HeaderDesc::HeaderID enum"); } -static constexpr Builtin::Info BuiltinInfo[] = { - {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER, - ALL_LANGUAGES}, -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS}, +static constexpr unsigned NumBuiltins = Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { + Builtin::Info{}, // No-builtin info entry. +#define GET_BUILTIN_INFOS #include "clang/Basic/Builtins.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); -const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const { - if (ID < Builtin::FirstTSBuiltin) - return BuiltinInfo[ID]; - assert(((ID - Builtin::FirstTSBuiltin) < - (TSRecords.size() + AuxTSRecords.size())) && +std::pair +Builtin::Context::getShardAndInfo(unsigned ID) const { + assert((ID < (Builtin::FirstTSBuiltin + NumTargetBuiltins + + NumAuxTargetBuiltins)) && "Invalid builtin ID!"); - if (isAuxBuiltinID(ID)) - return AuxTSRecords[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]; - return TSRecords[ID - Builtin::FirstTSBuiltin]; + + ArrayRef Shards = BuiltinShards; + if (isAuxBuiltinID(ID)) { + Shards = AuxTargetShards; + ID = getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin; + } else if (ID >= Builtin::FirstTSBuiltin) { + Shards = TargetShards; + ID -= Builtin::FirstTSBuiltin; + } + + // Loop over the shards to find the one matching this ID. We don't expect to + // have many shards and so its better to search linearly than with a binary + // search. + for (const auto &Shard : Shards) { + if (ID < Shard.Infos.size()) { + return {Shard, Shard.Infos[ID]}; + } + + ID -= Shard.Infos.size(); + } + llvm_unreachable("Invalid target builtin shard structure!"); +} + +std::string Builtin::Info::getName(const Builtin::InfosShard &Shard) const { + return (Twine(Shard.NamePrefix) + (*Shard.Strings)[Offsets.Name]).str(); +} + +/// Return the identifier name for the specified builtin, +/// e.g. "__builtin_abs". +std::string Builtin::Context::getName(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return I.getName(Shard); +} + +std::string Builtin::Context::getQuotedName(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (Twine("'") + Shard.NamePrefix + (*Shard.Strings)[I.Offsets.Name] + + "'") + .str(); +} + +const char *Builtin::Context::getTypeString(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (*Shard.Strings)[I.Offsets.Type].data(); } +const char *Builtin::Context::getAttributesString(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (*Shard.Strings)[I.Offsets.Attributes].data(); +} + +const char *Builtin::Context::getRequiredFeatures(unsigned ID) const { + const auto &[Shard, I] = getShardAndInfo(ID); + return (*Shard.Strings)[I.Offsets.Features].data(); +} + +Builtin::Context::Context() : BuiltinShards{{&BuiltinStrings, BuiltinInfos}} {} + void Builtin::Context::InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget) { - assert(TSRecords.empty() && "Already initialized target?"); - TSRecords = Target.getTargetBuiltins(); - if (AuxTarget) - AuxTSRecords = AuxTarget->getTargetBuiltins(); + assert(TargetShards.empty() && "Already initialized target?"); + assert(NumTargetBuiltins == 0 && "Already initialized target?"); + TargetShards = Target.getTargetBuiltins(); + for (const auto &Shard : TargetShards) + NumTargetBuiltins += Shard.Infos.size(); + if (AuxTarget) { + AuxTargetShards = AuxTarget->getTargetBuiltins(); + for (const auto &Shard : AuxTargetShards) + NumAuxTargetBuiltins += Shard.Infos.size(); + } } bool Builtin::Context::isBuiltinFunc(llvm::StringRef FuncName) { bool InStdNamespace = FuncName.consume_front("std-"); - for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; - ++i) { - if (FuncName == BuiltinInfo[i].Name && - (bool)strchr(BuiltinInfo[i].Attributes, 'z') == InStdNamespace) - return strchr(BuiltinInfo[i].Attributes, 'f') != nullptr; - } + for (const auto &Shard : {InfosShard{&BuiltinStrings, BuiltinInfos}}) + if (llvm::StringRef FuncNameSuffix = FuncName; + FuncNameSuffix.consume_front(Shard.NamePrefix)) + for (const auto &I : Shard.Infos) + if (FuncNameSuffix == (*Shard.Strings)[I.Offsets.Name] && + (bool)strchr((*Shard.Strings)[I.Offsets.Attributes].data(), 'z') == + InStdNamespace) + return strchr((*Shard.Strings)[I.Offsets.Attributes].data(), 'f') != + nullptr; return false; } /// Is this builtin supported according to the given language options? -static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, +static bool builtinIsSupported(const llvm::StringTable &Strings, + const Builtin::Info &BuiltinInfo, const LangOptions &LangOpts) { + auto AttributesStr = Strings[BuiltinInfo.Offsets.Attributes]; + /* Builtins Unsupported */ - if (LangOpts.NoBuiltin && strchr(BuiltinInfo.Attributes, 'f') != nullptr) + if (LangOpts.NoBuiltin && strchr(AttributesStr.data(), 'f') != nullptr) return false; /* CorBuiltins Unsupported */ if (!LangOpts.Coroutines && (BuiltinInfo.Langs & COR_LANG)) @@ -123,7 +189,7 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG) return false; /* consteval Unsupported */ - if (!LangOpts.CPlusPlus20 && strchr(BuiltinInfo.Attributes, 'G') != nullptr) + if (!LangOpts.CPlusPlus20 && strchr(AttributesStr.data(), 'G') != nullptr) return false; return true; } @@ -132,22 +198,34 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, /// appropriate builtin ID # and mark any non-portable builtin identifiers as /// such. void Builtin::Context::initializeBuiltins(IdentifierTable &Table, - const LangOptions& LangOpts) { - // Step #1: mark all target-independent builtins with their ID's. - for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; ++i) - if (builtinIsSupported(BuiltinInfo[i], LangOpts)) { - Table.get(BuiltinInfo[i].Name).setBuiltinID(i); - } - - // Step #2: Register target-specific builtins. - for (unsigned i = 0, e = TSRecords.size(); i != e; ++i) - if (builtinIsSupported(TSRecords[i], LangOpts)) - Table.get(TSRecords[i].Name).setBuiltinID(i + Builtin::FirstTSBuiltin); + const LangOptions &LangOpts) { + { + unsigned ID = 0; + // Step #1: mark all target-independent builtins with their ID's. + for (const auto &Shard : BuiltinShards) + for (const auto &I : Shard.Infos) { + // If this is a real builtin (ID != 0) and is supported, add it. + if (ID != 0 && builtinIsSupported(*Shard.Strings, I, LangOpts)) + Table.get(I.getName(Shard)).setBuiltinID(ID); + ++ID; + } + assert(ID == FirstTSBuiltin && "Should have added all non-target IDs!"); + + // Step #2: Register target-specific builtins. + for (const auto &Shard : TargetShards) + for (const auto &I : Shard.Infos) { + if (builtinIsSupported(*Shard.Strings, I, LangOpts)) + Table.get(I.getName(Shard)).setBuiltinID(ID); + ++ID; + } - // Step #3: Register target-specific builtins for AuxTarget. - for (unsigned i = 0, e = AuxTSRecords.size(); i != e; ++i) - Table.get(AuxTSRecords[i].Name) - .setBuiltinID(i + Builtin::FirstTSBuiltin + TSRecords.size()); + // Step #3: Register target-specific builtins for AuxTarget. + for (const auto &Shard : AuxTargetShards) + for (const auto &I : Shard.Infos) { + Table.get(I.getName(Shard)).setBuiltinID(ID); + ++ID; + } + } // Step #4: Unregister any builtins specified by -fno-builtin-foo. for (llvm::StringRef Name : LangOpts.NoBuiltinFuncs) { @@ -163,12 +241,8 @@ void Builtin::Context::initializeBuiltins(IdentifierTable &Table, } } -std::string Builtin::Context::getQuotedName(unsigned ID) const { - return (llvm::Twine("'") + getName(ID) + "'").str(); -} - unsigned Builtin::Context::getRequiredVectorWidth(unsigned ID) const { - const char *WidthPos = ::strchr(getRecord(ID).Attributes, 'V'); + const char *WidthPos = ::strchr(getAttributesString(ID), 'V'); if (!WidthPos) return 0; @@ -191,7 +265,7 @@ bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx, assert(::toupper(Fmt[0]) == Fmt[1] && "Format string is not in the form \"xX\""); - const char *Like = ::strpbrk(getRecord(ID).Attributes, Fmt); + const char *Like = ::strpbrk(getAttributesString(ID), Fmt); if (!Like) return false; @@ -218,7 +292,7 @@ bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx, bool Builtin::Context::performsCallback(unsigned ID, SmallVectorImpl &Encoding) const { - const char *CalleePos = ::strchr(getRecord(ID).Attributes, 'C'); + const char *CalleePos = ::strchr(getAttributesString(ID), 'C'); if (!CalleePos) return false; diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index ae71758bc81e0..9e2f134135647 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -145,7 +145,7 @@ void DiagnosticsEngine::Reset(bool soft /*=false*/) { // Create a DiagState and DiagStatePoint representing diagnostic changes // through command-line. - DiagStates.emplace_back(); + DiagStates.emplace_back(*Diags); DiagStatesByLoc.appendFirst(&DiagStates.back()); } } @@ -156,8 +156,11 @@ DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) { DiagMap.insert(std::make_pair(Diag, DiagnosticMapping())); // Initialize the entry if we added it. - if (Result.second) - Result.first->second = DiagnosticIDs::getDefaultMapping(Diag); + if (Result.second) { + Result.first->second = DiagIDs.getDefaultMapping(Diag); + if (DiagnosticIDs::IsCustomDiag(Diag)) + DiagIDs.initCustomDiagMapping(Result.first->second, Diag); + } return Result.first->second; } @@ -299,7 +302,8 @@ void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr, for (auto &Mapping : *Transition.State) { StringRef Option = - DiagnosticIDs::getWarningOptionForDiag(Mapping.first); + SrcMgr.getDiagnostics().Diags->getWarningOptionForDiag( + Mapping.first); if (!DiagName.empty() && DiagName != Option) continue; @@ -343,9 +347,7 @@ void DiagnosticsEngine::PushDiagStatePoint(DiagState *State, void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation L) { - assert(Diag < diag::DIAG_UPPER_LIMIT && - "Can only map builtin diagnostics"); - assert((Diags->isBuiltinWarningOrExtension(Diag) || + assert((Diags->isWarningOrExtension(Diag) || (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) && "Cannot map errors into warnings!"); assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location"); @@ -397,6 +399,8 @@ bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor, if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags)) return true; + Diags->setGroupSeverity(Group, Map); + // Set the mapping. for (diag::kind Diag : GroupDiags) setSeverity(Diag, Map, Loc); @@ -419,6 +423,7 @@ bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, if (Enabled) return setSeverityForGroup(diag::Flavor::WarningOrError, Group, diag::Severity::Error); + Diags->setGroupSeverity(Group, diag::Severity::Warning); // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and // potentially downgrade anything already mapped to be a warning. @@ -450,6 +455,7 @@ bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, if (Enabled) return setSeverityForGroup(diag::Flavor::WarningOrError, Group, diag::Severity::Fatal); + Diags->setGroupSeverity(Group, diag::Severity::Error); // Otherwise, we want to set the diagnostic mapping's "no Wfatal-errors" bit, // and potentially downgrade anything already mapped to be a fatal error. @@ -482,7 +488,7 @@ void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor, // Set the mapping. for (diag::kind Diag : AllDiags) - if (Diags->isBuiltinWarningOrExtension(Diag)) + if (Diags->isWarningOrExtension(Diag)) setSeverity(Diag, Map, Loc); } diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index de1de6f61f3a1..ca5b8d2da769e 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -62,13 +62,12 @@ const uint32_t StaticDiagInfoDescriptionOffsets[] = { #undef DIAG }; -// Diagnostic classes. enum DiagnosticClass { - CLASS_NOTE = 0x01, - CLASS_REMARK = 0x02, - CLASS_WARNING = 0x03, - CLASS_EXTENSION = 0x04, - CLASS_ERROR = 0x05 + CLASS_NOTE = DiagnosticIDs::CLASS_NOTE, + CLASS_REMARK = DiagnosticIDs::CLASS_REMARK, + CLASS_WARNING = DiagnosticIDs::CLASS_WARNING, + CLASS_EXTENSION = DiagnosticIDs::CLASS_EXTENSION, + CLASS_ERROR = DiagnosticIDs::CLASS_ERROR, }; struct StaticDiagInfoRec { @@ -229,11 +228,60 @@ CATEGORY(INSTALLAPI, REFACTORING) return Found; } -DiagnosticMapping DiagnosticIDs::getDefaultMapping(unsigned DiagID) { +//===----------------------------------------------------------------------===// +// Custom Diagnostic information +//===----------------------------------------------------------------------===// + +namespace clang { +namespace diag { +using CustomDiagDesc = DiagnosticIDs::CustomDiagDesc; +class CustomDiagInfo { + std::vector DiagInfo; + std::map DiagIDs; + std::map> GroupToDiags; + +public: + /// getDescription - Return the description of the specified custom + /// diagnostic. + const CustomDiagDesc &getDescription(unsigned DiagID) const { + assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && + "Invalid diagnostic ID"); + return DiagInfo[DiagID - DIAG_UPPER_LIMIT]; + } + + unsigned getOrCreateDiagID(DiagnosticIDs::CustomDiagDesc D) { + // Check to see if it already exists. + std::map::iterator I = DiagIDs.lower_bound(D); + if (I != DiagIDs.end() && I->first == D) + return I->second; + + // If not, assign a new ID. + unsigned ID = DiagInfo.size() + DIAG_UPPER_LIMIT; + DiagIDs.insert(std::make_pair(D, ID)); + DiagInfo.push_back(D); + if (auto Group = D.GetGroup()) + GroupToDiags[*Group].emplace_back(ID); + return ID; + } + + ArrayRef getDiagsInGroup(diag::Group G) const { + if (auto Diags = GroupToDiags.find(G); Diags != GroupToDiags.end()) + return Diags->second; + return {}; + } +}; + +} // namespace diag +} // namespace clang + +DiagnosticMapping DiagnosticIDs::getDefaultMapping(unsigned DiagID) const { DiagnosticMapping Info = DiagnosticMapping::Make( diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false); - if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) { + if (IsCustomDiag(DiagID)) { + Info.setSeverity( + CustomDiagInfo->getDescription(DiagID).GetDefaultSeverity()); + } else if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) { Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity); if (StaticInfo->WarnNoWerror) { @@ -246,6 +294,22 @@ DiagnosticMapping DiagnosticIDs::getDefaultMapping(unsigned DiagID) { return Info; } +void DiagnosticIDs::initCustomDiagMapping(DiagnosticMapping &Mapping, + unsigned DiagID) { + assert(IsCustomDiag(DiagID)); + const auto &Diag = CustomDiagInfo->getDescription(DiagID); + if (auto Group = Diag.GetGroup()) { + GroupInfo GroupInfo = GroupInfos[static_cast(*Group)]; + if (static_cast(GroupInfo.Severity) != diag::Severity()) + Mapping.setSeverity(static_cast(GroupInfo.Severity)); + Mapping.setNoWarningAsError(GroupInfo.HasNoWarningAsError); + } else { + Mapping.setSeverity(Diag.GetDefaultSeverity()); + Mapping.setNoWarningAsError(true); + Mapping.setNoErrorAsFatal(true); + } +} + /// getCategoryNumberForDiag - Return the category number that a specified /// DiagID belongs to, or 0 if no category. unsigned DiagnosticIDs::getCategoryNumberForDiag(unsigned DiagID) { @@ -303,61 +367,6 @@ bool DiagnosticIDs::isDeferrable(unsigned DiagID) { return false; } -/// getBuiltinDiagClass - Return the class field of the diagnostic. -/// -static unsigned getBuiltinDiagClass(unsigned DiagID) { - if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) - return Info->Class; - return ~0U; -} - -//===----------------------------------------------------------------------===// -// Custom Diagnostic information -//===----------------------------------------------------------------------===// - -namespace clang { - namespace diag { - class CustomDiagInfo { - typedef std::pair DiagDesc; - std::vector DiagInfo; - std::map DiagIDs; - public: - - /// getDescription - Return the description of the specified custom - /// diagnostic. - StringRef getDescription(unsigned DiagID) const { - assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && - "Invalid diagnostic ID"); - return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second; - } - - /// getLevel - Return the level of the specified custom diagnostic. - DiagnosticIDs::Level getLevel(unsigned DiagID) const { - assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() && - "Invalid diagnostic ID"); - return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first; - } - - unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message, - DiagnosticIDs &Diags) { - DiagDesc D(L, std::string(Message)); - // Check to see if it already exists. - std::map::iterator I = DiagIDs.lower_bound(D); - if (I != DiagIDs.end() && I->first == D) - return I->second; - - // If not, assign a new ID. - unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT; - DiagIDs.insert(std::make_pair(D, ID)); - DiagInfo.push_back(D); - return ID; - } - }; - - } // end diag namespace -} // end clang namespace - - //===----------------------------------------------------------------------===// // Common Diagnostic implementation //===----------------------------------------------------------------------===// @@ -372,38 +381,32 @@ DiagnosticIDs::~DiagnosticIDs() {} /// /// \param FormatString A fixed diagnostic format string that will be hashed and /// mapped to a unique DiagID. -unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString) { +unsigned DiagnosticIDs::getCustomDiagID(CustomDiagDesc Diag) { if (!CustomDiagInfo) CustomDiagInfo.reset(new diag::CustomDiagInfo()); - return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *this); + return CustomDiagInfo->getOrCreateDiagID(Diag); } - -/// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic -/// level of the specified diagnostic ID is a Warning or Extension. -/// This only works on builtin diagnostics, not custom ones, and is not legal to -/// call on NOTEs. -bool DiagnosticIDs::isBuiltinWarningOrExtension(unsigned DiagID) { - return DiagID < diag::DIAG_UPPER_LIMIT && - getBuiltinDiagClass(DiagID) != CLASS_ERROR; +bool DiagnosticIDs::isWarningOrExtension(unsigned DiagID) const { + return DiagID < diag::DIAG_UPPER_LIMIT + ? getDiagClass(DiagID) != CLASS_ERROR + : CustomDiagInfo->getDescription(DiagID).GetClass() != CLASS_ERROR; } /// Determine whether the given built-in diagnostic ID is a /// Note. -bool DiagnosticIDs::isBuiltinNote(unsigned DiagID) { - return DiagID < diag::DIAG_UPPER_LIMIT && - getBuiltinDiagClass(DiagID) == CLASS_NOTE; +bool DiagnosticIDs::isNote(unsigned DiagID) const { + return DiagID < diag::DIAG_UPPER_LIMIT && getDiagClass(DiagID) == CLASS_NOTE; } -/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic +/// isExtensionDiag - Determine whether the given built-in diagnostic /// ID is for an extension of some sort. This also returns EnabledByDefault, /// which is set to indicate whether the diagnostic is ignored by default (in /// which case -pedantic enables it) or treated as a warning/error by default. /// -bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID, - bool &EnabledByDefault) { - if (DiagID >= diag::DIAG_UPPER_LIMIT || - getBuiltinDiagClass(DiagID) != CLASS_EXTENSION) +bool DiagnosticIDs::isExtensionDiag(unsigned DiagID, + bool &EnabledByDefault) const { + if (IsCustomDiag(DiagID) || getDiagClass(DiagID) != CLASS_EXTENSION) return false; EnabledByDefault = @@ -411,10 +414,7 @@ bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID, return true; } -bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) { - if (DiagID >= diag::DIAG_UPPER_LIMIT) - return false; - +bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) const { return getDefaultMapping(DiagID).getSeverity() >= diag::Severity::Error; } @@ -424,7 +424,7 @@ StringRef DiagnosticIDs::getDescription(unsigned DiagID) const { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) return Info->getDescription(); assert(CustomDiagInfo && "Invalid CustomDiagInfo"); - return CustomDiagInfo->getDescription(DiagID); + return CustomDiagInfo->getDescription(DiagID).GetDescription(); } static DiagnosticIDs::Level toLevel(diag::Severity SV) { @@ -449,13 +449,7 @@ static DiagnosticIDs::Level toLevel(diag::Severity SV) { DiagnosticIDs::Level DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, const DiagnosticsEngine &Diag) const { - // Handle custom diagnostics, which cannot be mapped. - if (DiagID >= diag::DIAG_UPPER_LIMIT) { - assert(CustomDiagInfo && "Invalid CustomDiagInfo"); - return CustomDiagInfo->getLevel(DiagID); - } - - unsigned DiagClass = getBuiltinDiagClass(DiagID); + unsigned DiagClass = getDiagClass(DiagID); if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note; return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag)); } @@ -469,7 +463,8 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, diag::Severity DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, const DiagnosticsEngine &Diag) const { - assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE); + bool IsCustomDiag = DiagnosticIDs::IsCustomDiag(DiagID); + assert(getDiagClass(DiagID) != CLASS_NOTE); // Specific non-error diagnostics may be mapped to various levels from ignored // to error. Errors can only be mapped to fatal. @@ -477,7 +472,7 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, // Get the mapping information, or compute it lazily. DiagnosticsEngine::DiagState *State = Diag.GetDiagStateForLoc(Loc); - DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID); + DiagnosticMapping Mapping = State->getOrAddMapping((diag::kind)DiagID); // TODO: Can a null severity really get here? if (Mapping.getSeverity() != diag::Severity()) @@ -485,14 +480,15 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, // Upgrade ignored diagnostics if -Weverything is enabled. if (State->EnableAllWarnings && Result == diag::Severity::Ignored && - !Mapping.isUser() && getBuiltinDiagClass(DiagID) != CLASS_REMARK) + !Mapping.isUser() && + (IsCustomDiag || getDiagClass(DiagID) != CLASS_REMARK)) Result = diag::Severity::Warning; // Ignore -pedantic diagnostics inside __extension__ blocks. // (The diagnostics controlled by -pedantic are the extension diagnostics // that are not enabled by default.) bool EnabledByDefault = false; - bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault); + bool IsExtensionDiag = isExtensionDiag(DiagID, EnabledByDefault); if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault) return diag::Severity::Ignored; @@ -510,10 +506,12 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, // as well as disabling all messages which are currently mapped to Warning // (whether by default or downgraded from Error via e.g. -Wno-error or #pragma // diagnostic.) + // FIXME: Should -w be ignored for custom warnings without a group? if (State->IgnoreAllWarnings) { - if (Result == diag::Severity::Warning || - (Result >= diag::Severity::Error && - !isDefaultMappingAsError((diag::kind)DiagID))) + if ((!IsCustomDiag || CustomDiagInfo->getDescription(DiagID).GetGroup()) && + (Result == diag::Severity::Warning || + (Result >= diag::Severity::Error && + !isDefaultMappingAsError((diag::kind)DiagID)))) return diag::Severity::Ignored; } @@ -541,9 +539,11 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, return Result; const auto &SM = Diag.getSourceManager(); - // Custom diagnostics always are emitted in system headers. + bool ShowInSystemHeader = - !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader; + IsCustomDiag + ? CustomDiagInfo->getDescription(DiagID).ShouldShowInSystemHeader() + : !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader; // If we are in a system header, we ignore it. We look at the diagnostic class // because we also want to ignore extensions and warnings in -Werror and @@ -566,6 +566,15 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, return Result; } +DiagnosticIDs::Class DiagnosticIDs::getDiagClass(unsigned DiagID) const { + if (IsCustomDiag(DiagID)) + return Class(CustomDiagInfo->getDescription(DiagID).GetClass()); + + if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) + return Class(Info->Class); + return CLASS_INVALID; +} + #define GET_DIAG_ARRAYS #include "clang/Basic/DiagnosticGroups.inc" #undef GET_DIAG_ARRAYS @@ -607,7 +616,12 @@ DiagnosticIDs::getGroupForWarningOption(StringRef Name) { return static_cast(Found - OptionTable); } -std::optional DiagnosticIDs::getGroupForDiag(unsigned DiagID) { +std::optional +DiagnosticIDs::getGroupForDiag(unsigned DiagID) const { + if (IsCustomDiag(DiagID)) { + assert(CustomDiagInfo); + return CustomDiagInfo->getDescription(DiagID).GetGroup(); + } if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) return static_cast(Info->getOptionGroupIndex()); return std::nullopt; @@ -639,7 +653,8 @@ std::vector DiagnosticIDs::getDiagnosticFlags() { /// were filtered out due to having the wrong flavor. static bool getDiagnosticsInGroup(diag::Flavor Flavor, const WarningOption *Group, - SmallVectorImpl &Diags) { + SmallVectorImpl &Diags, + diag::CustomDiagInfo *CustomDiagInfo) { // An empty group is considered to be a warning group: we have empty groups // for GCC compatibility, and GCC does not have remarks. if (!Group->Members && !Group->SubGroups) @@ -658,9 +673,14 @@ static bool getDiagnosticsInGroup(diag::Flavor Flavor, // Add the members of the subgroups. const int16_t *SubGroups = DiagSubGroups + Group->SubGroups; - for (; *SubGroups != (int16_t)-1; ++SubGroups) + for (; *SubGroups != (int16_t)-1; ++SubGroups) { + if (CustomDiagInfo) + llvm::copy( + CustomDiagInfo->getDiagsInGroup(static_cast(*SubGroups)), + std::back_inserter(Diags)); NotFound &= getDiagnosticsInGroup(Flavor, &OptionTable[(short)*SubGroups], - Diags); + Diags, CustomDiagInfo); + } return NotFound; } @@ -668,12 +688,49 @@ static bool getDiagnosticsInGroup(diag::Flavor Flavor, bool DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group, SmallVectorImpl &Diags) const { - if (std::optional G = getGroupForWarningOption(Group)) - return ::getDiagnosticsInGroup( - Flavor, &OptionTable[static_cast(*G)], Diags); + if (std::optional G = getGroupForWarningOption(Group)) { + if (CustomDiagInfo) + llvm::copy(CustomDiagInfo->getDiagsInGroup(*G), + std::back_inserter(Diags)); + return ::getDiagnosticsInGroup(Flavor, + &OptionTable[static_cast(*G)], + Diags, CustomDiagInfo.get()); + } return true; } +template +static void forEachSubGroupImpl(const WarningOption *Group, Func func) { + for (const int16_t *SubGroups = DiagSubGroups + Group->SubGroups; + *SubGroups != -1; ++SubGroups) { + func(static_cast(*SubGroups)); + forEachSubGroupImpl(&OptionTable[*SubGroups], std::move(func)); + } +} + +template +static void forEachSubGroup(diag::Group Group, Func func) { + const WarningOption *WarningOpt = &OptionTable[static_cast(Group)]; + func(static_cast(Group)); + ::forEachSubGroupImpl(WarningOpt, std::move(func)); +} + +void DiagnosticIDs::setGroupSeverity(StringRef Group, diag::Severity Sev) { + if (std::optional G = getGroupForWarningOption(Group)) { + ::forEachSubGroup(*G, [&](size_t SubGroup) { + GroupInfos[SubGroup].Severity = static_cast(Sev); + }); + } +} + +void DiagnosticIDs::setGroupNoWarningsAsError(StringRef Group, bool Val) { + if (std::optional G = getGroupForWarningOption(Group)) { + ::forEachSubGroup(*G, [&](size_t SubGroup) { + GroupInfos[static_cast(*G)].HasNoWarningAsError = Val; + }); + } +} + void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor, std::vector &Diags) { for (unsigned i = 0; i != StaticDiagInfoSize; ++i) @@ -696,7 +753,7 @@ StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor, // Don't suggest groups that are not of this kind. llvm::SmallVector Diags; - if (::getDiagnosticsInGroup(Flavor, &O, Diags) || Diags.empty()) + if (::getDiagnosticsInGroup(Flavor, &O, Diags, nullptr) || Diags.empty()) continue; if (Distance == BestDistance) { @@ -810,14 +867,8 @@ void DiagnosticIDs::EmitDiag(DiagnosticsEngine &Diag, } bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const { - if (DiagID >= diag::DIAG_UPPER_LIMIT) { - assert(CustomDiagInfo && "Invalid CustomDiagInfo"); - // Custom diagnostics. - return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error; - } - // Only errors may be unrecoverable. - if (getBuiltinDiagClass(DiagID) < CLASS_ERROR) + if (getDiagClass(DiagID) < CLASS_ERROR) return false; if (DiagID == diag::err_unavailable || diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 62a13f01481b2..956d92a7e95f0 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -765,6 +765,12 @@ bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) { return false; } +bool clang::isOpenMPOrderConcurrentNestableDirective( + OpenMPDirectiveKind DKind) { + return DKind == OMPD_atomic || DKind == OMPD_loop || DKind == OMPD_simd || + DKind == OMPD_parallel || isOpenMPLoopTransformationDirective(DKind); +} + void clang::getOpenMPCaptureRegions( SmallVectorImpl &CaptureRegions, OpenMPDirectiveKind DKind) { diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp index 5b9b88d032702..e0eff2a37b8a0 100644 --- a/clang/lib/Basic/Sanitizers.cpp +++ b/clang/lib/Basic/Sanitizers.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include +#include #include using namespace clang; @@ -43,6 +44,27 @@ std::optional SanitizerMaskCutoffs::operator[](unsigned Kind) const { void SanitizerMaskCutoffs::clear(SanitizerMask K) { set(K, 0); } +std::optional> +SanitizerMaskCutoffs::getAllScaled(unsigned ScalingFactor) const { + std::vector ScaledCutoffs; + + bool AnyCutoff = false; + for (unsigned int i = 0; i < SanitizerKind::SO_Count; ++i) { + auto C = (*this)[i]; + if (C.has_value()) { + ScaledCutoffs.push_back(lround(std::clamp(*C, 0.0, 1.0) * ScalingFactor)); + AnyCutoff = true; + } else { + ScaledCutoffs.push_back(0); + } + } + + if (AnyCutoff) + return ScaledCutoffs; + + return std::nullopt; +} + // Once LLVM switches to C++17, the constexpr variables can be inline and we // won't need this. #define SANITIZER(NAME, ID) constexpr SanitizerMask SanitizerKind::ID; diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index 0b899137bbb5c..fad8d773bfc52 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -26,36 +26,106 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsNEON.def" - -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsSVE.def" - -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsSME.def" - -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, -#include "clang/Basic/BuiltinsAArch64.def" +static constexpr int NumNeonBuiltins = + NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin; +static constexpr int NumFp16Builtins = + NEON::FirstTSBuiltin - NEON::FirstFp16Builtin; +static constexpr int NumSVEBuiltins = + SVE::FirstNeonBridgeBuiltin - NEON::FirstTSBuiltin; +static constexpr int NumSVENeonBridgeBuiltins = + SVE::FirstTSBuiltin - SVE::FirstNeonBridgeBuiltin; +static constexpr int NumSMEBuiltins = SME::FirstTSBuiltin - SVE::FirstTSBuiltin; +static constexpr int NumAArch64Builtins = + AArch64::LastTSBuiltin - SME::FirstTSBuiltin; +static constexpr int NumBuiltins = + AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == + (NumNeonBuiltins + NumFp16Builtins + NumSVEBuiltins + + NumSVENeonBridgeBuiltins + NumSMEBuiltins + NumAArch64Builtins)); + +namespace clang { +namespace NEON { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_INFOS }; +namespace FP16 { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_INFOS +}; +} // namespace FP16 +} // namespace NEON + +namespace SVE { +#define GET_SVE_BUILTIN_STR_TABLE +#include "clang/Basic/arm_sve_builtins.inc" +#undef GET_SVE_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_SVE_BUILTIN_INFOS +#include "clang/Basic/arm_sve_builtins.inc" +#undef GET_SVE_BUILTIN_INFOS +}; +} // namespace SVE + +namespace SME { +#define GET_SME_BUILTIN_STR_TABLE +#include "clang/Basic/arm_sme_builtins.inc" +#undef GET_SME_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_SME_BUILTIN_INFOS +#include "clang/Basic/arm_sme_builtins.inc" +#undef GET_SME_BUILTIN_INFOS +}; +} // namespace SME +} // namespace clang + +static constexpr llvm::StringTable BuiltinSVENeonBridgeStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#define GET_SVE_BUILTINS +#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def" +#undef GET_SVE_BUILTINS +#undef TARGET_BUILTIN + ; +static constexpr llvm::StringTable BuiltinAArch64Strings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsAArch64.def" + ; + +static constexpr auto BuiltinSVENeonBridgeInfos = + Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define GET_SVE_BUILTINS +#include "clang/Basic/BuiltinsAArch64NeonSVEBridge.def" +#undef GET_SVE_BUILTINS +#undef TARGET_BUILTIN + }); +static constexpr auto BuiltinAArch64Infos = + Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsAArch64.def" + }); + void AArch64TargetInfo::setArchFeatures() { if (*ArchInfo == llvm::AArch64::ARMV8R) { HasDotProd = true; @@ -253,11 +323,19 @@ bool AArch64TargetInfo::validateGlobalRegisterVariable( bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, BranchProtectionInfo &BPI, + const LangOptions &LO, StringRef &Err) const { llvm::ARM::ParsedBranchProtection PBP; if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err, HasPAuthLR)) return false; + // GCS is currently untested with ptrauth-returns, but enabling this could be + // allowed in future after testing with a suitable system. + if (LO.PointerAuthReturns && + (PBP.Scope != "none" || PBP.BranchProtectionPAuthLR || + PBP.GuardedControlStack)) + return false; + BPI.SignReturnAddr = llvm::StringSwitch(PBP.Scope) .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) @@ -697,18 +775,27 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, } } -ArrayRef AArch64TargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +AArch64TargetInfo::getTargetBuiltins() const { + return { + {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"}, + {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos, + "__builtin_neon_"}, + {&SVE::BuiltinStrings, SVE::BuiltinInfos, "__builtin_sve_"}, + {&BuiltinSVENeonBridgeStrings, BuiltinSVENeonBridgeInfos}, + {&SME::BuiltinStrings, SME::BuiltinInfos, "__builtin_sme_"}, + {&BuiltinAArch64Strings, BuiltinAArch64Infos}, + }; } std::optional> -AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { +AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts, + bool IsArmStreamingFunction) const { if (LangOpts.VScaleMin || LangOpts.VScaleMax) return std::pair( LangOpts.VScaleMin ? LangOpts.VScaleMin : 1, LangOpts.VScaleMax); - if (hasFeature("sve")) + if (hasFeature("sve") || (IsArmStreamingFunction && hasFeature("sme"))) return std::pair(1, 16); return std::nullopt; diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index ecf80b23a508c..9b6451bd06316 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -44,6 +44,7 @@ static const unsigned ARM64AddrSpaceMap[] = { static_cast(AArch64AddrSpace::ptr32_uptr), static_cast(AArch64AddrSpace::ptr64), 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -131,6 +132,7 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, + const LangOptions &LO, StringRef &Err) const override; bool isValidCPUName(StringRef Name) const override; @@ -180,10 +182,11 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; std::optional> - getVScaleRange(const LangOptions &LangOpts) const override; + getVScaleRange(const LangOptions &LangOpts, + bool IsArmStreamingFunction) const override; bool doesFeatureAffectCodeGen(StringRef Name) const override; bool validateCpuSupports(StringRef FeatureStr) const override; bool hasFeature(StringRef Feature) const override; @@ -226,6 +229,11 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool validatePointerAuthKey(const llvm::APSInt &value) const override; const char *getBFloat16Mangling() const override { return "u6__bf16"; }; + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(256, 64); + } + bool hasInt128Type() const override; bool hasBitIntType() const override { return true; } diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 99f8f2944e279..228f967caf2f1 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -59,6 +59,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared + llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant }; const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { @@ -74,27 +75,35 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::CONSTANT_ADDRESS, // cuda_constant llvm::AMDGPUAS::LOCAL_ADDRESS, // cuda_shared // SYCL address space values for this map are dummy - llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global - llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_device - llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host - llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local - llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private - llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr - llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr - llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 - llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared - + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_device + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_global_host + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_local + llvm::AMDGPUAS::FLAT_ADDRESS, // sycl_private + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_sptr + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr32_uptr + llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 + llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared + llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant }; } // namespace targets } // namespace clang -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsAMDGPU.def" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsAMDGPU.def" +}); const char *const AMDGPUTargetInfo::GCCRegNames[] = { "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", @@ -266,9 +275,9 @@ void AMDGPUTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { !isAMDGCN(getTriple())); } -ArrayRef AMDGPUTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +AMDGPUTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts, diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index ea4189cdea47d..3d6778fb5a76f 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -257,7 +257,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { StringRef CPU, const std::vector &FeatureVec) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool useFP16ConversionIntrinsics() const override { return false; } diff --git a/clang/lib/Basic/Targets/ARC.h b/clang/lib/Basic/Targets/ARC.h index 7f3d0aa15ab81..2b69f95591fa1 100644 --- a/clang/lib/Basic/Targets/ARC.h +++ b/clang/lib/Basic/Targets/ARC.h @@ -40,7 +40,9 @@ class LLVM_LIBRARY_VISIBILITY ARCTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp index 0fd5433a76402..ca2c1ffbb0eb7 100644 --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -405,6 +405,7 @@ bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const { bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, + const LangOptions &LO, StringRef &Err) const { llvm::ARM::ParsedBranchProtection PBP; if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) @@ -608,6 +609,8 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector &Features, HasBTI = 1; } else if (Feature == "+fullbf16") { HasFullBFloat16 = true; + } else if (Feature == "+execute-only") { + TLSSupported = false; } } @@ -1072,31 +1075,99 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts, } } -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsNEON.def" - -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, -#include "clang/Basic/BuiltinsARM.def" +static constexpr int NumBuiltins = ARM::LastTSBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumNeonBuiltins = + NEON::FirstFp16Builtin - Builtin::FirstTSBuiltin; +static constexpr int NumFp16Builtins = + NEON::FirstTSBuiltin - NEON::FirstFp16Builtin; +static constexpr int NumMVEBuiltins = + ARM::FirstCDEBuiltin - NEON::FirstTSBuiltin; +static constexpr int NumCDEBuiltins = + ARM::FirstARMBuiltin - ARM::FirstCDEBuiltin; +static constexpr int NumARMBuiltins = ARM::LastTSBuiltin - ARM::FirstARMBuiltin; +static_assert(NumBuiltins == + (NumNeonBuiltins + NumFp16Builtins + NumMVEBuiltins + + NumCDEBuiltins + NumARMBuiltins)); + +namespace clang { +namespace NEON { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_BUILTIN_INFOS +}; + +namespace FP16 { +#define GET_NEON_BUILTIN_STR_TABLE +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_NEON_BUILTIN_INFOS +#include "clang/Basic/arm_fp16.inc" +#undef GET_NEON_BUILTIN_INFOS +}; +} // namespace FP16 +} // namespace NEON +} // namespace clang + +namespace { +namespace MVE { +#define GET_MVE_BUILTIN_STR_TABLE +#include "clang/Basic/arm_mve_builtins.inc" +#undef GET_MVE_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_MVE_BUILTIN_INFOS +#include "clang/Basic/arm_mve_builtins.inc" +#undef GET_MVE_BUILTIN_INFOS }; +} // namespace MVE -ArrayRef ARMTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin); +namespace CDE { +#define GET_CDE_BUILTIN_STR_TABLE +#include "clang/Basic/arm_cde_builtins.inc" +#undef GET_CDE_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = { +#define GET_CDE_BUILTIN_INFOS +#include "clang/Basic/arm_cde_builtins.inc" +#undef GET_CDE_BUILTIN_INFOS +}; +} // namespace CDE +} // namespace + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsARM.def" + ; // namespace clang + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define TARGET_HEADER_BUILTIN CLANG_TARGET_HEADER_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsARM.def" +}); + +llvm::SmallVector +ARMTargetInfo::getTargetBuiltins() const { + return { + {&NEON::BuiltinStrings, NEON::BuiltinInfos, "__builtin_neon_"}, + {&NEON::FP16::BuiltinStrings, NEON::FP16::BuiltinInfos, + "__builtin_neon_"}, + {&MVE::BuiltinStrings, MVE::BuiltinInfos, "__builtin_arm_mve_"}, + {&CDE::BuiltinStrings, CDE::BuiltinInfos, "__builtin_arm_cde_"}, + {&BuiltinStrings, BuiltinInfos}, + }; } bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h index fdb40c3d41918..1719217ca25b7 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -155,6 +155,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { bool isBranchProtectionSupportedArch(StringRef Arch) const override; bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, + const LangOptions &LO, StringRef &Err) const override; // FIXME: This should be based on Arch attributes, not CPU names. @@ -196,7 +197,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool isCLZForZeroUndef() const override; BuiltinVaListKind getBuiltinVaListKind() const override; @@ -227,7 +228,7 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { const char *getBFloat16Mangling() const override { return "u6__bf16"; }; std::pair hardwareInterferenceSizes() const override { - return std::make_pair(getTriple().isArch64Bit() ? 256 : 64, 64); + return std::make_pair(64, 64); } }; diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h index df1f8d171efba..2117ab58e6f30 100644 --- a/clang/lib/Basic/Targets/AVR.h +++ b/clang/lib/Basic/Targets/AVR.h @@ -63,7 +63,9 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } bool allowsLargerPreferedTypeAlignment() const override { return false; } diff --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp index f4684765b7ffb..a463de0884020 100644 --- a/clang/lib/Basic/Targets/BPF.cpp +++ b/clang/lib/Basic/Targets/BPF.cpp @@ -19,11 +19,19 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsBPF.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsBPF.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -81,9 +89,9 @@ void BPFTargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); } -ArrayRef BPFTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::BPF::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +BPFTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } bool BPFTargetInfo::handleTargetFeatures(std::vector &Features, diff --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h index 27a4b5f314970..d1f68b842348e 100644 --- a/clang/lib/Basic/Targets/BPF.h +++ b/clang/lib/Basic/Targets/BPF.h @@ -58,7 +58,7 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo { bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; std::string_view getClobbers() const override { return ""; } diff --git a/clang/lib/Basic/Targets/CSKY.cpp b/clang/lib/Basic/Targets/CSKY.cpp index c8bf8b9234d24..e698508a2370c 100644 --- a/clang/lib/Basic/Targets/CSKY.cpp +++ b/clang/lib/Basic/Targets/CSKY.cpp @@ -139,10 +139,6 @@ bool CSKYTargetInfo::handleTargetFeatures(std::vector &Features, return true; } -ArrayRef CSKYTargetInfo::getTargetBuiltins() const { - return ArrayRef(); -} - ArrayRef CSKYTargetInfo::getGCCRegNames() const { static const char *const GCCRegNames[] = { // Integer registers diff --git a/clang/lib/Basic/Targets/CSKY.h b/clang/lib/Basic/Targets/CSKY.h index 94d4eeb9a1fff..ddfbe4794daad 100644 --- a/clang/lib/Basic/Targets/CSKY.h +++ b/clang/lib/Basic/Targets/CSKY.h @@ -73,7 +73,9 @@ class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo { unsigned getMinGlobalAlign(uint64_t, bool HasNonWeakDef) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } BuiltinVaListKind getBuiltinVaListKind() const override { return VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index ab22d1281a4df..6e3ddad626341 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -42,6 +42,7 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 3, // hlsl_groupshared + 2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -72,7 +73,9 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo { return Feature == "directx"; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } std::string_view getClobbers() const override { return ""; } diff --git a/clang/lib/Basic/Targets/Hexagon.cpp b/clang/lib/Basic/Targets/Hexagon.cpp index b5e06b679ece7..c19c2e76c511a 100644 --- a/clang/lib/Basic/Targets/Hexagon.cpp +++ b/clang/lib/Basic/Targets/Hexagon.cpp @@ -204,15 +204,26 @@ ArrayRef HexagonTargetInfo::getGCCRegAliases() const { return llvm::ArrayRef(GCCRegAliases); } -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsHexagon.def" +static constexpr int NumBuiltins = + clang::Hexagon::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_INFOS +}; + +static constexpr Builtin::Info PrefixedBuiltinInfos[] = { +#define GET_BUILTIN_PREFIXED_INFOS +#include "clang/Basic/BuiltinsHexagon.inc" +#undef GET_BUILTIN_PREFIXED_INFOS }; +static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == + NumBuiltins); bool HexagonTargetInfo::hasFeature(StringRef Feature) const { std::string VS = "hvxv" + HVXVersion; @@ -271,7 +282,8 @@ void HexagonTargetInfo::fillValidCPUList( Values.push_back(Suffix.Name); } -ArrayRef HexagonTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +HexagonTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}, + {&BuiltinStrings, PrefixedBuiltinInfos, "__builtin_HEXAGON_"}}; } diff --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h index 7f053ab7e4888..a65663ca09eee 100644 --- a/clang/lib/Basic/Targets/Hexagon.h +++ b/clang/lib/Basic/Targets/Hexagon.h @@ -66,7 +66,7 @@ class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { BoolWidth = BoolAlign = 8; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { diff --git a/clang/lib/Basic/Targets/Lanai.h b/clang/lib/Basic/Targets/Lanai.h index f7e439c7c9e1c..e32ef9d7d40da 100644 --- a/clang/lib/Basic/Targets/Lanai.h +++ b/clang/lib/Basic/Targets/Lanai.h @@ -78,7 +78,9 @@ class LLVM_LIBRARY_VISIBILITY LanaiTargetInfo : public TargetInfo { return TargetInfo::VoidPtrBuiltinVaList; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override { diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index bb0d0b68cfcb0..ca742797d7a3b 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -273,13 +273,55 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsLoongArch.def" -}; +static constexpr int NumBaseBuiltins = + LoongArch::FirstLSXBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumLSXBuiltins = + LoongArch::FirstLASXBuiltin - LoongArch::FirstLSXBuiltin; +static constexpr int NumLASXBuiltins = + LoongArch::LastTSBuiltin - LoongArch::FirstLASXBuiltin; +static constexpr int NumBuiltins = + LoongArch::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == + (NumBaseBuiltins + NumLSXBuiltins + NumLASXBuiltins)); + +static constexpr llvm::StringTable BuiltinBaseStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsLoongArchBase.def" +#undef TARGET_BUILTIN + ; + +static constexpr auto BuiltinBaseInfos = Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsLoongArchBase.def" +#undef TARGET_BUILTIN +}); + +static constexpr llvm::StringTable BuiltinLSXStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsLoongArchLSX.def" +#undef TARGET_BUILTIN + ; + +static constexpr auto BuiltinLSXInfos = Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsLoongArchLSX.def" +#undef TARGET_BUILTIN +}); + +static constexpr llvm::StringTable BuiltinLASXStrings = + CLANG_BUILTIN_STR_TABLE_START +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsLoongArchLASX.def" +#undef TARGET_BUILTIN + ; + +static constexpr auto BuiltinLASXInfos = Builtin::MakeInfos({ +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsLoongArchLASX.def" +#undef TARGET_BUILTIN +}); bool LoongArchTargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, @@ -306,9 +348,13 @@ bool LoongArchTargetInfo::hasFeature(StringRef Feature) const { .Default(false); } -ArrayRef LoongArchTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +LoongArchTargetInfo::getTargetBuiltins() const { + return { + {&BuiltinBaseStrings, BuiltinBaseInfos}, + {&BuiltinLSXStrings, BuiltinLSXInfos}, + {&BuiltinLASXStrings, BuiltinLASXInfos}, + }; } bool LoongArchTargetInfo::handleTargetFeatures( diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 5c34c84ff8d3e..4c7b53abfef9b 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -72,7 +72,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/M68k.cpp b/clang/lib/Basic/Targets/M68k.cpp index b5b29fd867563..e5b7f06829cd9 100644 --- a/clang/lib/Basic/Targets/M68k.cpp +++ b/clang/lib/Basic/Targets/M68k.cpp @@ -115,7 +115,8 @@ void M68kTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__HAVE_68881__"); } -ArrayRef M68kTargetInfo::getTargetBuiltins() const { +llvm::SmallVector +M68kTargetInfo::getTargetBuiltins() const { // FIXME: Implement. return {}; } diff --git a/clang/lib/Basic/Targets/M68k.h b/clang/lib/Basic/Targets/M68k.h index b732add77e034..729d79ff77fbf 100644 --- a/clang/lib/Basic/Targets/M68k.h +++ b/clang/lib/Basic/Targets/M68k.h @@ -44,7 +44,7 @@ class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasFeature(StringRef Feature) const override; ArrayRef getGCCRegNames() const override; ArrayRef getGCCRegAliases() const override; diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h index 2266ada25c1dd..d7d05f992f4f6 100644 --- a/clang/lib/Basic/Targets/MSP430.h +++ b/clang/lib/Basic/Targets/MSP430.h @@ -50,7 +50,7 @@ class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { + llvm::SmallVector getTargetBuiltins() const override { // FIXME: Implement. return {}; } diff --git a/clang/lib/Basic/Targets/Mips.cpp b/clang/lib/Basic/Targets/Mips.cpp index d56995e3ccc48..866be53c8a363 100644 --- a/clang/lib/Basic/Targets/Mips.cpp +++ b/clang/lib/Basic/Targets/Mips.cpp @@ -20,13 +20,20 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsMips.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY #include "clang/Basic/BuiltinsMips.def" -}; +}); bool MipsTargetInfo::processorSupportsGPR64() const { return llvm::StringSwitch(CPU) @@ -223,9 +230,9 @@ bool MipsTargetInfo::hasFeature(StringRef Feature) const { .Default(false); } -ArrayRef MipsTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +MipsTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } unsigned MipsTargetInfo::getUnwindWordWidth() const { diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index 7ddcd57053cb2..35501ed44ccd7 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -198,7 +198,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasFeature(StringRef Feature) const override; diff --git a/clang/lib/Basic/Targets/NVPTX.cpp b/clang/lib/Basic/Targets/NVPTX.cpp index 56efad90cb7c8..7d13c1f145440 100644 --- a/clang/lib/Basic/Targets/NVPTX.cpp +++ b/clang/lib/Basic/Targets/NVPTX.cpp @@ -20,15 +20,19 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsNVPTX.def" +static constexpr int NumBuiltins = + clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsNVPTX.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsNVPTX.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"}; @@ -66,12 +70,13 @@ NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple, HasFloat16 = true; if (TargetPointerWidth == 32) - resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"); - else if (Opts.NVPTXUseShortPointers) resetDataLayout( - "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"); + "e-p:32:32-p6:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"); + else if (Opts.NVPTXUseShortPointers) + resetDataLayout("e-p3:32:32-p4:32:32-p5:32:32-p6:32:32-i64:64-i128:128-v16:" + "16-v32:32-n16:32:64"); else - resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64"); + resetDataLayout("e-p6:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"); // If possible, get a TargetInfo for our host triple, so we can match its // types. @@ -298,7 +303,7 @@ void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts, } } -ArrayRef NVPTXTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +NVPTXTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index d81b89a7f24ac..6a868c42e1265 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -46,6 +46,7 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -74,7 +75,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool useFP16ConversionIntrinsics() const override { return false; } diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp index bf10f9a725567..8af6623e5cb15 100644 --- a/clang/lib/Basic/Targets/OSTargets.cpp +++ b/clang/lib/Basic/Targets/OSTargets.cpp @@ -259,8 +259,10 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) { Builder.defineMacro("_KERNEL_MODE"); Builder.defineMacro("_INTEGRAL_MAX_BITS", "64"); - Builder.defineMacro("__STDC_NO_THREADS__"); - + // Define __STDC_NO_THREADS__ based on MSVC version, threads.h availability, + // and language standard. + if (!(Opts.isCompatibleWithMSVC(LangOptions::MSVC2022_9) && Opts.C11)) + Builder.defineMacro("__STDC_NO_THREADS__"); // Starting with VS 2022 17.1, MSVC predefines the below macro to inform // users of the execution character set defined at compile time. // The value given is the Windows Code Page Identifier: diff --git a/clang/lib/Basic/Targets/PNaCl.h b/clang/lib/Basic/Targets/PNaCl.h index 7e0e10aa362d8..d162776b5a0d6 100644 --- a/clang/lib/Basic/Targets/PNaCl.h +++ b/clang/lib/Basic/Targets/PNaCl.h @@ -52,7 +52,9 @@ class LLVM_LIBRARY_VISIBILITY PNaClTargetInfo : public TargetInfo { return Feature == "pnacl"; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::PNaClABIBuiltinVaList; diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 1448069173b5f..2d8891a739ca3 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -19,15 +19,22 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsPPC.def" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY +#include "clang/Basic/BuiltinsPPC.def" +}); /// handleTargetFeatures - Perform initialization based on the user /// configured set of features. @@ -927,9 +934,9 @@ void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) { MaxAtomicInlineWidth = 128; } -ArrayRef PPCTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::PPC::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +PPCTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 3cd0fcad17293..db6ac6f0bd338 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -187,7 +187,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { StringRef getABI() const override { return ABI; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool isCLZForZeroUndef() const override { return false; } diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 8167d7603b0e1..b4aa3206fcfab 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -222,7 +222,7 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, // Currently we support the v1.0 RISC-V V intrinsics. Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(1, 0))); - auto VScale = getVScaleRange(Opts); + auto VScale = getVScaleRange(Opts, false); if (VScale && VScale->first && VScale->first == VScale->second) Builder.defineMacro("__riscv_v_fixed_vlen", Twine(VScale->first * llvm::RISCV::RVVBitsPerBlock)); @@ -240,22 +240,61 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, } } -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsRISCVVector.def" -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#include "clang/Basic/BuiltinsRISCV.inc" +static constexpr int NumRVVBuiltins = + RISCVVector::FirstSiFiveBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumRVVSiFiveBuiltins = + RISCVVector::FirstTSBuiltin - RISCVVector::FirstSiFiveBuiltin; +static constexpr int NumRISCVBuiltins = + RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; +static constexpr int NumBuiltins = + RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == + (NumRVVBuiltins + NumRVVSiFiveBuiltins + NumRISCVBuiltins)); + +namespace RVV { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE +static_assert(BuiltinStrings.size() < 100'000); + +static constexpr std::array BuiltinInfos = { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVV + +namespace RVVSiFive { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE + +static constexpr std::array BuiltinInfos = + { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS }; +} // namespace RVVSiFive + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_STR_TABLE -ArrayRef RISCVTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin); +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_INFOS +}; +static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins); + +llvm::SmallVector +RISCVTargetInfo::getTargetBuiltins() const { + return { + {&RVV::BuiltinStrings, RVV::BuiltinInfos, "__builtin_rvv_"}, + {&RVVSiFive::BuiltinStrings, RVVSiFive::BuiltinInfos, "__builtin_rvv_"}, + {&BuiltinStrings, BuiltinInfos}, + }; } bool RISCVTargetInfo::initFeatureMap( @@ -289,7 +328,8 @@ bool RISCVTargetInfo::initFeatureMap( } std::optional> -RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts) const { +RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts, + bool IsArmStreamingFunction) const { // RISCV::RVVBitsPerBlock is 64. unsigned VScaleMin = ISAInfo->getMinVLen() / llvm::RISCV::RVVBitsPerBlock; diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index bb3f3a5cda7c6..c26aa19080162 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -62,7 +62,7 @@ class RISCVTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; @@ -99,7 +99,8 @@ class RISCVTargetInfo : public TargetInfo { const std::vector &FeaturesVec) const override; std::optional> - getVScaleRange(const LangOptions &LangOpts) const override; + getVScaleRange(const LangOptions &LangOpts, + bool IsArmStreamingFunction) const override; bool hasFeature(StringRef Feature) const override; diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp index f242fedc1ad66..5c076f694dfa4 100644 --- a/clang/lib/Basic/Targets/SPIR.cpp +++ b/clang/lib/Basic/Targets/SPIR.cpp @@ -20,15 +20,23 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin; + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsSPIRV.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS #include "clang/Basic/BuiltinsSPIRV.inc" +#undef GET_BUILTIN_INFOS }; +static_assert(std::size(BuiltinInfos) == NumBuiltins); -ArrayRef SPIRVTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::SPIRV::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +SPIRVTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } void SPIRTargetInfo::getTargetDefines(const LangOptions &Opts, @@ -94,7 +102,8 @@ SPIRV64AMDGCNTargetInfo::convertConstraint(const char *&Constraint) const { return AMDGPUTI.convertConstraint(Constraint); } -ArrayRef SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const { +llvm::SmallVector +SPIRV64AMDGCNTargetInfo::getTargetBuiltins() const { return AMDGPUTI.getTargetBuiltins(); } diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 5a328b9ceeb1d..61f9ef7e3e361 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -47,6 +47,7 @@ static const unsigned SPIRDefIsPrivMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 2, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -80,6 +81,7 @@ static const unsigned SPIRDefIsGenMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -159,7 +161,9 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { // memcpy as per section 3 of the SPIR spec. bool useFP16ConversionIntrinsics() const override { return false; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } std::string_view getClobbers() const override { return ""; } @@ -313,7 +317,9 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo { resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-" "v256:256-v512:512-v1024:1024-n8:16:32:64-G1"); } - ArrayRef getTargetBuiltins() const override; + + llvm::SmallVector getTargetBuiltins() const override; + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; }; @@ -408,7 +414,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final std::string convertConstraint(const char *&Constraint) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; diff --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h index 9c529a5bc5e7f..3215e648ba6c3 100644 --- a/clang/lib/Basic/Targets/Sparc.h +++ b/clang/lib/Basic/Targets/Sparc.h @@ -48,7 +48,7 @@ class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo { bool hasFeature(StringRef Feature) const override; - ArrayRef getTargetBuiltins() const override { + llvm::SmallVector getTargetBuiltins() const override { // FIXME: Implement! return {}; } diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp index c836d110d26d5..0e9a61c6a01c8 100644 --- a/clang/lib/Basic/Targets/SystemZ.cpp +++ b/clang/lib/Basic/Targets/SystemZ.cpp @@ -20,13 +20,21 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::SystemZ::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsSystemZ.def" -}; + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#include "clang/Basic/BuiltinsSystemZ.def" +}); const char *const SystemZTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -172,7 +180,7 @@ void SystemZTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__VEC__", "10305"); } -ArrayRef SystemZTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::SystemZ::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +SystemZTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index d05948586c467..4ca3f53f83cba 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -42,6 +42,7 @@ static const unsigned ZOSAddressMap[] = { 1, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant 0 // wasm_funcref }; @@ -99,7 +100,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; ArrayRef getGCCRegNames() const override; diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h index d6280b02f07b2..46c70de8f9ec1 100644 --- a/clang/lib/Basic/Targets/TCE.h +++ b/clang/lib/Basic/Targets/TCE.h @@ -51,6 +51,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -95,7 +96,9 @@ class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo { bool hasFeature(StringRef Feature) const override { return Feature == "tce"; } - ArrayRef getTargetBuiltins() const override { return {}; } + llvm::SmallVector getTargetBuiltins() const override { + return {}; + } std::string_view getClobbers() const override { return ""; } diff --git a/clang/lib/Basic/Targets/VE.cpp b/clang/lib/Basic/Targets/VE.cpp index 67cae8faf6052..5451f3c303637 100644 --- a/clang/lib/Basic/Targets/VE.cpp +++ b/clang/lib/Basic/Targets/VE.cpp @@ -18,11 +18,19 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsVE.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY #include "clang/Basic/BuiltinsVE.def" -}; +}); void VETargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -39,7 +47,6 @@ void VETargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } -ArrayRef VETargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::VE::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector VETargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h index 7e8fdf6096ef2..e9b7e92f3f850 100644 --- a/clang/lib/Basic/Targets/VE.h +++ b/clang/lib/Basic/Targets/VE.h @@ -55,7 +55,7 @@ class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo { bool hasSjLjLowering() const override { return true; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index 7b0fd0c841ba2..f19c57f1a3a50 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -20,15 +20,22 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + clang::WebAssembly::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsWebAssembly.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define TARGET_BUILTIN CLANG_TARGET_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY #include "clang/Basic/BuiltinsWebAssembly.def" -}; +}); static constexpr llvm::StringLiteral ValidCPUNames[] = { {"mvp"}, {"bleeding-edge"}, {"generic"}, {"lime1"}}; @@ -360,9 +367,9 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( return true; } -ArrayRef WebAssemblyTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin - - Builtin::FirstTSBuiltin); +llvm::SmallVector +WebAssemblyTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags, diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 0a14da6a277b8..fb48c786a7edb 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -42,6 +42,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = { 0, // ptr32_uptr 0, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant 20, // wasm_funcref }; @@ -120,7 +121,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { bool setCPU(const std::string &Name) final { return isValidCPUName(Name); } - ArrayRef getTargetBuiltins() const final; + llvm::SmallVector getTargetBuiltins() const final; BuiltinVaListKind getBuiltinVaListKind() const final { return VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index 40ad8fd9a0967..84a05cec04e7f 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -23,23 +23,53 @@ namespace clang { namespace targets { -static constexpr Builtin::Info BuiltinInfoX86[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, +// The x86-32 builtins are a subset and prefix of the x86-64 builtins. +static constexpr int NumX86Builtins = + X86::LastX86CommonBuiltin - Builtin::FirstTSBuiltin + 1; +static constexpr int NumX86_64Builtins = + X86::LastTSBuiltin - X86::FirstX86_64Builtin; +static constexpr int NumBuiltins = X86::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == (NumX86Builtins + NumX86_64Builtins)); + +namespace X86 { +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_STR_TABLE -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ - {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_INFOS +}; + +static constexpr Builtin::Info PrefixedBuiltinInfos[] = { +#define GET_BUILTIN_PREFIXED_INFOS +#include "clang/Basic/BuiltinsX86.inc" +#undef GET_BUILTIN_PREFIXED_INFOS +}; +static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == + NumX86Builtins); +} // namespace X86 + +namespace X86_64 { +#define GET_BUILTIN_STR_TABLE #include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_INFOS +}; + +static constexpr Builtin::Info PrefixedBuiltinInfos[] = { +#define GET_BUILTIN_PREFIXED_INFOS +#include "clang/Basic/BuiltinsX86_64.inc" +#undef GET_BUILTIN_PREFIXED_INFOS }; +static_assert((std::size(BuiltinInfos) + std::size(PrefixedBuiltinInfos)) == + NumX86_64Builtins); +} // namespace X86_64 static const char *const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", @@ -1856,12 +1886,21 @@ ArrayRef X86TargetInfo::getGCCAddlRegNames() const { return llvm::ArrayRef(AddlRegNames); } -ArrayRef X86_32TargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - - Builtin::FirstTSBuiltin + 1); +llvm::SmallVector +X86_32TargetInfo::getTargetBuiltins() const { + return { + {&X86::BuiltinStrings, X86::BuiltinInfos}, + {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"}, + }; } -ArrayRef X86_64TargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfoX86, - X86::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +X86_64TargetInfo::getTargetBuiltins() const { + return { + {&X86::BuiltinStrings, X86::BuiltinInfos}, + {&X86::BuiltinStrings, X86::PrefixedBuiltinInfos, "__builtin_ia32_"}, + {&X86_64::BuiltinStrings, X86_64::BuiltinInfos}, + {&X86_64::BuiltinStrings, X86_64::PrefixedBuiltinInfos, + "__builtin_ia32_"}, + }; } diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 2c200e64a3d84..205edcab9ccb3 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -46,6 +46,7 @@ static const unsigned X86AddrSpaceMap[] = { 271, // ptr32_uptr 272, // ptr64 0, // hlsl_groupshared + 0, // hlsl_constant // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -508,7 +509,7 @@ class LLVM_LIBRARY_VISIBILITY X86_32TargetInfo : public X86TargetInfo { MaxAtomicInlineWidth = 64; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasBitIntType() const override { return true; } size_t getMaxBitIntWidth() const override { @@ -820,7 +821,7 @@ class LLVM_LIBRARY_VISIBILITY X86_64TargetInfo : public X86TargetInfo { MaxAtomicInlineWidth = 128; } - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; bool hasBitIntType() const override { return true; } size_t getMaxBitIntWidth() const override { diff --git a/clang/lib/Basic/Targets/XCore.cpp b/clang/lib/Basic/Targets/XCore.cpp index fd377bbfb90e1..c725703ede5b0 100644 --- a/clang/lib/Basic/Targets/XCore.cpp +++ b/clang/lib/Basic/Targets/XCore.cpp @@ -18,13 +18,20 @@ using namespace clang; using namespace clang::targets; -static constexpr Builtin::Info BuiltinInfo[] = { -#define BUILTIN(ID, TYPE, ATTRS) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, +static constexpr int NumBuiltins = + XCore::LastTSBuiltin - Builtin::FirstTSBuiltin; + +static constexpr llvm::StringTable BuiltinStrings = + CLANG_BUILTIN_STR_TABLE_START +#define BUILTIN CLANG_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsXCore.def" + ; + +static constexpr auto BuiltinInfos = Builtin::MakeInfos({ +#define BUILTIN CLANG_BUILTIN_ENTRY +#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY #include "clang/Basic/BuiltinsXCore.def" -}; +}); void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -32,7 +39,7 @@ void XCoreTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__XS1B__"); } -ArrayRef XCoreTargetInfo::getTargetBuiltins() const { - return llvm::ArrayRef(BuiltinInfo, - clang::XCore::LastTSBuiltin - Builtin::FirstTSBuiltin); +llvm::SmallVector +XCoreTargetInfo::getTargetBuiltins() const { + return {{&BuiltinStrings, BuiltinInfos}}; } diff --git a/clang/lib/Basic/Targets/XCore.h b/clang/lib/Basic/Targets/XCore.h index 84fd59d1a71e4..9af9e0658f629 100644 --- a/clang/lib/Basic/Targets/XCore.h +++ b/clang/lib/Basic/Targets/XCore.h @@ -43,7 +43,7 @@ class LLVM_LIBRARY_VISIBILITY XCoreTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override; + llvm::SmallVector getTargetBuiltins() const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::VoidPtrBuiltinVaList; diff --git a/clang/lib/Basic/Targets/Xtensa.h b/clang/lib/Basic/Targets/Xtensa.h index a440ba8aa3c6d..470835aacff52 100644 --- a/clang/lib/Basic/Targets/Xtensa.h +++ b/clang/lib/Basic/Targets/Xtensa.h @@ -56,8 +56,8 @@ class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo { void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; - ArrayRef getTargetBuiltins() const override { - return std::nullopt; + llvm::SmallVector getTargetBuiltins() const override { + return {}; } BuiltinVaListKind getBuiltinVaListKind() const override { diff --git a/clang/lib/Basic/Warnings.cpp b/clang/lib/Basic/Warnings.cpp index da0304463007b..5f48e0ec81554 100644 --- a/clang/lib/Basic/Warnings.cpp +++ b/clang/lib/Basic/Warnings.cpp @@ -73,16 +73,6 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, else Diags.setExtensionHandlingBehavior(diag::Severity::Ignored); - if (!Opts.DiagnosticSuppressionMappingsFile.empty()) { - if (auto FileContents = - VFS.getBufferForFile(Opts.DiagnosticSuppressionMappingsFile)) { - Diags.setDiagSuppressionMapping(**FileContents); - } else if (ReportDiags) { - Diags.Report(diag::err_drv_no_such_file) - << Opts.DiagnosticSuppressionMappingsFile; - } - } - SmallVector _Diags; const IntrusiveRefCntPtr< DiagnosticIDs > DiagIDs = Diags.getDiagnosticIDs(); @@ -237,4 +227,17 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags, } } } + + // Process suppression mappings file after processing other warning flags + // (like -Wno-unknown-warning-option) as we can emit extra warnings during + // processing. + if (!Opts.DiagnosticSuppressionMappingsFile.empty()) { + if (auto FileContents = + VFS.getBufferForFile(Opts.DiagnosticSuppressionMappingsFile)) { + Diags.setDiagSuppressionMapping(**FileContents); + } else if (ReportDiags) { + Diags.Report(diag::err_drv_no_such_file) + << Opts.DiagnosticSuppressionMappingsFile; + } + } } diff --git a/clang/lib/CIR/CMakeLists.txt b/clang/lib/CIR/CMakeLists.txt index f3ef8525e15c2..4a99ecb33dfb2 100644 --- a/clang/lib/CIR/CMakeLists.txt +++ b/clang/lib/CIR/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(Dialect) add_subdirectory(CodeGen) add_subdirectory(FrontendAction) add_subdirectory(Interfaces) +add_subdirectory(Lowering) diff --git a/clang/lib/CIR/FrontendAction/.clang-tidy b/clang/lib/CIR/FrontendAction/.clang-tidy new file mode 100644 index 0000000000000..cfb5bdb4bd1fe --- /dev/null +++ b/clang/lib/CIR/FrontendAction/.clang-tidy @@ -0,0 +1,16 @@ +InheritParentConfig: true +CheckOptions: + - key: readability-identifier-naming.ClassCase + value: CamelCase + - key: readability-identifier-naming.EnumCase + value: CamelCase + - key: readability-identifier-naming.FunctionCase + value: camelBack + - key: readability-identifier-naming.MemberCase + value: CamelCase + - key: readability-identifier-naming.ParameterCase + value: CamelCase + - key: readability-identifier-naming.UnionCase + value: CamelCase + - key: readability-identifier-naming.VariableCase + value: CamelCase diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp index 21b6bc56ed050..eab6958ac8f6d 100644 --- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp +++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp @@ -7,23 +7,47 @@ //===----------------------------------------------------------------------===// #include "clang/CIR/FrontendAction/CIRGenAction.h" -#include "clang/CIR/CIRGenerator.h" -#include "clang/Frontend/CompilerInstance.h" - #include "mlir/IR/MLIRContext.h" #include "mlir/IR/OwningOpRef.h" +#include "clang/CIR/CIRGenerator.h" +#include "clang/CIR/LowerToLLVM.h" +#include "clang/CodeGen/BackendUtil.h" +#include "clang/Frontend/CompilerInstance.h" +#include "llvm/IR/Module.h" using namespace cir; using namespace clang; namespace cir { +static BackendAction +getBackendActionFromOutputType(CIRGenAction::OutputType Action) { + switch (Action) { + case CIRGenAction::OutputType::EmitCIR: + assert(false && + "Unsupported output type for getBackendActionFromOutputType!"); + break; // Unreachable, but fall through to report that + case CIRGenAction::OutputType::EmitLLVM: + return BackendAction::Backend_EmitLL; + } + // We should only get here if a non-enum value is passed in or we went through + // the assert(false) case above + llvm_unreachable("Unsupported output type!"); +} + +static std::unique_ptr +lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx) { + return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx); +} + class CIRGenConsumer : public clang::ASTConsumer { virtual void anchor(); CIRGenAction::OutputType Action; + CompilerInstance &CI; + std::unique_ptr OutputStream; ASTContext *Context{nullptr}; @@ -31,18 +55,12 @@ class CIRGenConsumer : public clang::ASTConsumer { std::unique_ptr Gen; public: - CIRGenConsumer(CIRGenAction::OutputType Action, - DiagnosticsEngine &DiagnosticsEngine, - IntrusiveRefCntPtr VFS, - const HeaderSearchOptions &HeaderSearchOptions, - const CodeGenOptions &CodeGenOptions, - const TargetOptions &TargetOptions, - const LangOptions &LangOptions, - const FrontendOptions &FEOptions, + CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI, std::unique_ptr OS) - : Action(Action), OutputStream(std::move(OS)), FS(VFS), - Gen(std::make_unique(DiagnosticsEngine, std::move(VFS), - CodeGenOptions)) {} + : Action(Action), CI(CI), OutputStream(std::move(OS)), + FS(&CI.getVirtualFileSystem()), + Gen(std::make_unique(CI.getDiagnostics(), std::move(FS), + CI.getCodeGenOpts())) {} void Initialize(ASTContext &Ctx) override { assert(!Context && "initialized multiple times"); @@ -66,6 +84,17 @@ class CIRGenConsumer : public clang::ASTConsumer { MlirModule->print(*OutputStream, Flags); } break; + case CIRGenAction::OutputType::EmitLLVM: { + llvm::LLVMContext LLVMCtx; + std::unique_ptr LLVMModule = + lowerFromCIRToLLVMIR(MlirModule, LLVMCtx); + + BackendAction BEAction = getBackendActionFromOutputType(Action); + emitBackendOutput( + CI, CI.getCodeGenOpts(), C.getTargetInfo().getDataLayoutString(), + LLVMModule.get(), BEAction, FS, std::move(OutputStream)); + break; + } } } }; @@ -84,6 +113,8 @@ getOutputStream(CompilerInstance &CI, StringRef InFile, switch (Action) { case CIRGenAction::OutputType::EmitCIR: return CI.createDefaultOutputFile(false, InFile, "cir"); + case CIRGenAction::OutputType::EmitLLVM: + return CI.createDefaultOutputFile(false, InFile, "ll"); } llvm_unreachable("Invalid CIRGenAction::OutputType"); } @@ -95,10 +126,8 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { if (!Out) Out = getOutputStream(CI, InFile, Action); - auto Result = std::make_unique( - Action, CI.getDiagnostics(), &CI.getVirtualFileSystem(), - CI.getHeaderSearchOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), - CI.getLangOpts(), CI.getFrontendOpts(), std::move(Out)); + auto Result = + std::make_unique(Action, CI, std::move(Out)); return Result; } @@ -106,3 +135,7 @@ CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { void EmitCIRAction::anchor() {} EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx) : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {} + +void EmitLLVMAction::anchor() {} +EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx) + : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {} diff --git a/clang/lib/CIR/FrontendAction/CMakeLists.txt b/clang/lib/CIR/FrontendAction/CMakeLists.txt index b0616ab5d64b0..ac2b857239d07 100644 --- a/clang/lib/CIR/FrontendAction/CMakeLists.txt +++ b/clang/lib/CIR/FrontendAction/CMakeLists.txt @@ -12,6 +12,8 @@ add_clang_library(clangCIRFrontendAction clangAST clangFrontend clangCIR + clangCIRLoweringDirectToLLVM + clangCodeGen MLIRCIR MLIRIR ) diff --git a/clang/lib/CIR/Lowering/CMakeLists.txt b/clang/lib/CIR/Lowering/CMakeLists.txt new file mode 100644 index 0000000000000..95c304ded9183 --- /dev/null +++ b/clang/lib/CIR/Lowering/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(DirectToLLVM) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt b/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt new file mode 100644 index 0000000000000..3f74c79249a27 --- /dev/null +++ b/clang/lib/CIR/Lowering/DirectToLLVM/CMakeLists.txt @@ -0,0 +1,17 @@ +set(LLVM_LINK_COMPONENTS + Core + Support + ) + +get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) + +add_clang_library(clangCIRLoweringDirectToLLVM + LowerToLLVM.cpp + + LINK_LIBS + MLIRIR + ${dialect_libs} + MLIRCIR + MLIRBuiltinToLLVMIRTranslation + MLIRLLVMToLLVMIRTranslation + ) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp new file mode 100644 index 0000000000000..d60a6b38b0c12 --- /dev/null +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -0,0 +1,336 @@ +//====- LowerToLLVM.cpp - Lowering from CIR to LLVMIR ---------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements lowering of CIR operations to LLVMIR. +// +//===----------------------------------------------------------------------===// + +#include "LowerToLLVM.h" + +#include "mlir/Conversion/LLVMCommon/TypeConverter.h" +#include "mlir/Dialect/DLTI/DLTI.h" +#include "mlir/Dialect/Func/IR/FuncOps.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/IR/BuiltinDialect.h" +#include "mlir/IR/BuiltinOps.h" +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassManager.h" +#include "mlir/Target/LLVMIR/Dialect/Builtin/BuiltinToLLVMIRTranslation.h" +#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h" +#include "mlir/Target/LLVMIR/Export.h" +#include "mlir/Transforms/DialectConversion.h" +#include "clang/CIR/Dialect/IR/CIRAttrVisitor.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/MissingFeatures.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/TimeProfiler.h" + +using namespace cir; +using namespace llvm; + +namespace cir { +namespace direct { + +class CIRAttrToValue : public CirAttrVisitor { +public: + CIRAttrToValue(mlir::Operation *parentOp, + mlir::ConversionPatternRewriter &rewriter, + const mlir::TypeConverter *converter) + : parentOp(parentOp), rewriter(rewriter), converter(converter) {} + + mlir::Value lowerCirAttrAsValue(mlir::Attribute attr) { return visit(attr); } + + mlir::Value visitCirIntAttr(cir::IntAttr intAttr) { + mlir::Location loc = parentOp->getLoc(); + return rewriter.create( + loc, converter->convertType(intAttr.getType()), intAttr.getValue()); + } + + mlir::Value visitCirFPAttr(cir::FPAttr fltAttr) { + mlir::Location loc = parentOp->getLoc(); + return rewriter.create( + loc, converter->convertType(fltAttr.getType()), fltAttr.getValue()); + } + + mlir::Value visitCirConstPtrAttr(cir::ConstPtrAttr ptrAttr) { + mlir::Location loc = parentOp->getLoc(); + if (ptrAttr.isNullValue()) { + return rewriter.create( + loc, converter->convertType(ptrAttr.getType())); + } + mlir::DataLayout layout(parentOp->getParentOfType()); + mlir::Value ptrVal = rewriter.create( + loc, + rewriter.getIntegerType(layout.getTypeSizeInBits(ptrAttr.getType())), + ptrAttr.getValue().getInt()); + return rewriter.create( + loc, converter->convertType(ptrAttr.getType()), ptrVal); + } + +private: + mlir::Operation *parentOp; + mlir::ConversionPatternRewriter &rewriter; + const mlir::TypeConverter *converter; +}; + +// This class handles rewriting initializer attributes for types that do not +// require region initialization. +class GlobalInitAttrRewriter + : public CirAttrVisitor { +public: + GlobalInitAttrRewriter(mlir::Type type, + mlir::ConversionPatternRewriter &rewriter) + : llvmType(type), rewriter(rewriter) {} + + mlir::Attribute rewriteInitAttr(mlir::Attribute attr) { return visit(attr); } + + mlir::Attribute visitCirIntAttr(cir::IntAttr attr) { + return rewriter.getIntegerAttr(llvmType, attr.getValue()); + } + mlir::Attribute visitCirFPAttr(cir::FPAttr attr) { + return rewriter.getFloatAttr(llvmType, attr.getValue()); + } + +private: + mlir::Type llvmType; + mlir::ConversionPatternRewriter &rewriter; +}; + +// This pass requires the CIR to be in a "flat" state. All blocks in each +// function must belong to the parent region. Once scopes and control flow +// are implemented in CIR, a pass will be run before this one to flatten +// the CIR and get it into the state that this pass requires. +struct ConvertCIRToLLVMPass + : public mlir::PassWrapper> { + void getDependentDialects(mlir::DialectRegistry ®istry) const override { + registry.insert(); + } + void runOnOperation() final; + + StringRef getDescription() const override { + return "Convert the prepared CIR dialect module to LLVM dialect"; + } + + StringRef getArgument() const override { return "cir-flat-to-llvm"; } +}; + +bool CIRToLLVMGlobalOpLowering::attrRequiresRegionInitialization( + mlir::Attribute attr) const { + // There will be more cases added later. + return isa(attr); +} + +/// Replace CIR global with a region initialized LLVM global and update +/// insertion point to the end of the initializer block. +void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp( + cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const { + assert(!cir::MissingFeatures::convertTypeForMemory()); + const mlir::Type llvmType = getTypeConverter()->convertType(op.getSymType()); + + // FIXME: These default values are placeholders until the the equivalent + // attributes are available on cir.global ops. This duplicates code + // in CIRToLLVMGlobalOpLowering::matchAndRewrite() but that will go + // away when the placeholders are no longer needed. + assert(!cir::MissingFeatures::opGlobalConstant()); + const bool isConst = false; + assert(!cir::MissingFeatures::addressSpace()); + const unsigned addrSpace = 0; + assert(!cir::MissingFeatures::opGlobalDSOLocal()); + const bool isDsoLocal = true; + assert(!cir::MissingFeatures::opGlobalThreadLocal()); + const bool isThreadLocal = false; + assert(!cir::MissingFeatures::opGlobalAlignment()); + const uint64_t alignment = 0; + assert(!cir::MissingFeatures::opGlobalLinkage()); + const mlir::LLVM::Linkage linkage = mlir::LLVM::Linkage::External; + const StringRef symbol = op.getSymName(); + + SmallVector attributes; + auto newGlobalOp = rewriter.replaceOpWithNewOp( + op, llvmType, isConst, linkage, symbol, nullptr, alignment, addrSpace, + isDsoLocal, isThreadLocal, + /*comdat=*/mlir::SymbolRefAttr(), attributes); + newGlobalOp.getRegion().push_back(new mlir::Block()); + rewriter.setInsertionPointToEnd(newGlobalOp.getInitializerBlock()); +}; + +mlir::LogicalResult +CIRToLLVMGlobalOpLowering::matchAndRewriteRegionInitializedGlobal( + cir::GlobalOp op, mlir::Attribute init, + mlir::ConversionPatternRewriter &rewriter) const { + // TODO: Generalize this handling when more types are needed here. + assert(isa(init)); + + // TODO(cir): once LLVM's dialect has proper equivalent attributes this + // should be updated. For now, we use a custom op to initialize globals + // to the appropriate value. + const mlir::Location loc = op.getLoc(); + setupRegionInitializedLLVMGlobalOp(op, rewriter); + CIRAttrToValue attrVisitor(op, rewriter, typeConverter); + mlir::Value value = attrVisitor.lowerCirAttrAsValue(init); + rewriter.create(loc, value); + return mlir::success(); +} + +mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite( + cir::GlobalOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + + std::optional init = op.getInitialValue(); + + // If we have an initializer and it requires region initialization, handle + // that separately + if (init.has_value() && attrRequiresRegionInitialization(init.value())) { + return matchAndRewriteRegionInitializedGlobal(op, init.value(), rewriter); + } + + // Fetch required values to create LLVM op. + const mlir::Type cirSymType = op.getSymType(); + + // This is the LLVM dialect type. + assert(!cir::MissingFeatures::convertTypeForMemory()); + const mlir::Type llvmType = getTypeConverter()->convertType(cirSymType); + // FIXME: These default values are placeholders until the the equivalent + // attributes are available on cir.global ops. + assert(!cir::MissingFeatures::opGlobalConstant()); + const bool isConst = false; + assert(!cir::MissingFeatures::addressSpace()); + const unsigned addrSpace = 0; + assert(!cir::MissingFeatures::opGlobalDSOLocal()); + const bool isDsoLocal = true; + assert(!cir::MissingFeatures::opGlobalThreadLocal()); + const bool isThreadLocal = false; + assert(!cir::MissingFeatures::opGlobalAlignment()); + const uint64_t alignment = 0; + assert(!cir::MissingFeatures::opGlobalLinkage()); + const mlir::LLVM::Linkage linkage = mlir::LLVM::Linkage::External; + const StringRef symbol = op.getSymName(); + SmallVector attributes; + + if (init.has_value()) { + GlobalInitAttrRewriter initRewriter(llvmType, rewriter); + init = initRewriter.rewriteInitAttr(init.value()); + // If initRewriter returned a null attribute, init will have a value but + // the value will be null. If that happens, initRewriter didn't handle the + // attribute type. It probably needs to be added to GlobalInitAttrRewriter. + if (!init.value()) { + op.emitError() << "unsupported initializer '" << init.value() << "'"; + return mlir::failure(); + } + } + + // Rewrite op. + rewriter.replaceOpWithNewOp( + op, llvmType, isConst, linkage, symbol, init.value_or(mlir::Attribute()), + alignment, addrSpace, isDsoLocal, isThreadLocal, + /*comdat=*/mlir::SymbolRefAttr(), attributes); + + return mlir::success(); +} + +static void prepareTypeConverter(mlir::LLVMTypeConverter &converter, + mlir::DataLayout &dataLayout) { + converter.addConversion([&](cir::PointerType type) -> mlir::Type { + // Drop pointee type since LLVM dialect only allows opaque pointers. + assert(!cir::MissingFeatures::addressSpace()); + unsigned targetAS = 0; + + return mlir::LLVM::LLVMPointerType::get(type.getContext(), targetAS); + }); + converter.addConversion([&](cir::IntType type) -> mlir::Type { + // LLVM doesn't work with signed types, so we drop the CIR signs here. + return mlir::IntegerType::get(type.getContext(), type.getWidth()); + }); + converter.addConversion([&](cir::SingleType type) -> mlir::Type { + return mlir::Float32Type::get(type.getContext()); + }); + converter.addConversion([&](cir::DoubleType type) -> mlir::Type { + return mlir::Float64Type::get(type.getContext()); + }); + converter.addConversion([&](cir::FP80Type type) -> mlir::Type { + return mlir::Float80Type::get(type.getContext()); + }); + converter.addConversion([&](cir::FP128Type type) -> mlir::Type { + return mlir::Float128Type::get(type.getContext()); + }); + converter.addConversion([&](cir::LongDoubleType type) -> mlir::Type { + return converter.convertType(type.getUnderlying()); + }); + converter.addConversion([&](cir::FP16Type type) -> mlir::Type { + return mlir::Float16Type::get(type.getContext()); + }); + converter.addConversion([&](cir::BF16Type type) -> mlir::Type { + return mlir::BFloat16Type::get(type.getContext()); + }); +} + +void ConvertCIRToLLVMPass::runOnOperation() { + llvm::TimeTraceScope scope("Convert CIR to LLVM Pass"); + + mlir::ModuleOp module = getOperation(); + mlir::DataLayout dl(module); + mlir::LLVMTypeConverter converter(&getContext()); + prepareTypeConverter(converter, dl); + + mlir::RewritePatternSet patterns(&getContext()); + + patterns.add(converter, patterns.getContext(), dl); + + mlir::ConversionTarget target(getContext()); + target.addLegalOp(); + target.addLegalDialect(); + target.addIllegalDialect(); + + if (failed(applyPartialConversion(module, target, std::move(patterns)))) + signalPassFailure(); +} + +static std::unique_ptr createConvertCIRToLLVMPass() { + return std::make_unique(); +} + +static void populateCIRToLLVMPasses(mlir::OpPassManager &pm) { + pm.addPass(createConvertCIRToLLVMPass()); +} + +std::unique_ptr +lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, LLVMContext &llvmCtx) { + llvm::TimeTraceScope scope("lower from CIR to LLVM directly"); + + mlir::MLIRContext *mlirCtx = mlirModule.getContext(); + + mlir::PassManager pm(mlirCtx); + populateCIRToLLVMPasses(pm); + + if (mlir::failed(pm.run(mlirModule))) { + // FIXME: Handle any errors where they occurs and return a nullptr here. + report_fatal_error( + "The pass manager failed to lower CIR to LLVMIR dialect!"); + } + + mlir::registerBuiltinDialectTranslation(*mlirCtx); + mlir::registerLLVMDialectTranslation(*mlirCtx); + + llvm::TimeTraceScope translateScope("translateModuleToLLVMIR"); + + StringRef moduleName = mlirModule.getName().value_or("CIRToLLVMModule"); + std::unique_ptr llvmModule = + mlir::translateModuleToLLVMIR(mlirModule, llvmCtx, moduleName); + + if (!llvmModule) { + // FIXME: Handle any errors where they occurs and return a nullptr here. + report_fatal_error("Lowering from LLVMIR dialect to llvm IR failed!"); + } + + return llvmModule; +} +} // namespace direct +} // namespace cir diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h new file mode 100644 index 0000000000000..b3366c1fb9337 --- /dev/null +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -0,0 +1,52 @@ +//====- LowerToLLVM.h- Lowering from CIR to LLVM --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares an interface for converting CIR modules to LLVM IR. +// +//===----------------------------------------------------------------------===// +#ifndef CLANG_CIR_LOWERTOLLVM_H +#define CLANG_CIR_LOWERTOLLVM_H + +#include "mlir/Transforms/DialectConversion.h" +#include "clang/CIR/Dialect/IR/CIRDialect.h" + +namespace cir { + +namespace direct { + +class CIRToLLVMGlobalOpLowering + : public mlir::OpConversionPattern { + const mlir::DataLayout &dataLayout; + +public: + CIRToLLVMGlobalOpLowering(const mlir::TypeConverter &typeConverter, + mlir::MLIRContext *context, + const mlir::DataLayout &dataLayout) + : OpConversionPattern(typeConverter, context), dataLayout(dataLayout) { + setHasBoundedRewriteRecursion(); + } + + mlir::LogicalResult + matchAndRewrite(cir::GlobalOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override; + +private: + bool attrRequiresRegionInitialization(mlir::Attribute attr) const; + + mlir::LogicalResult matchAndRewriteRegionInitializedGlobal( + cir::GlobalOp op, mlir::Attribute init, + mlir::ConversionPatternRewriter &rewriter) const; + + void setupRegionInitializedLLVMGlobalOp( + cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const; +}; + +} // namespace direct +} // namespace cir + +#endif // CLANG_CIR_LOWERTOLLVM_H diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index 14ba55360fe05..4f2218b583e41 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -12,9 +12,6 @@ add_subdirectory(Analysis) add_subdirectory(Edit) add_subdirectory(ExtractAPI) add_subdirectory(Rewrite) -if(CLANG_ENABLE_ARCMT) - add_subdirectory(ARCMigrate) -endif() add_subdirectory(Driver) add_subdirectory(Serialization) add_subdirectory(Frontend) diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h index a18c7169af1eb..a748ddaa110a5 100644 --- a/clang/lib/CodeGen/Address.h +++ b/clang/lib/CodeGen/Address.h @@ -197,10 +197,7 @@ class Address { /// Return the type of the pointer value. llvm::PointerType *getType() const { - return llvm::PointerType::get( - ElementType, - llvm::cast(Pointer.getPointer()->getType()) - ->getAddressSpace()); + return llvm::cast(Pointer.getPointer()->getType()); } /// Return the type of the values stored in this address. diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 3e65eeb3755d2..1750719e17670 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -124,15 +124,25 @@ namespace clang { extern llvm::cl::opt ClSanitizeGuardChecks; } -namespace { - // Default filename used for profile generation. -std::string getDefaultProfileGenName() { +static std::string getDefaultProfileGenName() { return DebugInfoCorrelate || ProfileCorrelate != InstrProfCorrelator::NONE ? "default_%m.proflite" : "default_%m.profraw"; } +// Path and name of file used for profile generation +static std::string getProfileGenName(const CodeGenOptions &CodeGenOpts) { + std::string FileName = CodeGenOpts.InstrProfileOutput.empty() + ? getDefaultProfileGenName() + : CodeGenOpts.InstrProfileOutput; + if (CodeGenOpts.ContinuousProfileSync) + FileName = "%c" + FileName; + return FileName; +} + +namespace { + class EmitAssemblyHelper { CompilerInstance &CI; DiagnosticsEngine &Diags; @@ -551,7 +561,9 @@ getInstrProfOptions(const CodeGenOptions &CodeGenOpts, return std::nullopt; InstrProfOptions Options; Options.NoRedZone = CodeGenOpts.DisableRedZone; - Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput; + Options.InstrProfileOutput = CodeGenOpts.ContinuousProfileSync + ? ("%c" + CodeGenOpts.InstrProfileOutput) + : CodeGenOpts.InstrProfileOutput; Options.Atomic = CodeGenOpts.AtomicProfileUpdate; return Options; } @@ -795,14 +807,23 @@ static void addSanitizers(const Triple &TargetTriple, PB.registerOptimizerLastEPCallback(SanitizersCallback); } - if (LowerAllowCheckPass::IsRequested()) { + // SanitizeSkipHotCutoffs: doubles with range [0, 1] + // Opts.cutoffs: unsigned ints with range [0, 1000000] + auto ScaledCutoffs = CodeGenOpts.SanitizeSkipHotCutoffs.getAllScaled(1000000); + + // TODO: remove IsRequested() + if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value()) { // We want to call it after inline, which is about OptimizerEarlyEPCallback. - PB.registerOptimizerEarlyEPCallback([&](ModulePassManager &MPM, - OptimizationLevel Level, - ThinOrFullLTOPhase Phase) { - LowerAllowCheckPass::Options Opts; - MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts))); - }); + PB.registerOptimizerEarlyEPCallback( + [ScaledCutoffs](ModulePassManager &MPM, OptimizationLevel Level, + ThinOrFullLTOPhase Phase) { + LowerAllowCheckPass::Options Opts; + // TODO: after removing IsRequested(), make this unconditional + if (ScaledCutoffs.has_value()) + Opts.cutoffs = ScaledCutoffs.value(); + MPM.addPass( + createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts))); + }); } } @@ -813,13 +834,12 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (CodeGenOpts.hasProfileIRInstr()) // -fprofile-generate. - PGOOpt = PGOOptions( - CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName() - : CodeGenOpts.InstrProfileOutput, - "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr, - PGOOptions::NoCSAction, ClPGOColdFuncAttr, - CodeGenOpts.DebugInfoForProfiling, - /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate); + PGOOpt = PGOOptions(getProfileGenName(CodeGenOpts), "", "", + CodeGenOpts.MemoryProfileUsePath, nullptr, + PGOOptions::IRInstr, PGOOptions::NoCSAction, + ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, + /*PseudoProbeForProfiling=*/false, + CodeGenOpts.AtomicProfileUpdate); else if (CodeGenOpts.hasProfileIRUse()) { // -fprofile-use. auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse @@ -863,24 +883,20 @@ void EmitAssemblyHelper::RunOptimizationPipeline( PGOOpt->Action != PGOOptions::SampleUse && "Cannot run CSProfileGen pass with ProfileGen or SampleUse " " pass"); - PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty() - ? getDefaultProfileGenName() - : CodeGenOpts.InstrProfileOutput; + PGOOpt->CSProfileGenFile = getProfileGenName(CodeGenOpts); PGOOpt->CSAction = PGOOptions::CSIRInstr; } else - PGOOpt = PGOOptions("", - CodeGenOpts.InstrProfileOutput.empty() - ? getDefaultProfileGenName() - : CodeGenOpts.InstrProfileOutput, - "", /*MemoryProfile=*/"", nullptr, - PGOOptions::NoAction, PGOOptions::CSIRInstr, - ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling); + PGOOpt = PGOOptions("", getProfileGenName(CodeGenOpts), "", + /*MemoryProfile=*/"", nullptr, PGOOptions::NoAction, + PGOOptions::CSIRInstr, ClPGOColdFuncAttr, + CodeGenOpts.DebugInfoForProfiling); } if (TM) TM->setPGOOption(PGOOpt); PipelineTuningOptions PTO; PTO.LoopUnrolling = CodeGenOpts.UnrollLoops; + PTO.LoopInterchange = CodeGenOpts.InterchangeLoops; // For historical reasons, loop interleaving is set to mirror setting for loop // unrolling. PTO.LoopInterleaving = CodeGenOpts.UnrollLoops; @@ -1305,6 +1321,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex, initTargetOptions(CI, Diags, Conf.Options); Conf.SampleProfile = std::move(SampleProfile); Conf.PTO.LoopUnrolling = CGOpts.UnrollLoops; + Conf.PTO.LoopInterchange = CGOpts.InterchangeLoops; // For historical reasons, loop interleaving is set to mirror setting for loop // unrolling. Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops; diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index a7584a95c8ca7..faef6a5fbe1f5 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1097,31 +1097,10 @@ llvm::Type *CodeGenModule::getBlockDescriptorType() { if (BlockDescriptorType) return BlockDescriptorType; - llvm::Type *UnsignedLongTy = - getTypes().ConvertType(getContext().UnsignedLongTy); - - // struct __block_descriptor { - // unsigned long reserved; - // unsigned long block_size; - // - // // later, the following will be added - // - // struct { - // void (*copyHelper)(); - // void (*copyHelper)(); - // } helpers; // !!! optional - // - // const char *signature; // the block signature - // const char *layout; // reserved - // }; - BlockDescriptorType = llvm::StructType::create( - "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy); - - // Now form a pointer to that. unsigned AddrSpace = 0; if (getLangOpts().OpenCL) AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_constant); - BlockDescriptorType = llvm::PointerType::get(BlockDescriptorType, AddrSpace); + BlockDescriptorType = llvm::PointerType::get(getLLVMContext(), AddrSpace); return BlockDescriptorType; } @@ -2800,7 +2779,8 @@ static void configureBlocksRuntimeObject(CodeGenModule &CGM, llvm::Constant *C) { auto *GV = cast(C->stripPointerCasts()); - if (CGM.getTarget().getTriple().isOSBinFormatCOFF()) { + if (!CGM.getCodeGenOpts().StaticClosure && + CGM.getTarget().getTriple().isOSBinFormatCOFF()) { const IdentifierInfo &II = CGM.getContext().Idents.get(C->getName()); TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl(); DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); @@ -2815,7 +2795,6 @@ static void configureBlocksRuntimeObject(CodeGenModule &CGM, (ND = dyn_cast(Result))) break; - // TODO: support static blocks runtime if (GV->isDeclaration() && (!ND || !ND->hasAttr())) { GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); GV->setLinkage(llvm::GlobalValue::ExternalLinkage); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 26bccccdc5e36..0fe8cf5179b53 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -29,6 +29,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/OSLog.h" #include "clang/AST/OperationKinds.h" +#include "clang/AST/StmtVisitor.h" #include "clang/AST/Type.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" @@ -264,8 +265,10 @@ llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, unsigned BuiltinID) { assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); - // Get the name, skip over the __builtin_ prefix (if necessary). - StringRef Name; + // Get the name, skip over the __builtin_ prefix (if necessary). We may have + // to build this up so provide a small stack buffer to handle the vast + // majority of names. + llvm::SmallString<64> Name; GlobalDecl D(FD); // TODO: This list should be expanded or refactored after all GCC-compatible @@ -1049,33 +1052,102 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); } -const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberFieldAndOffset( - ASTContext &Ctx, const RecordDecl *RD, const FieldDecl *FAMDecl, - uint64_t &Offset) { +namespace { + +/// StructFieldAccess is a simple visitor class to grab the first MemberExpr +/// from an Expr. It records any ArraySubscriptExpr we meet along the way. +class StructFieldAccess + : public ConstStmtVisitor { + bool AddrOfSeen = false; + +public: + const ArraySubscriptExpr *ASE = nullptr; + + const Expr *VisitMemberExpr(const MemberExpr *E) { + if (AddrOfSeen && E->getType()->isArrayType()) + // Avoid forms like '&ptr->array'. + return nullptr; + return E; + } + + const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) { + if (ASE) + // We don't support multiple subscripts. + return nullptr; + + AddrOfSeen = false; // '&ptr->array[idx]' is okay. + ASE = E; + return Visit(E->getBase()); + } + const Expr *VisitCastExpr(const CastExpr *E) { + if (E->getCastKind() == CK_LValueToRValue) + return E; + return Visit(E->getSubExpr()); + } + const Expr *VisitParenExpr(const ParenExpr *E) { + return Visit(E->getSubExpr()); + } + const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) { + AddrOfSeen = true; + return Visit(E->getSubExpr()); + } + const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) { + AddrOfSeen = false; + return Visit(E->getSubExpr()); + } +}; + +} // end anonymous namespace + +/// Find a struct's flexible array member. It may be embedded inside multiple +/// sub-structs, but must still be the last field. +static const FieldDecl *FindFlexibleArrayMemberField(CodeGenFunction &CGF, + ASTContext &Ctx, + const RecordDecl *RD) { const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = - getLangOpts().getStrictFlexArraysLevel(); - uint32_t FieldNo = 0; + CGF.getLangOpts().getStrictFlexArraysLevel(); if (RD->isImplicit()) return nullptr; for (const FieldDecl *FD : RD->fields()) { - if ((!FAMDecl || FD == FAMDecl) && - Decl::isFlexibleArrayMemberLike( + if (Decl::isFlexibleArrayMemberLike( Ctx, FD, FD->getType(), StrictFlexArraysLevel, - /*IgnoreTemplateOrMacroSubstitution=*/true)) { - const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); - Offset += Layout.getFieldOffset(FieldNo); + /*IgnoreTemplateOrMacroSubstitution=*/true)) return FD; + + if (auto RT = FD->getType()->getAs()) + if (const FieldDecl *FD = + FindFlexibleArrayMemberField(CGF, Ctx, RT->getAsRecordDecl())) + return FD; + } + + return nullptr; +} + +/// Calculate the offset of a struct field. It may be embedded inside multiple +/// sub-structs. +static bool GetFieldOffset(ASTContext &Ctx, const RecordDecl *RD, + const FieldDecl *FD, int64_t &Offset) { + if (RD->isImplicit()) + return false; + + // Keep track of the field number ourselves, because the other methods + // (CGRecordLayout::getLLVMFieldNo) aren't always equivalent to how the AST + // is laid out. + uint32_t FieldNo = 0; + const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); + + for (const FieldDecl *Field : RD->fields()) { + if (Field == FD) { + Offset += Layout.getFieldOffset(FieldNo); + return true; } - QualType Ty = FD->getType(); - if (Ty->isRecordType()) { - if (const FieldDecl *Field = FindFlexibleArrayMemberFieldAndOffset( - Ctx, Ty->getAsRecordDecl(), FAMDecl, Offset)) { - const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); + if (auto RT = Field->getType()->getAs()) { + if (GetFieldOffset(Ctx, RT->getAsRecordDecl(), FD, Offset)) { Offset += Layout.getFieldOffset(FieldNo); - return Field; + return true; } } @@ -1083,202 +1155,255 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberFieldAndOffset( ++FieldNo; } - return nullptr; + return false; } -static unsigned CountCountedByAttrs(const RecordDecl *RD) { - unsigned Num = 0; - - for (const FieldDecl *FD : RD->fields()) { - if (FD->getType()->isCountAttributedType()) - return ++Num; +static std::optional +GetFieldOffset(ASTContext &Ctx, const RecordDecl *RD, const FieldDecl *FD) { + int64_t Offset = 0; - QualType Ty = FD->getType(); - if (Ty->isRecordType()) - Num += CountCountedByAttrs(Ty->getAsRecordDecl()); - } + if (GetFieldOffset(Ctx, RD, FD, Offset)) + return std::optional(Offset); - return Num; + return std::nullopt; } llvm::Value * -CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, - llvm::IntegerType *ResType) { - // The code generated here calculates the size of a struct with a flexible - // array member that uses the counted_by attribute. There are two instances - // we handle: - // - // struct s { - // unsigned long flags; - // int count; - // int array[] __attribute__((counted_by(count))); - // } - // - // 1) bdos of the flexible array itself: - // - // __builtin_dynamic_object_size(p->array, 1) == - // p->count * sizeof(*p->array) - // - // 2) bdos of a pointer into the flexible array: - // - // __builtin_dynamic_object_size(&p->array[42], 1) == - // (p->count - 42) * sizeof(*p->array) +CodeGenFunction::emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE, + unsigned Type, + llvm::IntegerType *ResType) { + ASTContext &Ctx = getContext(); + + // Note: If the whole struct is specificed in the __bdos (i.e. Visitor + // returns a DeclRefExpr). The calculation of the whole size of the structure + // with a flexible array member can be done in two ways: // - // 2) bdos of the whole struct, including the flexible array: + // 1) sizeof(struct S) + count * sizeof(typeof(fam)) + // 2) offsetof(struct S, fam) + count * sizeof(typeof(fam)) // - // __builtin_dynamic_object_size(p, 1) == - // max(sizeof(struct s), - // offsetof(struct s, array) + p->count * sizeof(*p->array)) + // The first will add additional padding after the end of the array + // allocation while the second method is more precise, but not quite expected + // from programmers. See + // https://lore.kernel.org/lkml/ZvV6X5FPBBW7CO1f@archlinux/ for a discussion + // of the topic. // - ASTContext &Ctx = getContext(); - const Expr *Base = E->IgnoreParenImpCasts(); - const Expr *Idx = nullptr; - - if (const auto *UO = dyn_cast(Base); - UO && UO->getOpcode() == UO_AddrOf) { - Expr *SubExpr = UO->getSubExpr()->IgnoreParenImpCasts(); - if (const auto *ASE = dyn_cast(SubExpr)) { - Base = ASE->getBase()->IgnoreParenImpCasts(); - Idx = ASE->getIdx()->IgnoreParenImpCasts(); - - if (const auto *IL = dyn_cast(Idx)) { - int64_t Val = IL->getValue().getSExtValue(); - if (Val < 0) - return getDefaultBuiltinObjectSizeResult(Type, ResType); - - if (Val == 0) - // The index is 0, so we don't need to take it into account. - Idx = nullptr; - } - } else { - // Potential pointer to another element in the struct. - Base = SubExpr; - } - } + // GCC isn't (currently) able to calculate __bdos on a pointer to the whole + // structure. Therefore, because of the above issue, we choose to match what + // GCC does for consistency's sake. - // Get the flexible array member Decl. - const RecordDecl *OuterRD = nullptr; - const FieldDecl *FAMDecl = nullptr; - if (const auto *ME = dyn_cast(Base)) { - // Check if \p Base is referencing the FAM itself. - const ValueDecl *VD = ME->getMemberDecl(); - OuterRD = VD->getDeclContext()->getOuterLexicalRecordContext(); - FAMDecl = dyn_cast(VD); - if (!FAMDecl) - return nullptr; - } else if (const auto *DRE = dyn_cast(Base)) { - // Check if we're pointing to the whole struct. - QualType Ty = DRE->getDecl()->getType(); - if (Ty->isPointerType()) - Ty = Ty->getPointeeType(); - OuterRD = Ty->getAsRecordDecl(); - - // If we have a situation like this: - // - // struct union_of_fams { - // int flags; - // union { - // signed char normal_field; - // struct { - // int count1; - // int arr1[] __counted_by(count1); - // }; - // struct { - // signed char count2; - // int arr2[] __counted_by(count2); - // }; - // }; - // }; - // - // We don't know which 'count' to use in this scenario: - // - // size_t get_size(struct union_of_fams *p) { - // return __builtin_dynamic_object_size(p, 1); - // } - // - // Instead of calculating a wrong number, we give up. - if (OuterRD && CountCountedByAttrs(OuterRD) > 1) - return nullptr; - } + StructFieldAccess Visitor; + const MemberExpr *ME = dyn_cast_if_present(Visitor.Visit(E)); + if (!ME) + return nullptr; - if (!OuterRD) + const auto *FD = dyn_cast(ME->getMemberDecl()); + if (!FD) return nullptr; - // We call FindFlexibleArrayMemberAndOffset even if FAMDecl is non-null to - // get its offset. - uint64_t Offset = 0; - FAMDecl = - FindFlexibleArrayMemberFieldAndOffset(Ctx, OuterRD, FAMDecl, Offset); - Offset = Ctx.toCharUnitsFromBits(Offset).getQuantity(); + const RecordDecl *RD = FD->getDeclContext()->getOuterLexicalRecordContext(); + const FieldDecl *FlexibleArrayMemberFD = nullptr; - if (!FAMDecl || !FAMDecl->getType()->isCountAttributedType()) - // No flexible array member found or it doesn't have the "counted_by" - // attribute. - return nullptr; + if (Decl::isFlexibleArrayMemberLike( + Ctx, FD, FD->getType(), getLangOpts().getStrictFlexArraysLevel(), + /*IgnoreTemplateOrMacroSubstitution=*/true)) + FlexibleArrayMemberFD = FD; + else + FlexibleArrayMemberFD = FindFlexibleArrayMemberField(*this, Ctx, RD); - const FieldDecl *CountedByFD = FAMDecl->findCountedByField(); - if (!CountedByFD) - // Can't find the field referenced by the "counted_by" attribute. + if (!FlexibleArrayMemberFD || + !FlexibleArrayMemberFD->getType()->isCountAttributedType()) return nullptr; - if (isa(Base)) - // The whole struct is specificed in the __bdos. The calculation of the - // whole size of the structure can be done in two ways: - // - // 1) sizeof(struct S) + count * sizeof(typeof(fam)) - // 2) offsetof(struct S, fam) + count * sizeof(typeof(fam)) - // - // The first will add additional padding after the end of the array, - // allocation while the second method is more precise, but not quite - // expected from programmers. See - // https://lore.kernel.org/lkml/ZvV6X5FPBBW7CO1f@archlinux/ for a - // discussion of the topic. - // - // GCC isn't (currently) able to calculate __bdos on a pointer to the whole - // structure. Therefore, because of the above issue, we'll choose to match - // what GCC does for consistency's sake. + const FieldDecl *CountFD = FlexibleArrayMemberFD->findCountedByField(); + if (!CountFD) + // Can't find the field referenced by the "counted_by" attribute. return nullptr; - // Build a load of the counted_by field. - bool IsSigned = CountedByFD->getType()->isSignedIntegerType(); - Value *CountedByInst = EmitLoadOfCountedByField(Base, FAMDecl, CountedByFD); - if (!CountedByInst) - return getDefaultBuiltinObjectSizeResult(Type, ResType); - - CountedByInst = Builder.CreateIntCast(CountedByInst, ResType, IsSigned); + const Expr *Idx = nullptr; + if (Visitor.ASE) { + Idx = Visitor.ASE->getIdx(); - // Build a load of the index and subtract it from the count. - Value *IdxInst = nullptr; - if (Idx) { - if (Idx->HasSideEffects(getContext())) + if (Idx->HasSideEffects(Ctx)) // We can't have side-effects. return getDefaultBuiltinObjectSizeResult(Type, ResType); + if (const auto *IL = dyn_cast(Idx)) { + int64_t Val = IL->getValue().getSExtValue(); + if (Val < 0) + return getDefaultBuiltinObjectSizeResult(Type, ResType); + + // The index is 0, so we don't need to take it into account. + if (Val == 0) + Idx = nullptr; + } + } + + // Calculate the flexible array member's object size using these formulae + // (note: if the calculation is negative, we return 0.): + // + // struct p; + // struct s { + // /* ... */ + // int count; + // struct p *array[] __attribute__((counted_by(count))); + // }; + // + // 1) 'ptr->array': + // + // count = ptr->count; + // + // flexible_array_member_base_size = sizeof (*ptr->array); + // flexible_array_member_size = + // count * flexible_array_member_base_size; + // + // if (flexible_array_member_size < 0) + // return 0; + // return flexible_array_member_size; + // + // 2) '&ptr->array[idx]': + // + // count = ptr->count; + // index = idx; + // + // flexible_array_member_base_size = sizeof (*ptr->array); + // flexible_array_member_size = + // count * flexible_array_member_base_size; + // + // index_size = index * flexible_array_member_base_size; + // + // if (flexible_array_member_size < 0 || index < 0) + // return 0; + // return flexible_array_member_size - index_size; + // + // 3) '&ptr->field': + // + // count = ptr->count; + // sizeof_struct = sizeof (struct s); + // + // flexible_array_member_base_size = sizeof (*ptr->array); + // flexible_array_member_size = + // count * flexible_array_member_base_size; + // + // field_offset = offsetof (struct s, field); + // offset_diff = sizeof_struct - field_offset; + // + // if (flexible_array_member_size < 0) + // return 0; + // return offset_diff + flexible_array_member_size; + // + // 4) '&ptr->field_array[idx]': + // + // count = ptr->count; + // index = idx; + // sizeof_struct = sizeof (struct s); + // + // flexible_array_member_base_size = sizeof (*ptr->array); + // flexible_array_member_size = + // count * flexible_array_member_base_size; + // + // field_base_size = sizeof (*ptr->field_array); + // field_offset = offsetof (struct s, field) + // field_offset += index * field_base_size; + // + // offset_diff = sizeof_struct - field_offset; + // + // if (flexible_array_member_size < 0 || index < 0) + // return 0; + // return offset_diff + flexible_array_member_size; + + QualType CountTy = CountFD->getType(); + bool IsSigned = CountTy->isSignedIntegerType(); + + QualType FlexibleArrayMemberTy = FlexibleArrayMemberFD->getType(); + QualType FieldTy = FD->getType(); + + // Explicit cast because otherwise the CharWidth will promote an i32's into + // u64's leading to overflows.. + int64_t CharWidth = static_cast(CGM.getContext().getCharWidth()); + + // size_t field_offset = offsetof (struct s, field); + Value *FieldOffset = nullptr; + if (FlexibleArrayMemberFD != FD) { + std::optional Offset = GetFieldOffset(Ctx, RD, FD); + if (!Offset) + return nullptr; + FieldOffset = + llvm::ConstantInt::get(ResType, *Offset / CharWidth, IsSigned); + } + + // size_t count = (size_t) ptr->count; + Value *Count = EmitLoadOfCountedByField(ME, FlexibleArrayMemberFD, CountFD); + if (!Count) + return nullptr; + Count = Builder.CreateIntCast(Count, ResType, IsSigned, "count"); + + // size_t index = (size_t) ptr->index; + Value *Index = nullptr; + if (Idx) { bool IdxSigned = Idx->getType()->isSignedIntegerType(); - IdxInst = EmitAnyExprToTemp(Idx).getScalarVal(); - IdxInst = Builder.CreateIntCast(IdxInst, ResType, IdxSigned); - - // We go ahead with the calculation here. If the index turns out to be - // negative, we'll catch it at the end. - CountedByInst = - Builder.CreateSub(CountedByInst, IdxInst, "", !IsSigned, IsSigned); - } - - // Calculate how large the flexible array member is in bytes. - const ArrayType *ArrayTy = Ctx.getAsArrayType(FAMDecl->getType()); - CharUnits Size = Ctx.getTypeSizeInChars(ArrayTy->getElementType()); - llvm::Constant *ElemSize = - llvm::ConstantInt::get(ResType, Size.getQuantity(), IsSigned); - Value *Res = - Builder.CreateMul(CountedByInst, ElemSize, "", !IsSigned, IsSigned); - Res = Builder.CreateIntCast(Res, ResType, IsSigned); - - // A negative \p IdxInst or \p CountedByInst means that the index lands - // outside of the flexible array member. If that's the case, we want to - // return 0. - Value *Cmp = Builder.CreateIsNotNeg(CountedByInst); - if (IdxInst) - Cmp = Builder.CreateAnd(Builder.CreateIsNotNeg(IdxInst), Cmp); + Index = EmitScalarExpr(Idx); + Index = Builder.CreateIntCast(Index, ResType, IdxSigned, "index"); + } + + // size_t flexible_array_member_base_size = sizeof (*ptr->array); + const ArrayType *ArrayTy = Ctx.getAsArrayType(FlexibleArrayMemberTy); + CharUnits BaseSize = Ctx.getTypeSizeInChars(ArrayTy->getElementType()); + auto *FlexibleArrayMemberBaseSize = + llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned); + + // size_t flexible_array_member_size = + // count * flexible_array_member_base_size; + Value *FlexibleArrayMemberSize = + Builder.CreateMul(Count, FlexibleArrayMemberBaseSize, + "flexible_array_member_size", !IsSigned, IsSigned); + + Value *Res = nullptr; + if (FlexibleArrayMemberFD == FD) { + if (Idx) { // Option (2) '&ptr->array[idx]' + // size_t index_size = index * flexible_array_member_base_size; + Value *IndexSize = Builder.CreateMul(FlexibleArrayMemberBaseSize, Index, + "index_size", !IsSigned, IsSigned); + + // return flexible_array_member_size - index_size; + Res = Builder.CreateSub(FlexibleArrayMemberSize, IndexSize, "result", + !IsSigned, IsSigned); + } else { // Option (1) 'ptr->array' + // return flexible_array_member_size; + Res = FlexibleArrayMemberSize; + } + } else { + // size_t sizeof_struct = sizeof (struct s); + llvm::StructType *StructTy = getTypes().getCGRecordLayout(RD).getLLVMType(); + const llvm::DataLayout &Layout = CGM.getDataLayout(); + TypeSize Size = Layout.getTypeSizeInBits(StructTy); + Value *SizeofStruct = + llvm::ConstantInt::get(ResType, Size.getKnownMinValue() / CharWidth); + + if (Idx) { // Option (4) '&ptr->field_array[idx]' + // size_t field_base_size = sizeof (*ptr->field_array); + const ArrayType *ArrayTy = Ctx.getAsArrayType(FieldTy); + CharUnits BaseSize = Ctx.getTypeSizeInChars(ArrayTy->getElementType()); + auto *FieldBaseSize = + llvm::ConstantInt::get(ResType, BaseSize.getQuantity(), IsSigned); + + // field_offset += index * field_base_size; + Value *Mul = Builder.CreateMul(Index, FieldBaseSize, "field_offset", + !IsSigned, IsSigned); + FieldOffset = Builder.CreateAdd(FieldOffset, Mul); + } + // Option (3) '&ptr->field', and Option (4) continuation. + + // size_t offset_diff = flexible_array_member_offset - field_offset; + Value *OffsetDiff = Builder.CreateSub(SizeofStruct, FieldOffset, + "offset_diff", !IsSigned, IsSigned); + + // return offset_diff + flexible_array_member_size; + Res = Builder.CreateAdd(FlexibleArrayMemberSize, OffsetDiff, "result"); + } + + Value *Cmp = Builder.CreateIsNotNeg(Res); + if (Idx) + Cmp = Builder.CreateAnd(Builder.CreateIsNotNeg(Index), Cmp); return Builder.CreateSelect(Cmp, Res, ConstantInt::get(ResType, 0, IsSigned)); } @@ -1315,13 +1440,6 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, } } - if (IsDynamic) { - // Emit special code for a flexible array member with the "counted_by" - // attribute. - if (Value *V = emitFlexibleArrayMemberSize(E, Type, ResType)) - return V; - } - // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't // evaluate E for side-effects. In either case, we shouldn't lower to // @llvm.objectsize. @@ -1332,6 +1450,12 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, assert(Ptr->getType()->isPointerTy() && "Non-pointer passed to __builtin_object_size?"); + if (IsDynamic) + // Emit special code for a flexible array member with the "counted_by" + // attribute. + if (Value *V = emitCountedByMemberSize(E, Ptr, Type, ResType)) + return V; + Function *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()}); @@ -6454,7 +6578,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, LargestVectorWidth = std::max(LargestVectorWidth, VectorWidth); // See if we have a target specific intrinsic. - StringRef Name = getContext().BuiltinInfo.getName(BuiltinID); + std::string Name = getContext().BuiltinInfo.getName(BuiltinID); Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; StringRef Prefix = llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); @@ -6679,6 +6803,7 @@ static llvm::FixedVectorType *GetNeonType(CodeGenFunction *CGF, switch (TypeFlags.getEltType()) { case NeonTypeFlags::Int8: case NeonTypeFlags::Poly8: + case NeonTypeFlags::MFloat8: return llvm::FixedVectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); case NeonTypeFlags::Int16: case NeonTypeFlags::Poly16: @@ -6758,12 +6883,68 @@ Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl &Ops, return Builder.CreateCall(F, Ops, name); } +Value *CodeGenFunction::EmitFP8NeonCall(unsigned IID, + ArrayRef Tys, + SmallVectorImpl &Ops, + const CallExpr *E, const char *name) { + llvm::Value *FPM = + EmitScalarOrConstFoldImmArg(/* ICEArguments */ 0, E->getNumArgs() - 1, E); + Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_set_fpmr), FPM); + return EmitNeonCall(CGM.getIntrinsic(IID, Tys), Ops, name); +} + +llvm::Value *CodeGenFunction::EmitFP8NeonFDOTCall( + unsigned IID, bool ExtendLaneArg, llvm::Type *RetTy, + SmallVectorImpl &Ops, const CallExpr *E, const char *name) { + + const unsigned ElemCount = Ops[0]->getType()->getPrimitiveSizeInBits() / + RetTy->getPrimitiveSizeInBits(); + llvm::Type *Tys[] = {llvm::FixedVectorType::get(RetTy, ElemCount), + Ops[1]->getType()}; + if (ExtendLaneArg) { + auto *VT = llvm::FixedVectorType::get(Int8Ty, 16); + Ops[2] = Builder.CreateInsertVector(VT, PoisonValue::get(VT), Ops[2], + Builder.getInt64(0)); + } + return EmitFP8NeonCall(IID, Tys, Ops, E, name); +} + +llvm::Value *CodeGenFunction::EmitFP8NeonFMLACall( + unsigned IID, bool ExtendLaneArg, llvm::Type *RetTy, + SmallVectorImpl &Ops, const CallExpr *E, const char *name) { + + if (ExtendLaneArg) { + auto *VT = llvm::FixedVectorType::get(Int8Ty, 16); + Ops[2] = Builder.CreateInsertVector(VT, PoisonValue::get(VT), Ops[2], + Builder.getInt64(0)); + } + const unsigned ElemCount = Ops[0]->getType()->getPrimitiveSizeInBits() / + RetTy->getPrimitiveSizeInBits(); + return EmitFP8NeonCall(IID, {llvm::FixedVectorType::get(RetTy, ElemCount)}, + Ops, E, name); +} + Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, bool neg) { int SV = cast(V)->getSExtValue(); return ConstantInt::get(Ty, neg ? -SV : SV); } +Value *CodeGenFunction::EmitFP8NeonCvtCall(unsigned IID, llvm::Type *Ty0, + llvm::Type *Ty1, bool Extract, + SmallVectorImpl &Ops, + const CallExpr *E, + const char *name) { + llvm::Type *Tys[] = {Ty0, Ty1}; + if (Extract) { + // Op[0] is mfloat8x16_t, but the intrinsic converts only the lower part of + // the vector. + Tys[1] = llvm::FixedVectorType::get(Int8Ty, 8); + Ops[0] = Builder.CreateExtractVector(Tys[1], Ops[0], Builder.getInt64(0)); + } + return EmitFP8NeonCall(IID, Tys, Ops, E, name); +} + // Right-shift a vector by a constant. Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, llvm::Type *Ty, bool usgn, @@ -12735,6 +12916,8 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return V; unsigned Int; + bool ExtractLow = false; + bool ExtendLaneArg = false; switch (BuiltinID) { default: return nullptr; case NEON::BI__builtin_neon_vbsl_v: @@ -13949,7 +14132,145 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Int = Intrinsic::aarch64_neon_vluti4q_laneq_x2; return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vluti4q_laneq_x2"); } - + case NEON::BI__builtin_neon_vcvt1_low_bf16_mf8_fpm: + ExtractLow = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vcvt1_bf16_mf8_fpm: + case NEON::BI__builtin_neon_vcvt1_high_bf16_mf8_fpm: + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_cvtl1, + llvm::FixedVectorType::get(BFloatTy, 8), + Ops[0]->getType(), ExtractLow, Ops, E, "vbfcvt1"); + case NEON::BI__builtin_neon_vcvt2_low_bf16_mf8_fpm: + ExtractLow = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vcvt2_bf16_mf8_fpm: + case NEON::BI__builtin_neon_vcvt2_high_bf16_mf8_fpm: + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_cvtl2, + llvm::FixedVectorType::get(BFloatTy, 8), + Ops[0]->getType(), ExtractLow, Ops, E, "vbfcvt2"); + case NEON::BI__builtin_neon_vcvt1_low_f16_mf8_fpm: + ExtractLow = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vcvt1_f16_mf8_fpm: + case NEON::BI__builtin_neon_vcvt1_high_f16_mf8_fpm: + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_cvtl1, + llvm::FixedVectorType::get(HalfTy, 8), + Ops[0]->getType(), ExtractLow, Ops, E, "vbfcvt1"); + case NEON::BI__builtin_neon_vcvt2_low_f16_mf8_fpm: + ExtractLow = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vcvt2_f16_mf8_fpm: + case NEON::BI__builtin_neon_vcvt2_high_f16_mf8_fpm: + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_cvtl2, + llvm::FixedVectorType::get(HalfTy, 8), + Ops[0]->getType(), ExtractLow, Ops, E, "vbfcvt2"); + case NEON::BI__builtin_neon_vcvt_mf8_f32_fpm: + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_fcvtn, + llvm::FixedVectorType::get(Int8Ty, 8), + Ops[0]->getType(), false, Ops, E, "vfcvtn"); + case NEON::BI__builtin_neon_vcvt_mf8_f16_fpm: + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_fcvtn, + llvm::FixedVectorType::get(Int8Ty, 8), + llvm::FixedVectorType::get(HalfTy, 4), false, Ops, + E, "vfcvtn"); + case NEON::BI__builtin_neon_vcvtq_mf8_f16_fpm: + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_fcvtn, + llvm::FixedVectorType::get(Int8Ty, 16), + llvm::FixedVectorType::get(HalfTy, 8), false, Ops, + E, "vfcvtn"); + case NEON::BI__builtin_neon_vcvt_high_mf8_f32_fpm: { + llvm::Type *Ty = llvm::FixedVectorType::get(Int8Ty, 16); + Ops[0] = Builder.CreateInsertVector(Ty, PoisonValue::get(Ty), Ops[0], + Builder.getInt64(0)); + return EmitFP8NeonCvtCall(Intrinsic::aarch64_neon_fp8_fcvtn2, Ty, + Ops[1]->getType(), false, Ops, E, "vfcvtn2"); + } + + case NEON::BI__builtin_neon_vdot_f16_mf8_fpm: + case NEON::BI__builtin_neon_vdotq_f16_mf8_fpm: + return EmitFP8NeonFDOTCall(Intrinsic::aarch64_neon_fp8_fdot2, false, HalfTy, + Ops, E, "fdot2"); + case NEON::BI__builtin_neon_vdot_lane_f16_mf8_fpm: + case NEON::BI__builtin_neon_vdotq_lane_f16_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vdot_laneq_f16_mf8_fpm: + case NEON::BI__builtin_neon_vdotq_laneq_f16_mf8_fpm: + return EmitFP8NeonFDOTCall(Intrinsic::aarch64_neon_fp8_fdot2_lane, + ExtendLaneArg, HalfTy, Ops, E, "fdot2_lane"); + case NEON::BI__builtin_neon_vdot_f32_mf8_fpm: + case NEON::BI__builtin_neon_vdotq_f32_mf8_fpm: + return EmitFP8NeonFDOTCall(Intrinsic::aarch64_neon_fp8_fdot4, false, + FloatTy, Ops, E, "fdot4"); + case NEON::BI__builtin_neon_vdot_lane_f32_mf8_fpm: + case NEON::BI__builtin_neon_vdotq_lane_f32_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vdot_laneq_f32_mf8_fpm: + case NEON::BI__builtin_neon_vdotq_laneq_f32_mf8_fpm: + return EmitFP8NeonFDOTCall(Intrinsic::aarch64_neon_fp8_fdot4_lane, + ExtendLaneArg, FloatTy, Ops, E, "fdot4_lane"); + + case NEON::BI__builtin_neon_vmlalbq_f16_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fp8_fmlalb, + {llvm::FixedVectorType::get(HalfTy, 8)}, Ops, E, + "vmlal"); + case NEON::BI__builtin_neon_vmlaltq_f16_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fp8_fmlalt, + {llvm::FixedVectorType::get(HalfTy, 8)}, Ops, E, + "vmlal"); + case NEON::BI__builtin_neon_vmlallbbq_f32_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fp8_fmlallbb, + {llvm::FixedVectorType::get(FloatTy, 4)}, Ops, E, + "vmlall"); + case NEON::BI__builtin_neon_vmlallbtq_f32_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fp8_fmlallbt, + {llvm::FixedVectorType::get(FloatTy, 4)}, Ops, E, + "vmlall"); + case NEON::BI__builtin_neon_vmlalltbq_f32_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fp8_fmlalltb, + {llvm::FixedVectorType::get(FloatTy, 4)}, Ops, E, + "vmlall"); + case NEON::BI__builtin_neon_vmlallttq_f32_mf8_fpm: + return EmitFP8NeonCall(Intrinsic::aarch64_neon_fp8_fmlalltt, + {llvm::FixedVectorType::get(FloatTy, 4)}, Ops, E, + "vmlall"); + case NEON::BI__builtin_neon_vmlalbq_lane_f16_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vmlalbq_laneq_f16_mf8_fpm: + return EmitFP8NeonFMLACall(Intrinsic::aarch64_neon_fp8_fmlalb_lane, + ExtendLaneArg, HalfTy, Ops, E, "vmlal_lane"); + case NEON::BI__builtin_neon_vmlaltq_lane_f16_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vmlaltq_laneq_f16_mf8_fpm: + return EmitFP8NeonFMLACall(Intrinsic::aarch64_neon_fp8_fmlalt_lane, + ExtendLaneArg, HalfTy, Ops, E, "vmlal_lane"); + case NEON::BI__builtin_neon_vmlallbbq_lane_f32_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vmlallbbq_laneq_f32_mf8_fpm: + return EmitFP8NeonFMLACall(Intrinsic::aarch64_neon_fp8_fmlallbb_lane, + ExtendLaneArg, FloatTy, Ops, E, "vmlall_lane"); + case NEON::BI__builtin_neon_vmlallbtq_lane_f32_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vmlallbtq_laneq_f32_mf8_fpm: + return EmitFP8NeonFMLACall(Intrinsic::aarch64_neon_fp8_fmlallbt_lane, + ExtendLaneArg, FloatTy, Ops, E, "vmlall_lane"); + case NEON::BI__builtin_neon_vmlalltbq_lane_f32_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vmlalltbq_laneq_f32_mf8_fpm: + return EmitFP8NeonFMLACall(Intrinsic::aarch64_neon_fp8_fmlalltb_lane, + ExtendLaneArg, FloatTy, Ops, E, "vmlall_lane"); + case NEON::BI__builtin_neon_vmlallttq_lane_f32_mf8_fpm: + ExtendLaneArg = true; + LLVM_FALLTHROUGH; + case NEON::BI__builtin_neon_vmlallttq_laneq_f32_mf8_fpm: + return EmitFP8NeonFMLACall(Intrinsic::aarch64_neon_fp8_fmlalltt_lane, + ExtendLaneArg, FloatTy, Ops, E, "vmlall_lane"); case NEON::BI__builtin_neon_vamin_f16: case NEON::BI__builtin_neon_vaminq_f16: case NEON::BI__builtin_neon_vamin_f32: @@ -19098,6 +19419,25 @@ static Intrinsic::ID getWaveActiveSumIntrinsic(llvm::Triple::ArchType Arch, } } +// Return wave active sum that corresponds to the QT scalar type +static Intrinsic::ID getWaveActiveMaxIntrinsic(llvm::Triple::ArchType Arch, + CGHLSLRuntime &RT, QualType QT) { + switch (Arch) { + case llvm::Triple::spirv: + if (QT->isUnsignedIntegerType()) + return llvm::Intrinsic::spv_wave_reduce_umax; + return llvm::Intrinsic::spv_wave_reduce_max; + case llvm::Triple::dxil: { + if (QT->isUnsignedIntegerType()) + return llvm::Intrinsic::dx_wave_reduce_umax; + return llvm::Intrinsic::dx_wave_reduce_max; + } + default: + llvm_unreachable("Intrinsic WaveActiveMax" + " not supported by target architecture"); + } +} + Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue) { @@ -19105,6 +19445,70 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, return nullptr; switch (BuiltinID) { + case Builtin::BI__builtin_hlsl_adduint64: { + Value *OpA = EmitScalarExpr(E->getArg(0)); + Value *OpB = EmitScalarExpr(E->getArg(1)); + assert(E->getArg(0)->getType()->hasIntegerRepresentation() && + E->getArg(1)->getType()->hasIntegerRepresentation() && + "AddUint64 operands must have an integer representation"); + assert(((E->getArg(0)->getType()->castAs()->getNumElements() == + 2 && + E->getArg(1)->getType()->castAs()->getNumElements() == + 2) || + (E->getArg(0)->getType()->castAs()->getNumElements() == + 4 && + E->getArg(1)->getType()->castAs()->getNumElements() == + 4)) && + "input vectors must have 2 or 4 elements each"); + + uint64_t NumElements = + E->getArg(0)->getType()->castAs()->getNumElements(); + + llvm::Value *Result = PoisonValue::get(OpA->getType()); + llvm::Value *LowA; + llvm::Value *HighA; + llvm::Value *LowB; + llvm::Value *HighB; + + // Obtain low and high words of inputs A and B + if (NumElements == 2) { + LowA = Builder.CreateExtractElement(OpA, (uint64_t)0, "LowA"); + HighA = Builder.CreateExtractElement(OpA, (uint64_t)1, "HighA"); + LowB = Builder.CreateExtractElement(OpB, (uint64_t)0, "LowB"); + HighB = Builder.CreateExtractElement(OpB, (uint64_t)1, "HighB"); + } else { + LowA = Builder.CreateShuffleVector(OpA, ArrayRef{0, 2}, "LowA"); + HighA = Builder.CreateShuffleVector(OpA, ArrayRef{1, 3}, "HighA"); + LowB = Builder.CreateShuffleVector(OpB, ArrayRef{0, 2}, "LowB"); + HighB = Builder.CreateShuffleVector(OpB, ArrayRef{1, 3}, "HighB"); + } + + // Use an uadd_with_overflow to compute the sum of low words and obtain a + // carry value + llvm::Value *Carry; + llvm::Value *LowSum = EmitOverflowIntrinsic( + *this, llvm::Intrinsic::uadd_with_overflow, LowA, LowB, Carry); + llvm::Value *ZExtCarry = + Builder.CreateZExt(Carry, HighA->getType(), "CarryZExt"); + + // Sum the high words and the carry + llvm::Value *HighSum = Builder.CreateAdd(HighA, HighB, "HighSum"); + llvm::Value *HighSumPlusCarry = + Builder.CreateAdd(HighSum, ZExtCarry, "HighSumPlusCarry"); + + // Insert the low and high word sums into the result vector + if (NumElements == 2) { + Result = Builder.CreateInsertElement(Result, LowSum, (uint64_t)0, + "hlsl.AddUint64.upto0"); + Result = Builder.CreateInsertElement(Result, HighSumPlusCarry, + (uint64_t)1, "hlsl.AddUint64"); + } else { /* NumElements == 4 */ + Result = Builder.CreateShuffleVector(LowSum, HighSumPlusCarry, + ArrayRef{0, 2, 1, 3}, + "hlsl.AddUint64"); + } + return Result; + } case Builtin::BI__builtin_hlsl_resource_getpointer: { Value *HandleOp = EmitScalarExpr(E->getArg(0)); Value *IndexOp = EmitScalarExpr(E->getArg(1)); @@ -19427,6 +19831,23 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*AssumeConvergent=*/true), ArrayRef{OpExpr}, "hlsl.wave.active.sum"); } + case Builtin::BI__builtin_hlsl_wave_active_max: { + // Due to the use of variadic arguments, explicitly retreive argument + Value *OpExpr = EmitScalarExpr(E->getArg(0)); + llvm::FunctionType *FT = llvm::FunctionType::get( + OpExpr->getType(), ArrayRef{OpExpr->getType()}, false); + Intrinsic::ID IID = getWaveActiveMaxIntrinsic( + getTarget().getTriple().getArch(), CGM.getHLSLRuntime(), + E->getArg(0)->getType()); + + // Get overloaded name + std::string Name = + Intrinsic::getName(IID, ArrayRef{OpExpr->getType()}, &CGM.getModule()); + return EmitRuntimeCall(CGM.CreateRuntimeFunction(FT, Name, {}, + /*Local=*/false, + /*AssumeConvergent=*/true), + ArrayRef{OpExpr}, "hlsl.wave.active.max"); + } case Builtin::BI__builtin_hlsl_wave_get_lane_index: { // We don't define a SPIR-V intrinsic, instead it is a SPIR-V built-in // defined in SPIRVBuiltins.td. So instead we manually get the matching name @@ -21216,7 +21637,7 @@ static Value *MakeHalfType(unsigned IntrinsicID, unsigned BuiltinID, auto &C = CGF.CGM.getContext(); if (!(C.getLangOpts().NativeHalfType || !C.getTargetInfo().useFP16ConversionIntrinsics())) { - CGF.CGM.Error(E->getExprLoc(), C.BuiltinInfo.getName(BuiltinID).str() + + CGF.CGM.Error(E->getExprLoc(), C.BuiltinInfo.getQuotedName(BuiltinID) + " requires native half type support."); return nullptr; } @@ -22051,7 +22472,7 @@ RValue CodeGenFunction::EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp) { // By adding the mask, we ensure that align_up on an already aligned // value will not change the value. if (Args.Src->getType()->isPointerTy()) { - if (getLangOpts().isSignedOverflowDefined()) + if (getLangOpts().PointerOverflowDefined) SrcForMask = Builder.CreateGEP(Int8Ty, SrcForMask, Args.Mask, "over_boundary"); else diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 23a40b8f7c32a..5445a9278596d 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -40,8 +40,6 @@ class CGNVCUDARuntime : public CGCUDARuntime { /// The prefix used for function calls and section names (CUDA, HIP, LLVM) StringRef Prefix; - /// TODO: We should transition the OpenMP section to LLVM/Offload - StringRef SectionPrefix; private: llvm::IntegerType *IntTy, *SizeTy; @@ -234,13 +232,12 @@ CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM) VoidTy = CGM.VoidTy; PtrTy = CGM.UnqualPtrTy; - if (CGM.getLangOpts().OffloadViaLLVM) { + if (CGM.getLangOpts().OffloadViaLLVM) Prefix = "llvm"; - SectionPrefix = "omp"; - } else if (CGM.getLangOpts().HIP) - SectionPrefix = Prefix = "hip"; + else if (CGM.getLangOpts().HIP) + Prefix = "hip"; else - SectionPrefix = Prefix = "cuda"; + Prefix = "cuda"; } llvm::FunctionCallee CGNVCUDARuntime::getSetupArgumentFn() const { @@ -1198,14 +1195,19 @@ void CGNVCUDARuntime::transformManagedVars() { // register the symbols with the linked device image. void CGNVCUDARuntime::createOffloadingEntries() { SmallVector Out; - StringRef Section = (SectionPrefix + "_offloading_entries").toStringRef(Out); + llvm::object::OffloadKind Kind = CGM.getLangOpts().HIP + ? llvm::object::OffloadKind::OFK_HIP + : llvm::object::OffloadKind::OFK_Cuda; + // For now, just spoof this as OpenMP because that's the runtime it uses. + if (CGM.getLangOpts().OffloadViaLLVM) + Kind = llvm::object::OffloadKind::OFK_OpenMP; llvm::Module &M = CGM.getModule(); for (KernelInfo &I : EmittedKernels) llvm::offloading::emitOffloadingEntry( - M, KernelHandles[I.Kernel->getName()], + M, Kind, KernelHandles[I.Kernel->getName()], getDeviceSideName(cast(I.D)), /*Flags=*/0, /*Data=*/0, - llvm::offloading::OffloadGlobalEntry, Section); + llvm::offloading::OffloadGlobalEntry); for (VarInfo &I : DeviceVars) { uint64_t VarSize = @@ -1221,44 +1223,32 @@ void CGNVCUDARuntime::createOffloadingEntries() { ? static_cast(llvm::offloading::OffloadGlobalNormalized) : 0); if (I.Flags.getKind() == DeviceVarFlags::Variable) { - // TODO: Update the offloading entries struct to avoid this indirection. if (I.Flags.isManaged()) { assert(I.Var->getName().ends_with(".managed") && "HIP managed variables not transformed"); - // Create a struct to contain the two variables. auto *ManagedVar = M.getNamedGlobal( I.Var->getName().drop_back(StringRef(".managed").size())); - llvm::Constant *StructData[] = {ManagedVar, I.Var}; - llvm::Constant *Initializer = llvm::ConstantStruct::get( - llvm::offloading::getManagedTy(M), StructData); - auto *Struct = new llvm::GlobalVariable( - M, llvm::offloading::getManagedTy(M), - /*IsConstant=*/true, llvm::GlobalValue::PrivateLinkage, Initializer, - I.Var->getName(), /*InsertBefore=*/nullptr, - llvm::GlobalVariable::NotThreadLocal, - M.getDataLayout().getDefaultGlobalsAddressSpace()); - llvm::offloading::emitOffloadingEntry( - M, Struct, getDeviceSideName(I.D), VarSize, + M, Kind, I.Var, getDeviceSideName(I.D), VarSize, llvm::offloading::OffloadGlobalManagedEntry | Flags, - /*Data=*/static_cast(I.Var->getAlignment()), Section); + /*Data=*/I.Var->getAlignment(), ManagedVar); } else { llvm::offloading::emitOffloadingEntry( - M, I.Var, getDeviceSideName(I.D), VarSize, + M, Kind, I.Var, getDeviceSideName(I.D), VarSize, llvm::offloading::OffloadGlobalEntry | Flags, - /*Data=*/0, Section); + /*Data=*/0); } } else if (I.Flags.getKind() == DeviceVarFlags::Surface) { llvm::offloading::emitOffloadingEntry( - M, I.Var, getDeviceSideName(I.D), VarSize, + M, Kind, I.Var, getDeviceSideName(I.D), VarSize, llvm::offloading::OffloadGlobalSurfaceEntry | Flags, - I.Flags.getSurfTexType(), Section); + I.Flags.getSurfTexType()); } else if (I.Flags.getKind() == DeviceVarFlags::Texture) { llvm::offloading::emitOffloadingEntry( - M, I.Var, getDeviceSideName(I.D), VarSize, + M, Kind, I.Var, getDeviceSideName(I.D), VarSize, llvm::offloading::OffloadGlobalTextureEntry | Flags, - I.Flags.getSurfTexType(), Section); + I.Flags.getSurfTexType()); } } } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index e0cf6ca69f0df..2dce86410db85 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2881,7 +2881,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, } if (FI.getExtParameterInfo(ArgNo).isNoEscape()) - Attrs.addAttribute(llvm::Attribute::NoCapture); + Attrs.addCapturesAttr(llvm::CaptureInfo::none()); if (Attrs.hasAttributes()) { unsigned FirstIRArg, NumIRArgs; @@ -3581,15 +3581,26 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) { llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock(); if (IP->empty()) return nullptr; - // Look at directly preceding instruction, skipping bitcasts and lifetime - // markers. + // Look at directly preceding instruction, skipping bitcasts, lifetime + // markers, and fake uses and their operands. + const llvm::Instruction *LoadIntoFakeUse = nullptr; for (llvm::Instruction &I : make_range(IP->rbegin(), IP->rend())) { + // Ignore instructions that are just loads for fake uses; the load should + // immediately precede the fake use, so we only need to remember the + // operand for the last fake use seen. + if (LoadIntoFakeUse == &I) + continue; if (isa(&I)) continue; - if (auto *II = dyn_cast(&I)) + if (auto *II = dyn_cast(&I)) { if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end) continue; + if (II->getIntrinsicID() == llvm::Intrinsic::fake_use) { + LoadIntoFakeUse = dyn_cast(II->getArgOperand(0)); + continue; + } + } return GetStoreIfValid(&I); } return nullptr; diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index d9c0dbe45d6cf..7e1c5b7da9552 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -112,11 +112,15 @@ void EHScopeStack::deallocate(size_t Size) { StartOfData += llvm::alignTo(Size, ScopeStackAlignment); } -bool EHScopeStack::containsOnlyLifetimeMarkers( +bool EHScopeStack::containsOnlyNoopCleanups( EHScopeStack::stable_iterator Old) const { for (EHScopeStack::iterator it = begin(); stabilize(it) != Old; it++) { EHCleanupScope *cleanup = dyn_cast(&*it); - if (!cleanup || !cleanup->isLifetimeMarker()) + // If this is anything other than a lifetime marker or fake use cleanup, + // then the scope stack does not contain only noop cleanups. + if (!cleanup) + return false; + if (!cleanup->isLifetimeMarker() && !cleanup->isFakeUse()) return false; } @@ -154,6 +158,7 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) { bool IsNormalCleanup = Kind & NormalCleanup; bool IsEHCleanup = Kind & EHCleanup; bool IsLifetimeMarker = Kind & LifetimeMarker; + bool IsFakeUse = Kind & FakeUse; // Per C++ [except.terminate], it is implementation-defined whether none, // some, or all cleanups are called before std::terminate. Thus, when @@ -176,6 +181,8 @@ void *EHScopeStack::pushCleanup(CleanupKind Kind, size_t Size) { InnermostEHScope = stable_begin(); if (IsLifetimeMarker) Scope->setLifetimeMarker(); + if (IsFakeUse) + Scope->setFakeUse(); // With Windows -EHa, Invoke llvm.seh.scope.begin() for EHCleanup // If exceptions are disabled/ignored and SEH is not in use, then there is no diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h index c73c97146abc4..ba78e5478ac37 100644 --- a/clang/lib/CodeGen/CGCleanup.h +++ b/clang/lib/CodeGen/CGCleanup.h @@ -87,6 +87,10 @@ class EHScope { LLVM_PREFERRED_TYPE(bool) unsigned IsLifetimeMarker : 1; + /// Whether this cleanup is a fake use + LLVM_PREFERRED_TYPE(bool) + unsigned IsFakeUse : 1; + /// Whether the normal cleanup should test the activation flag. LLVM_PREFERRED_TYPE(bool) unsigned TestFlagInNormalCleanup : 1; @@ -352,6 +356,7 @@ class alignas(8) EHCleanupScope : public EHScope { CleanupBits.IsEHCleanup = isEH; CleanupBits.IsActive = true; CleanupBits.IsLifetimeMarker = false; + CleanupBits.IsFakeUse = false; CleanupBits.TestFlagInNormalCleanup = false; CleanupBits.TestFlagInEHCleanup = false; CleanupBits.CleanupSize = cleanupSize; @@ -384,6 +389,9 @@ class alignas(8) EHCleanupScope : public EHScope { bool isLifetimeMarker() const { return CleanupBits.IsLifetimeMarker; } void setLifetimeMarker() { CleanupBits.IsLifetimeMarker = true; } + bool isFakeUse() const { return CleanupBits.IsFakeUse; } + void setFakeUse() { CleanupBits.IsFakeUse = true; } + bool hasActiveFlag() const { return ActiveFlag.isValid(); } Address getActiveFlag() const { return ActiveFlag; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 6cbcaf0384410..d5b584ec0f2e9 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2815,7 +2815,7 @@ static bool shouldOmitDefinition(llvm::codegenoptions::DebugInfoKind DebugKind, // without any dllimport methods can be used in one DLL and constructed in // another, but it is the current behavior of LimitedDebugInfo. if (CXXDecl->hasDefinition() && CXXDecl->isDynamicClass() && - !isClassOrMethodDLLImport(CXXDecl)) + !isClassOrMethodDLLImport(CXXDecl) && !CXXDecl->hasAttr()) return true; TemplateSpecializationKind Spec = TSK_Undeclared; @@ -3567,6 +3567,10 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) { DBuilder.createEnumerator(Enum->getName(), Enum->getInitVal())); } + std::optional EnumKind; + if (auto *Attr = ED->getAttr()) + EnumKind = Attr->getExtensibility(); + // Return a CompositeType for the enum itself. llvm::DINodeArray EltArray = DBuilder.getOrCreateArray(Enumerators); @@ -3576,7 +3580,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) { llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit); return DBuilder.createEnumerationType( EnumContext, ED->getName(), DefUnit, Line, Size, Align, EltArray, ClassTy, - /*RunTimeLang=*/0, Identifier, ED->isScoped()); + /*RunTimeLang=*/0, Identifier, ED->isScoped(), EnumKind); } llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent, @@ -5083,10 +5087,9 @@ CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage, assert(CGM.getCodeGenOpts().hasReducedDebugInfo()); if (auto *DD = dyn_cast(VD)) { - for (auto *B : DD->bindings()) { + for (BindingDecl *B : DD->flat_bindings()) EmitDeclare(B, Storage, std::nullopt, Builder, VD->getType()->isReferenceType()); - } // Don't emit an llvm.dbg.declare for the composite storage as it doesn't // correspond to a user variable. return nullptr; diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 60f67d4640370..668282a6ab1a8 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -164,9 +164,10 @@ void CodeGenFunction::EmitDecl(const Decl &D) { "Should not see file-scope variables inside a function!"); EmitVarDecl(VD); if (auto *DD = dyn_cast(&VD)) - for (auto *B : DD->bindings()) + for (auto *B : DD->flat_bindings()) if (auto *HD = B->getHoldingVar()) EmitVarDecl(*HD); + return; } @@ -1355,6 +1356,14 @@ void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) { C->setDoesNotThrow(); } +void CodeGenFunction::EmitFakeUse(Address Addr) { + auto NL = ApplyDebugLocation::CreateEmpty(*this); + llvm::Value *V = Builder.CreateLoad(Addr, "fake.use"); + llvm::CallInst *C = Builder.CreateCall(CGM.getLLVMFakeUseFn(), {V}); + C->setDoesNotThrow(); + C->setTailCallKind(llvm::CallInst::TCK_NoTail); +} + void CodeGenFunction::EmitAndRegisterVariableArrayDimensions( CGDebugInfo *DI, const VarDecl &D, bool EmitDebugInfo) { // For each dimension stores its QualType and corresponding @@ -1414,6 +1423,39 @@ void CodeGenFunction::EmitAndRegisterVariableArrayDimensions( } } +/// Return the maximum size of an aggregate for which we generate a fake use +/// intrinsic when -fextend-variable-liveness is in effect. +static uint64_t maxFakeUseAggregateSize(const ASTContext &C) { + return 4 * C.getTypeSize(C.UnsignedIntTy); +} + +// Helper function to determine whether a variable's or parameter's lifetime +// should be extended. +static bool shouldExtendLifetime(const ASTContext &Context, + const Decl *FuncDecl, const VarDecl &D, + ImplicitParamDecl *CXXABIThisDecl) { + // When we're not inside a valid function it is unlikely that any + // lifetime extension is useful. + if (!FuncDecl) + return false; + if (FuncDecl->isImplicit()) + return false; + // Do not extend compiler-created variables except for the this pointer. + if (D.isImplicit() && &D != CXXABIThisDecl) + return false; + QualType Ty = D.getType(); + // No need to extend volatiles, they have a memory location. + if (Ty.isVolatileQualified()) + return false; + // Don't extend variables that exceed a certain size. + if (Context.getTypeSize(Ty) > maxFakeUseAggregateSize(Context)) + return false; + // Do not extend variables in nodebug or optnone functions. + if (FuncDecl->hasAttr() || FuncDecl->hasAttr()) + return false; + return true; +} + /// EmitAutoVarAlloca - Emit the alloca and debug information for a /// local variable. Does not emit initialization or destruction. CodeGenFunction::AutoVarEmission @@ -1666,6 +1708,18 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { emission.getOriginalAllocatedAddress(), emission.getSizeForLifetimeMarkers()); + // Analogous to lifetime markers, we use a 'cleanup' to emit fake.use + // calls for local variables. We are exempting volatile variables and + // non-scalars larger than 4 times the size of an unsigned int. Larger + // non-scalars are often allocated in memory and may create unnecessary + // overhead. + if (CGM.getCodeGenOpts().getExtendVariableLiveness() == + CodeGenOptions::ExtendVariableLivenessKind::All) { + if (shouldExtendLifetime(getContext(), CurCodeDecl, D, CXXABIThisDecl)) + EHStack.pushCleanup(NormalFakeUse, + emission.getAllocatedAddress()); + } + return emission; } @@ -2532,6 +2586,15 @@ llvm::Function *CodeGenModule::getLLVMLifetimeEndFn() { return LifetimeEndFn; } +/// Lazily declare the @llvm.fake.use intrinsic. +llvm::Function *CodeGenModule::getLLVMFakeUseFn() { + if (FakeUseFn) + return FakeUseFn; + FakeUseFn = llvm::Intrinsic::getOrInsertDeclaration( + &getModule(), llvm::Intrinsic::fake_use); + return FakeUseFn; +} + namespace { /// A cleanup to perform a release of an object at the end of a /// function. This is used to balance out the incoming +1 of a @@ -2725,6 +2788,18 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg, setAddrOfLocalVar(&D, DeclPtr); + // Push a FakeUse 'cleanup' object onto the EHStack for the parameter, + // which may be the 'this' pointer. This causes the emission of a fake.use + // call with the parameter as argument at the end of the function. + if (CGM.getCodeGenOpts().getExtendVariableLiveness() == + CodeGenOptions::ExtendVariableLivenessKind::All || + (CGM.getCodeGenOpts().getExtendVariableLiveness() == + CodeGenOptions::ExtendVariableLivenessKind::This && + &D == CXXABIThisDecl)) { + if (shouldExtendLifetime(getContext(), CurCodeDecl, D, CXXABIThisDecl)) + EHStack.pushCleanup(NormalFakeUse, DeclPtr); + } + // Emit debug info for param declarations in non-thunk functions. if (CGDebugInfo *DI = getDebugInfo()) { if (CGM.getCodeGenOpts().hasReducedDebugInfo() && !CurFuncIsThunk && @@ -2795,15 +2870,12 @@ void CodeGenModule::EmitOMPAllocateDecl(const OMPAllocateDecl *D) { // We can also keep the existing global if the address space is what we // expect it to be, if not, it is replaced. - QualType ASTTy = VD->getType(); clang::LangAS GVAS = GetGlobalVarAddressSpace(VD); auto TargetAS = getContext().getTargetAddressSpace(GVAS); if (Entry->getType()->getAddressSpace() == TargetAS) continue; - // Make a new global with the correct type / address space. - llvm::Type *Ty = getTypes().ConvertTypeForMem(ASTTy); - llvm::PointerType *PTy = llvm::PointerType::get(Ty, TargetAS); + llvm::PointerType *PTy = llvm::PointerType::get(getLLVMContext(), TargetAS); // Replace all uses of the old global with a cast. Since we mutate the type // in place we neeed an intermediate that takes the spot of the old entry @@ -2816,8 +2888,7 @@ void CodeGenModule::EmitOMPAllocateDecl(const OMPAllocateDecl *D) { Entry->mutateType(PTy); llvm::Constant *NewPtrForOldDecl = - llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( - Entry, DummyGV->getType()); + llvm::ConstantExpr::getAddrSpaceCast(Entry, DummyGV->getType()); // Now we have a casted version of the changed global, the dummy can be // replaced and deleted. diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 1c2fecea1a6ac..f5950f03673a1 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -345,10 +345,7 @@ void CodeGenFunction::registerGlobalDtorWithLLVM(const VarDecl &VD, void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtorStub) { // extern "C" int atexit(void (*f)(void)); - assert(dtorStub->getType() == - llvm::PointerType::get( - llvm::FunctionType::get(CGM.VoidTy, false), - dtorStub->getType()->getPointerAddressSpace()) && + assert(dtorStub->getType()->isPointerTy() && "Argument to atexit has a wrong type."); llvm::FunctionType *atexitTy = @@ -372,10 +369,7 @@ CodeGenFunction::unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub) { // value is returned. // // extern "C" int unatexit(void (*f)(void)); - assert(dtorStub->getType() == - llvm::PointerType::get( - llvm::FunctionType::get(CGM.VoidTy, false), - dtorStub->getType()->getPointerAddressSpace()) && + assert(dtorStub->getType()->isPointerTy() && "Argument to unatexit has a wrong type."); llvm::FunctionType *unatexitTy = diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 054f8d1eadb8c..2bbc0791c6587 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -24,6 +24,7 @@ #include "ConstantEmitter.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/NSAPI.h" @@ -871,7 +872,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *TypeHash = llvm::ConstantInt::get(Int64Ty, xxh3_64bits(Out.str())); - llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0); + llvm::Type *VPtrTy = llvm::PointerType::get(getLLVMContext(), 0); Address VPtrAddr(Ptr, IntPtrTy, getPointerAlign()); llvm::Value *VPtrVal = GetVTablePtr(VPtrAddr, VPtrTy, Ty->getAsCXXRecordDecl(), @@ -1809,8 +1810,7 @@ CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) { if (CGM.getLangOpts().CUDAIsDevice && result.Val.isLValue() && refExpr->refersToEnclosingVariableOrCapture()) { auto *MD = dyn_cast_or_null(CurCodeDecl); - if (MD && MD->getParent()->isLambda() && - MD->getOverloadedOperator() == OO_Call) { + if (isLambdaMethod(MD) && MD->getOverloadedOperator() == OO_Call) { const APValue::LValueBase &base = result.Val.getLValueBase(); if (const ValueDecl *D = base.dyn_cast()) { if (const VarDecl *VD = dyn_cast(D)) { @@ -2414,8 +2414,15 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, Vec = Builder.CreateBitCast(Vec, IRVecTy); // iN --> . } - Vec = Builder.CreateInsertElement(Vec, Src.getScalarVal(), - Dst.getVectorIdx(), "vecins"); + llvm::Value *SrcVal = Src.getScalarVal(); + // Allow inserting `<1 x T>` into an ``. It can happen with scalar + // types which are mapped to vector LLVM IR types (e.g. for implementing + // an ABI). + if (auto *EltTy = dyn_cast(SrcVal->getType()); + EltTy && EltTy->getNumElements() == 1) + SrcVal = Builder.CreateBitCast(SrcVal, EltTy->getElementType()); + Vec = Builder.CreateInsertElement(Vec, SrcVal, Dst.getVectorIdx(), + "vecins"); if (IRStoreTy) { // --> . Vec = Builder.CreateBitCast(Vec, IRStoreTy); @@ -3047,7 +3054,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { getContext().getDeclAlign(VD)); llvm::Type *VarTy = getTypes().ConvertTypeForMem(VD->getType()); auto *PTy = llvm::PointerType::get( - VarTy, getTypes().getTargetAddressSpace(VD->getType())); + getLLVMContext(), getTypes().getTargetAddressSpace(VD->getType())); Addr = Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, PTy, VarTy); } else { // Should we be using the alignment of the constant pointer we emitted? @@ -3607,29 +3614,33 @@ void CodeGenFunction::EmitCheck( llvm::Value *RecoverableCond = nullptr; llvm::Value *TrapCond = nullptr; bool NoMerge = false; + // Expand checks into: + // (Check1 || !allow_ubsan_check) && (Check2 || !allow_ubsan_check) ... + // We need separate allow_ubsan_check intrinsics because they have separately + // specified cutoffs. + // This expression looks expensive but will be simplified after + // LowerAllowCheckPass. for (auto &[Check, Ord] : Checked) { + llvm::Value *GuardedCheck = Check; + if (ClSanitizeGuardChecks || + (CGM.getCodeGenOpts().SanitizeSkipHotCutoffs[Ord] > 0)) { + llvm::Value *Allow = Builder.CreateCall( + CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check), + llvm::ConstantInt::get(CGM.Int8Ty, Ord)); + GuardedCheck = Builder.CreateOr(Check, Builder.CreateNot(Allow)); + } + // -fsanitize-trap= overrides -fsanitize-recover=. llvm::Value *&Cond = CGM.getCodeGenOpts().SanitizeTrap.has(Ord) ? TrapCond : CGM.getCodeGenOpts().SanitizeRecover.has(Ord) ? RecoverableCond : FatalCond; - Cond = Cond ? Builder.CreateAnd(Cond, Check) : Check; + Cond = Cond ? Builder.CreateAnd(Cond, GuardedCheck) : GuardedCheck; if (!CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Ord)) NoMerge = true; } - if (ClSanitizeGuardChecks) { - llvm::Value *Allow = - Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check), - llvm::ConstantInt::get(CGM.Int8Ty, CheckHandler)); - - for (llvm::Value **Cond : {&FatalCond, &RecoverableCond, &TrapCond}) { - if (*Cond) - *Cond = Builder.CreateOr(*Cond, Builder.CreateNot(Allow)); - } - } - if (TrapCond) EmitTrapCheck(TrapCond, CheckHandler, NoMerge); if (!FatalCond && !RecoverableCond) @@ -4311,14 +4322,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, // GEP indexes are signed, and scaling an index isn't permitted to // signed-overflow, so we use the same semantics for our explicit // multiply. We suppress this if overflow is not undefined behavior. - if (getLangOpts().isSignedOverflowDefined()) { + if (getLangOpts().PointerOverflowDefined) { Idx = Builder.CreateMul(Idx, numElements); } else { Idx = Builder.CreateNSWMul(Idx, numElements); } Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(), - !getLangOpts().isSignedOverflowDefined(), + !getLangOpts().PointerOverflowDefined, SignedIndices, E->getExprLoc()); } else if (const ObjCObjectType *OIT = E->getType()->getAs()){ @@ -4408,7 +4419,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, QualType arrayType = Array->getType(); Addr = emitArraySubscriptGEP( *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, - E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices, + E->getType(), !getLangOpts().PointerOverflowDefined, SignedIndices, E->getExprLoc(), &arrayType, E->getBase()); EltBaseInfo = ArrayLV.getBaseInfo(); EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType()); @@ -4417,10 +4428,9 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, Addr = EmitPointerWithAlignment(E->getBase(), &EltBaseInfo, &EltTBAAInfo); auto *Idx = EmitIdxAfterBase(/*Promote*/true); QualType ptrType = E->getBase()->getType(); - Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(), - !getLangOpts().isSignedOverflowDefined(), - SignedIndices, E->getExprLoc(), &ptrType, - E->getBase()); + Addr = emitArraySubscriptGEP( + *this, Addr, Idx, E->getType(), !getLangOpts().PointerOverflowDefined, + SignedIndices, E->getExprLoc(), &ptrType, E->getBase()); } LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo); @@ -4565,11 +4575,11 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, : llvm::ConstantInt::get(IntPtrTy, ConstLength); Idx = Builder.CreateAdd(LowerBoundVal, LengthVal, "lb_add_len", /*HasNUW=*/false, - !getLangOpts().isSignedOverflowDefined()); + !getLangOpts().PointerOverflowDefined); if (Length && LowerBound) { Idx = Builder.CreateSub( Idx, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "idx_sub_1", - /*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined()); + /*HasNUW=*/false, !getLangOpts().PointerOverflowDefined); } } else Idx = llvm::ConstantInt::get(IntPtrTy, ConstLength + ConstLowerBound); @@ -4595,7 +4605,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, Length->getType()->hasSignedIntegerRepresentation()); Idx = Builder.CreateSub( LengthVal, llvm::ConstantInt::get(IntPtrTy, /*V=*/1), "len_sub_1", - /*HasNUW=*/false, !getLangOpts().isSignedOverflowDefined()); + /*HasNUW=*/false, !getLangOpts().PointerOverflowDefined); } else { ConstLength = ConstLength.zextOrTrunc(PointerWidthInBits); --ConstLength; @@ -4622,12 +4632,12 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, // GEP indexes are signed, and scaling an index isn't permitted to // signed-overflow, so we use the same semantics for our explicit // multiply. We suppress this if overflow is not undefined behavior. - if (getLangOpts().isSignedOverflowDefined()) + if (getLangOpts().PointerOverflowDefined) Idx = Builder.CreateMul(Idx, NumElements); else Idx = Builder.CreateNSWMul(Idx, NumElements); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(), - !getLangOpts().isSignedOverflowDefined(), + !getLangOpts().PointerOverflowDefined, /*signedIndices=*/false, E->getExprLoc()); } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) { // If this is A[i] where A is an array, the frontend will have decayed the @@ -4647,7 +4657,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, // Propagate the alignment from the array itself to the result. EltPtr = emitArraySubscriptGEP( *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, - ResultExprTy, !getLangOpts().isSignedOverflowDefined(), + ResultExprTy, !getLangOpts().PointerOverflowDefined, /*signedIndices=*/false, E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy); @@ -4656,7 +4666,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, emitOMPArraySectionBase(*this, E->getBase(), BaseInfo, TBAAInfo, BaseTy, ResultExprTy, IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, - !getLangOpts().isSignedOverflowDefined(), + !getLangOpts().PointerOverflowDefined, /*signedIndices=*/false, E->getExprLoc()); } @@ -5328,6 +5338,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { case CK_MatrixCast: case CK_HLSLVectorTruncation: case CK_HLSLArrayRValue: + case CK_HLSLElementwiseCast: return EmitUnsupportedLValue(E, "unexpected cast lvalue"); case CK_Dependent: @@ -6366,3 +6377,75 @@ RValue CodeGenFunction::EmitPseudoObjectRValue(const PseudoObjectExpr *E, LValue CodeGenFunction::EmitPseudoObjectLValue(const PseudoObjectExpr *E) { return emitPseudoObjectExpr(*this, E, true, AggValueSlot::ignored()).LV; } + +void CodeGenFunction::FlattenAccessAndType( + Address Addr, QualType AddrType, + SmallVectorImpl> &AccessList, + SmallVectorImpl &FlatTypes) { + // WorkList is list of type we are processing + the Index List to access + // the field of that type in Addr for use in a GEP + llvm::SmallVector>, + 16> + WorkList; + llvm::IntegerType *IdxTy = llvm::IntegerType::get(getLLVMContext(), 32); + // Addr should be a pointer so we need to 'dereference' it + WorkList.push_back({AddrType, {llvm::ConstantInt::get(IdxTy, 0)}}); + + while (!WorkList.empty()) { + auto [T, IdxList] = WorkList.pop_back_val(); + T = T.getCanonicalType().getUnqualifiedType(); + assert(!isa(T) && "Matrix types not yet supported in HLSL"); + if (const auto *CAT = dyn_cast(T)) { + uint64_t Size = CAT->getZExtSize(); + for (int64_t I = Size - 1; I > -1; I--) { + llvm::SmallVector IdxListCopy = IdxList; + IdxListCopy.push_back(llvm::ConstantInt::get(IdxTy, I)); + WorkList.emplace_back(CAT->getElementType(), IdxListCopy); + } + } else if (const auto *RT = dyn_cast(T)) { + const RecordDecl *Record = RT->getDecl(); + assert(!Record->isUnion() && "Union types not supported in flat cast."); + + const CXXRecordDecl *CXXD = dyn_cast(Record); + + llvm::SmallVector FieldTypes; + if (CXXD && CXXD->isStandardLayout()) + Record = CXXD->getStandardLayoutBaseWithFields(); + + // deal with potential base classes + if (CXXD && !CXXD->isStandardLayout()) { + for (auto &Base : CXXD->bases()) + FieldTypes.push_back(Base.getType()); + } + + for (auto *FD : Record->fields()) + FieldTypes.push_back(FD->getType()); + + for (int64_t I = FieldTypes.size() - 1; I > -1; I--) { + llvm::SmallVector IdxListCopy = IdxList; + IdxListCopy.push_back(llvm::ConstantInt::get(IdxTy, I)); + WorkList.insert(WorkList.end(), {FieldTypes[I], IdxListCopy}); + } + } else if (const auto *VT = dyn_cast(T)) { + llvm::Type *LLVMT = ConvertTypeForMem(T); + CharUnits Align = getContext().getTypeAlignInChars(T); + Address GEP = + Builder.CreateInBoundsGEP(Addr, IdxList, LLVMT, Align, "vector.gep"); + for (unsigned I = 0, E = VT->getNumElements(); I < E; I++) { + llvm::Value *Idx = llvm::ConstantInt::get(IdxTy, I); + // gep on vector fields is not recommended so combine gep with + // extract/insert + AccessList.emplace_back(GEP, Idx); + FlatTypes.push_back(VT->getElementType()); + } + } else { + // a scalar/builtin type + llvm::Type *LLVMT = ConvertTypeForMem(T); + CharUnits Align = getContext().getTypeAlignInChars(T); + Address GEP = + Builder.CreateInBoundsGEP(Addr, IdxList, LLVMT, Align, "gep"); + AccessList.emplace_back(GEP, nullptr); + FlatTypes.push_back(T); + } + } +} diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 2ad6587089f10..c3f1cbed6b39f 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -491,6 +491,79 @@ static bool isTrivialFiller(Expr *E) { return false; } +// emit a flat cast where the RHS is a scalar, including vector +static void EmitHLSLScalarFlatCast(CodeGenFunction &CGF, Address DestVal, + QualType DestTy, llvm::Value *SrcVal, + QualType SrcTy, SourceLocation Loc) { + // Flatten our destination + SmallVector DestTypes; // Flattened type + SmallVector, 16> StoreGEPList; + // ^^ Flattened accesses to DestVal we want to store into + CGF.FlattenAccessAndType(DestVal, DestTy, StoreGEPList, DestTypes); + + assert(SrcTy->isVectorType() && "HLSL Flat cast doesn't handle splatting."); + const VectorType *VT = SrcTy->getAs(); + SrcTy = VT->getElementType(); + assert(StoreGEPList.size() <= VT->getNumElements() && + "Cannot perform HLSL flat cast when vector source \ + object has less elements than flattened destination \ + object."); + for (unsigned I = 0, Size = StoreGEPList.size(); I < Size; I++) { + llvm::Value *Load = CGF.Builder.CreateExtractElement(SrcVal, I, "vec.load"); + llvm::Value *Cast = + CGF.EmitScalarConversion(Load, SrcTy, DestTypes[I], Loc); + + // store back + llvm::Value *Idx = StoreGEPList[I].second; + if (Idx) { + llvm::Value *V = + CGF.Builder.CreateLoad(StoreGEPList[I].first, "load.for.insert"); + Cast = CGF.Builder.CreateInsertElement(V, Cast, Idx); + } + CGF.Builder.CreateStore(Cast, StoreGEPList[I].first); + } + return; +} + +// emit a flat cast where the RHS is an aggregate +static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, Address DestVal, + QualType DestTy, Address SrcVal, + QualType SrcTy, SourceLocation Loc) { + // Flatten our destination + SmallVector DestTypes; // Flattened type + SmallVector, 16> StoreGEPList; + // ^^ Flattened accesses to DestVal we want to store into + CGF.FlattenAccessAndType(DestVal, DestTy, StoreGEPList, DestTypes); + // Flatten our src + SmallVector SrcTypes; // Flattened type + SmallVector, 16> LoadGEPList; + // ^^ Flattened accesses to SrcVal we want to load from + CGF.FlattenAccessAndType(SrcVal, SrcTy, LoadGEPList, SrcTypes); + + assert(StoreGEPList.size() <= LoadGEPList.size() && + "Cannot perform HLSL flat cast when flattened source object \ + has less elements than flattened destination object."); + // apply casts to what we load from LoadGEPList + // and store result in Dest + for (unsigned I = 0, E = StoreGEPList.size(); I < E; I++) { + llvm::Value *Idx = LoadGEPList[I].second; + llvm::Value *Load = CGF.Builder.CreateLoad(LoadGEPList[I].first, "load"); + Load = + Idx ? CGF.Builder.CreateExtractElement(Load, Idx, "vec.extract") : Load; + llvm::Value *Cast = + CGF.EmitScalarConversion(Load, SrcTypes[I], DestTypes[I], Loc); + + // store back + Idx = StoreGEPList[I].second; + if (Idx) { + llvm::Value *V = + CGF.Builder.CreateLoad(StoreGEPList[I].first, "load.for.insert"); + Cast = CGF.Builder.CreateInsertElement(V, Cast, Idx); + } + CGF.Builder.CreateStore(Cast, StoreGEPList[I].first); + } +} + /// Emit initialization of an array from an initializer list. ExprToVisit must /// be either an InitListEpxr a CXXParenInitListExpr. void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, @@ -890,7 +963,25 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { case CK_HLSLArrayRValue: Visit(E->getSubExpr()); break; - + case CK_HLSLElementwiseCast: { + Expr *Src = E->getSubExpr(); + QualType SrcTy = Src->getType(); + RValue RV = CGF.EmitAnyExpr(Src); + QualType DestTy = E->getType(); + Address DestVal = Dest.getAddress(); + SourceLocation Loc = E->getExprLoc(); + + if (RV.isScalar()) { + llvm::Value *SrcVal = RV.getScalarVal(); + EmitHLSLScalarFlatCast(CGF, DestVal, DestTy, SrcVal, SrcTy, Loc); + } else { + assert(RV.isAggregate() && + "Can't perform HLSL Aggregate cast on a complex type."); + Address SrcVal = RV.getAggregateAddress(); + EmitHLSLElementwiseCast(CGF, DestVal, DestTy, SrcVal, SrcTy, Loc); + } + break; + } case CK_NoOp: case CK_UserDefinedConversion: case CK_ConstructorConversion: @@ -1461,6 +1552,7 @@ static bool castPreservesZero(const CastExpr *CE) { case CK_NonAtomicToAtomic: case CK_AtomicToNonAtomic: case CK_HLSLVectorTruncation: + case CK_HLSLElementwiseCast: return true; case CK_BaseToDerivedMemberPointer: diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index ac31dff11b585..c2679ea92dc97 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -610,6 +610,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, case CK_MatrixCast: case CK_HLSLVectorTruncation: case CK_HLSLArrayRValue: + case CK_HLSLElementwiseCast: llvm_unreachable("invalid cast kind for complex value"); case CK_FloatingRealToComplex: diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 655fc3dc954c8..ef11798869d3b 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -1335,6 +1335,7 @@ class ConstExprEmitter case CK_MatrixCast: case CK_HLSLVectorTruncation: case CK_HLSLArrayRValue: + case CK_HLSLElementwiseCast: return nullptr; } llvm_unreachable("Invalid CastKind"); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index ac499e490ee87..80daed7e53951 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2269,6 +2269,42 @@ bool CodeGenFunction::ShouldNullCheckClassCastValue(const CastExpr *CE) { return true; } +// RHS is an aggregate type +static Value *EmitHLSLElementwiseCast(CodeGenFunction &CGF, Address RHSVal, + QualType RHSTy, QualType LHSTy, + SourceLocation Loc) { + SmallVector, 16> LoadGEPList; + SmallVector SrcTypes; // Flattened type + CGF.FlattenAccessAndType(RHSVal, RHSTy, LoadGEPList, SrcTypes); + // LHS is either a vector or a builtin? + // if its a vector create a temp alloca to store into and return that + if (auto *VecTy = LHSTy->getAs()) { + assert(SrcTypes.size() >= VecTy->getNumElements() && + "Flattened type on RHS must have more elements than vector on LHS."); + llvm::Value *V = + CGF.Builder.CreateLoad(CGF.CreateIRTemp(LHSTy, "flatcast.tmp")); + // write to V. + for (unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) { + llvm::Value *Load = CGF.Builder.CreateLoad(LoadGEPList[I].first, "load"); + llvm::Value *Idx = LoadGEPList[I].second; + Load = Idx ? CGF.Builder.CreateExtractElement(Load, Idx, "vec.extract") + : Load; + llvm::Value *Cast = CGF.EmitScalarConversion( + Load, SrcTypes[I], VecTy->getElementType(), Loc); + V = CGF.Builder.CreateInsertElement(V, Cast, I); + } + return V; + } + // i its a builtin just do an extract element or load. + assert(LHSTy->isBuiltinType() && + "Destination type must be a vector or builtin type."); + llvm::Value *Load = CGF.Builder.CreateLoad(LoadGEPList[0].first, "load"); + llvm::Value *Idx = LoadGEPList[0].second; + Load = + Idx ? CGF.Builder.CreateExtractElement(Load, Idx, "vec.extract") : Load; + return CGF.EmitScalarConversion(Load, LHSTy, SrcTypes[0], Loc); +} + // VisitCastExpr - Emit code for an explicit or implicit cast. Implicit casts // have to handle a more broad range of conversions than explicit casts, as they // handle things like function to ptr-to-function decay etc. @@ -2759,7 +2795,16 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { llvm::Value *Zero = llvm::Constant::getNullValue(CGF.SizeTy); return Builder.CreateExtractElement(Vec, Zero, "cast.vtrunc"); } + case CK_HLSLElementwiseCast: { + RValue RV = CGF.EmitAnyExpr(E); + SourceLocation Loc = CE->getExprLoc(); + QualType SrcTy = E->getType(); + assert(RV.isAggregate() && "Not a valid HLSL Flat Cast."); + // RHS is an aggregate + Address SrcVal = RV.getAggregateAddress(); + return EmitHLSLElementwiseCast(CGF, SrcVal, SrcTy, DestTy, Loc); + } } // end of switch llvm_unreachable("unknown scalar cast"); @@ -3043,7 +3088,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, llvm::Value *numElts = CGF.getVLASize(vla).NumElts; if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize"); llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType()); - if (CGF.getLangOpts().isSignedOverflowDefined()) + if (CGF.getLangOpts().PointerOverflowDefined) value = Builder.CreateGEP(elemTy, value, numElts, "vla.inc"); else value = CGF.EmitCheckedInBoundsGEP( @@ -3054,7 +3099,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, } else if (type->isFunctionType()) { llvm::Value *amt = Builder.getInt32(amount); - if (CGF.getLangOpts().isSignedOverflowDefined()) + if (CGF.getLangOpts().PointerOverflowDefined) value = Builder.CreateGEP(CGF.Int8Ty, value, amt, "incdec.funcptr"); else value = @@ -3066,7 +3111,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, } else { llvm::Value *amt = Builder.getInt32(amount); llvm::Type *elemTy = CGF.ConvertTypeForMem(type); - if (CGF.getLangOpts().isSignedOverflowDefined()) + if (CGF.getLangOpts().PointerOverflowDefined) value = Builder.CreateGEP(elemTy, value, amt, "incdec.ptr"); else value = CGF.EmitCheckedInBoundsGEP( @@ -3179,7 +3224,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, llvm::Value *sizeValue = llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity()); - if (CGF.getLangOpts().isSignedOverflowDefined()) + if (CGF.getLangOpts().PointerOverflowDefined) value = Builder.CreateGEP(CGF.Int8Ty, value, sizeValue, "incdec.objptr"); else value = CGF.EmitCheckedInBoundsGEP( @@ -4075,7 +4120,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, // signed-overflow, so we use the same semantics for our explicit // multiply. We suppress this if overflow is not undefined behavior. llvm::Type *elemTy = CGF.ConvertTypeForMem(vla->getElementType()); - if (CGF.getLangOpts().isSignedOverflowDefined()) { + if (CGF.getLangOpts().PointerOverflowDefined) { index = CGF.Builder.CreateMul(index, numElements, "vla.index"); pointer = CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr"); } else { @@ -4096,7 +4141,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF, else elemTy = CGF.ConvertTypeForMem(elementType); - if (CGF.getLangOpts().isSignedOverflowDefined()) + if (CGF.getLangOpts().PointerOverflowDefined) return CGF.Builder.CreateGEP(elemTy, pointer, index, "add.ptr"); return CGF.EmitCheckedInBoundsGEP( diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 345e218f42451..6cccd353cff96 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -100,22 +100,6 @@ GlobalVariable *replaceBuffer(CGHLSLRuntime::Buffer &Buf) { llvm::formatv("{0}{1}", Buf.Name, Buf.IsCBuffer ? ".cb." : ".tb."), GlobalValue::NotThreadLocal); - IRBuilder<> B(CBGV->getContext()); - Value *ZeroIdx = B.getInt32(0); - // Replace Const use with CB use. - for (auto &[GV, Offset] : Buf.Constants) { - Value *GEP = - B.CreateGEP(Buf.LayoutStruct, CBGV, {ZeroIdx, B.getInt32(Offset)}); - - assert(Buf.LayoutStruct->getElementType(Offset) == GV->getValueType() && - "constant type mismatch"); - - // Replace. - GV->replaceAllUsesWith(GEP); - // Erase GV. - GV->removeDeadConstantUsers(); - GV->eraseFromParent(); - } return CBGV; } @@ -144,6 +128,7 @@ void CGHLSLRuntime::addConstant(VarDecl *D, Buffer &CB) { } auto *GV = cast(CGM.GetAddrOfGlobalVar(D)); + GV->setExternallyInitialized(true); // Add debug info for constVal. if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) if (CGM.getCodeGenOpts().getDebugInfo() >= @@ -360,6 +345,13 @@ void clang::CodeGen::CGHLSLRuntime::setHLSLEntryAttributes( WaveSizeAttr->getPreferred()); Fn->addFnAttr(WaveSizeKindStr, WaveSizeStr); } + // HLSL entry functions are materialized for module functions with + // HLSLShaderAttr attribute. SetLLVMFunctionAttributesForDefinition called + // later in the compiler-flow for such module functions is not aware of and + // hence not able to set attributes of the newly materialized entry functions. + // So, set attributes of entry function here, as appropriate. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + Fn->addFnAttr(llvm::Attribute::OptimizeNone); Fn->addFnAttr(llvm::Attribute::NoInline); } diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index cfc92be393940..ebd88bb38849e 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -773,7 +773,9 @@ class CGObjCGNUstep : public CGObjCGNU { // The lookup function is guaranteed not to capture the receiver pointer. if (auto *LookupFn2 = dyn_cast(LookupFn.getCallee())) - LookupFn2->addParamAttr(0, llvm::Attribute::NoCapture); + LookupFn2->addParamAttr( + 0, llvm::Attribute::getWithCaptureInfo(CGF.getLLVMContext(), + llvm::CaptureInfo::none())); llvm::Value *args[] = { EnforceType(Builder, ReceiverPtr.getPointer(), PtrToIdTy), diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index dd900f9b32fb7..6c929a6431c0f 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -5717,7 +5717,7 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) IntTy = CGM.IntTy; LongTy = cast(Types.ConvertType(Ctx.LongTy)); Int8PtrTy = CGM.Int8PtrTy; - Int8PtrProgramASTy = llvm::PointerType::get(CGM.Int8Ty, ProgramAS); + Int8PtrProgramASTy = llvm::PointerType::get(CGM.getLLVMContext(), ProgramAS); Int8PtrPtrTy = CGM.Int8PtrPtrTy; // arm64 targets use "int" ivar offset variables. All others, diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index b438a92a4fd62..a7f5c913f42fc 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -230,11 +230,14 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF, CodeGenFunction::LexicalScope Cleanups(CGF, Handler.Body->getSourceRange()); SaveAndRestore RevertAfterScope(CGF.CurrentFuncletPad); if (useFunclets) { - llvm::Instruction *CPICandidate = Handler.Block->getFirstNonPHI(); - if (auto *CPI = dyn_cast_or_null(CPICandidate)) { - CGF.CurrentFuncletPad = CPI; - CPI->setOperand(2, CGF.getExceptionSlot().emitRawPointer(CGF)); - CGF.EHStack.pushCleanup(NormalCleanup, CPI); + llvm::BasicBlock::iterator CPICandidate = + Handler.Block->getFirstNonPHIIt(); + if (CPICandidate != Handler.Block->end()) { + if (auto *CPI = dyn_cast_or_null(CPICandidate)) { + CGF.CurrentFuncletPad = CPI; + CPI->setOperand(2, CGF.getExceptionSlot().emitRawPointer(CGF)); + CGF.EHStack.pushCleanup(NormalCleanup, CPI); + } } } diff --git a/clang/lib/CodeGen/CGOpenCLRuntime.cpp b/clang/lib/CodeGen/CGOpenCLRuntime.cpp index 115b618056a44..9f8ff488755ec 100644 --- a/clang/lib/CodeGen/CGOpenCLRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenCLRuntime.cpp @@ -130,10 +130,11 @@ void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E, assert(!EnqueuedBlockMap.contains(E) && "Block expression emitted twice"); assert(isa(InvokeF) && "Invalid invoke function"); assert(Block->getType()->isPointerTy() && "Invalid block literal type"); - EnqueuedBlockMap[E].InvokeFunc = InvokeF; - EnqueuedBlockMap[E].BlockArg = Block; - EnqueuedBlockMap[E].BlockTy = BlockTy; - EnqueuedBlockMap[E].KernelHandle = nullptr; + EnqueuedBlockInfo &BlockInfo = EnqueuedBlockMap[E]; + BlockInfo.InvokeFunc = InvokeF; + BlockInfo.BlockArg = Block; + BlockInfo.BlockTy = BlockTy; + BlockInfo.KernelHandle = nullptr; } llvm::Function *CGOpenCLRuntime::getInvokeFunction(const Expr *E) { @@ -148,17 +149,19 @@ CGOpenCLRuntime::emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E) { // to get the block literal. const BlockExpr *Block = getBlockExpr(E); - assert(EnqueuedBlockMap.contains(Block) && "Block expression not emitted"); + auto It = EnqueuedBlockMap.find(Block); + assert(It != EnqueuedBlockMap.end() && "Block expression not emitted"); + EnqueuedBlockInfo &BlockInfo = It->second; // Do not emit the block wrapper again if it has been emitted. - if (EnqueuedBlockMap[Block].KernelHandle) { - return EnqueuedBlockMap[Block]; + if (BlockInfo.KernelHandle) { + return BlockInfo; } auto *F = CGF.getTargetHooks().createEnqueuedBlockKernel( - CGF, EnqueuedBlockMap[Block].InvokeFunc, EnqueuedBlockMap[Block].BlockTy); + CGF, BlockInfo.InvokeFunc, BlockInfo.BlockTy); // The common part of the post-processing of the kernel goes here. - EnqueuedBlockMap[Block].KernelHandle = F; - return EnqueuedBlockMap[Block]; + BlockInfo.KernelHandle = F; + return BlockInfo; } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index cafaaa364cb76..b679d63874b3b 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1457,14 +1457,13 @@ void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) { clearLocThreadIdInsertPt(CGF); OpenMPLocThreadIDMap.erase(CGF.CurFn); } - if (FunctionUDRMap.count(CGF.CurFn) > 0) { - for(const auto *D : FunctionUDRMap[CGF.CurFn]) + if (auto I = FunctionUDRMap.find(CGF.CurFn); I != FunctionUDRMap.end()) { + for (const auto *D : I->second) UDRMap.erase(D); - FunctionUDRMap.erase(CGF.CurFn); + FunctionUDRMap.erase(I); } - auto I = FunctionUDMMap.find(CGF.CurFn); - if (I != FunctionUDMMap.end()) { - for(const auto *D : I->second) + if (auto I = FunctionUDMMap.find(CGF.CurFn); I != FunctionUDMMap.end()) { + for (const auto *D : I->second) UDMMap.erase(D); FunctionUDMMap.erase(I); } diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 7c944fe85a352..c96301c306d41 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -489,6 +489,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { case Stmt::OpenACCUpdateConstructClass: EmitOpenACCUpdateConstruct(cast(*S)); break; + case Stmt::OpenACCAtomicConstructClass: + EmitOpenACCAtomicConstruct(cast(*S)); } } @@ -3303,18 +3305,9 @@ CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input) { llvm::ConvergenceControlInst * CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB) { - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - if (BB->empty()) - Builder.SetInsertPoint(BB); - else - Builder.SetInsertPoint(BB->getFirstInsertionPt()); - - llvm::CallBase *CB = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_loop, {}, {}); - Builder.restoreIP(IP); - - CB = addConvergenceControlToken(CB); - return cast(CB); + llvm::ConvergenceControlInst *ParentToken = ConvergenceTokenStack.back(); + assert(ParentToken); + return llvm::ConvergenceControlInst::CreateLoop(*BB, ParentToken); } llvm::ConvergenceControlInst * @@ -3327,13 +3320,5 @@ CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) { // Adding a convergence token requires the function to be marked as // convergent. F->setConvergent(); - - CGBuilderTy::InsertPoint IP = Builder.saveIP(); - Builder.SetInsertPoint(&BB->front()); - llvm::CallBase *I = Builder.CreateIntrinsic( - llvm::Intrinsic::experimental_convergence_entry, {}, {}); - assert(isa(I)); - Builder.restoreIP(IP); - - return cast(I); + return llvm::ConvergenceControlInst::CreateEntry(*BB); } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 11fdddba1144b..08165e0b28406 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -404,9 +404,9 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { // important to do this before we enter the return block or return // edges will be *really* confused. bool HasCleanups = EHStack.stable_begin() != PrologueCleanupDepth; - bool HasOnlyLifetimeMarkers = - HasCleanups && EHStack.containsOnlyLifetimeMarkers(PrologueCleanupDepth); - bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers; + bool HasOnlyNoopCleanups = + HasCleanups && EHStack.containsOnlyNoopCleanups(PrologueCleanupDepth); + bool EmitRetDbgLoc = !HasCleanups || HasOnlyNoopCleanups; std::optional OAL; if (HasCleanups) { @@ -551,14 +551,6 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { CurFn->addFnAttr("min-legal-vector-width", llvm::utostr(LargestVectorWidth)); - // Add vscale_range attribute if appropriate. - std::optional> VScaleRange = - getContext().getTargetInfo().getVScaleRange(getLangOpts()); - if (VScaleRange) { - CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs( - getLLVMContext(), VScaleRange->first, VScaleRange->second)); - } - // If we generated an unreachable return block, delete it now. if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty()) { Builder.ClearInsertionPoint(); @@ -1110,6 +1102,15 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (FD && FD->isMain()) Fn->removeFnAttr("zero-call-used-regs"); + // Add vscale_range attribute if appropriate. + std::optional> VScaleRange = + getContext().getTargetInfo().getVScaleRange( + getLangOpts(), FD ? IsArmStreamingFunction(FD, true) : false); + if (VScaleRange) { + CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs( + getLLVMContext(), VScaleRange->first, VScaleRange->second)); + } + llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); // Create a marker to make it easy to insert allocas into the entryblock diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index fab27d4c22ed8..e7a5100a9fa29 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -451,7 +451,7 @@ class CodeGenFunction : public CodeGenTypeCache { "EBB should be entry block of the current code gen function"); PostAllocaInsertPt = AllocaInsertPt->clone(); PostAllocaInsertPt->setName("postallocapt"); - PostAllocaInsertPt->insertAfter(AllocaInsertPt); + PostAllocaInsertPt->insertAfter(AllocaInsertPt->getIterator()); } return PostAllocaInsertPt; @@ -723,6 +723,20 @@ class CodeGenFunction : public CodeGenTypeCache { } }; + // We are using objects of this 'cleanup' class to emit fake.use calls + // for -fextend-variable-liveness. They are placed at the end of a variable's + // scope analogous to lifetime markers. + class FakeUse final : public EHScopeStack::Cleanup { + Address Addr; + + public: + FakeUse(Address addr) : Addr(addr) {} + + void Emit(CodeGenFunction &CGF, Flags flags) override { + CGF.EmitFakeUse(Addr); + } + }; + /// Header for data within LifetimeExtendedCleanupStack. struct LifetimeExtendedCleanupHeader { /// The size of the following cleanup object. @@ -3310,20 +3324,11 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *Index, QualType IndexType, QualType IndexedType, bool Accessed); - // Find a struct's flexible array member and get its offset. It may be - // embedded inside multiple sub-structs, but must still be the last field. - const FieldDecl * - FindFlexibleArrayMemberFieldAndOffset(ASTContext &Ctx, const RecordDecl *RD, - const FieldDecl *FAMDecl, - uint64_t &Offset); - - llvm::Value *GetCountedByFieldExprGEP(const Expr *Base, - const FieldDecl *FAMDecl, + llvm::Value *GetCountedByFieldExprGEP(const Expr *Base, const FieldDecl *FD, const FieldDecl *CountDecl); /// Build an expression accessing the "counted_by" field. - llvm::Value *EmitLoadOfCountedByField(const Expr *Base, - const FieldDecl *FAMDecl, + llvm::Value *EmitLoadOfCountedByField(const Expr *Base, const FieldDecl *FD, const FieldDecl *CountDecl); llvm::Value *EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, @@ -4162,6 +4167,13 @@ class CodeGenFunction : public CodeGenTypeCache { // but in the future we will implement some sort of IR. } + void EmitOpenACCAtomicConstruct(const OpenACCAtomicConstruct &S) { + // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', + // simply emitting its associated stmt, but in the future we will implement + // some sort of IR. + EmitStmt(S.getAssociatedStmt()); + } + //===--------------------------------------------------------------------===// // LValue Expression Emission //===--------------------------------------------------------------------===// @@ -4427,6 +4439,11 @@ class CodeGenFunction : public CodeGenTypeCache { AggValueSlot slot = AggValueSlot::ignored()); LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e); + void FlattenAccessAndType( + Address Addr, QualType AddrTy, + SmallVectorImpl> &AccessList, + SmallVectorImpl &FlatTypes); + llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); llvm::Value *EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface, @@ -4692,6 +4709,21 @@ class CodeGenFunction : public CodeGenTypeCache { SmallVectorImpl &O, const char *name, unsigned shift = 0, bool rightshift = false); + llvm::Value *EmitFP8NeonCall(unsigned IID, ArrayRef Tys, + SmallVectorImpl &O, + const CallExpr *E, const char *name); + llvm::Value *EmitFP8NeonCvtCall(unsigned IID, llvm::Type *Ty0, + llvm::Type *Ty1, bool Extract, + SmallVectorImpl &Ops, + const CallExpr *E, const char *name); + llvm::Value *EmitFP8NeonFDOTCall(unsigned IID, bool ExtendLaneArg, + llvm::Type *RetTy, + SmallVectorImpl &Ops, + const CallExpr *E, const char *name); + llvm::Value *EmitFP8NeonFMLACall(unsigned IID, bool ExtendLaneArg, + llvm::Type *RetTy, + SmallVectorImpl &Ops, + const CallExpr *E, const char *name); llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx, const llvm::ElementCount &Count); llvm::Value *EmitNeonSplat(llvm::Value *V, llvm::Constant *Idx); @@ -5060,6 +5092,8 @@ class CodeGenFunction : public CodeGenTypeCache { RValue EmitAtomicExpr(AtomicExpr *E); + void EmitFakeUse(Address Addr); + //===--------------------------------------------------------------------===// // Annotations Emission //===--------------------------------------------------------------------===// @@ -5338,8 +5372,9 @@ class CodeGenFunction : public CodeGenTypeCache { llvm::Value *EmittedE, bool IsDynamic); - llvm::Value *emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, - llvm::IntegerType *ResType); + llvm::Value *emitCountedByMemberSize(const Expr *E, llvm::Value *EmittedE, + unsigned Type, + llvm::IntegerType *ResType); void emitZeroOrPatternForAutoVarInit(QualType type, const VarDecl &D, Address Loc); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index eb8d3ceeeba4c..7924c32fcf633 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -486,8 +486,10 @@ void CodeGenModule::createOpenMPRuntime() { case llvm::Triple::nvptx: case llvm::Triple::nvptx64: case llvm::Triple::amdgcn: - assert(getLangOpts().OpenMPIsTargetDevice && - "OpenMP AMDGPU/NVPTX is only prepared to deal with device code."); + case llvm::Triple::spirv64: + assert( + getLangOpts().OpenMPIsTargetDevice && + "OpenMP AMDGPU/NVPTX/SPIRV is only prepared to deal with device code."); OpenMPRuntime.reset(new CGOpenMPRuntimeGPU(*this)); break; default: @@ -1149,6 +1151,8 @@ void CodeGenModule::Release() { if (CodeGenOpts.PatchableFunctionEntryOffset) getModule().addModuleFlag(llvm::Module::Override, "kcfi-offset", CodeGenOpts.PatchableFunctionEntryOffset); + if (CodeGenOpts.SanitizeKcfiArity) + getModule().addModuleFlag(llvm::Module::Override, "kcfi-arity", 1); } if (CodeGenOpts.CFProtectionReturn && @@ -1293,6 +1297,11 @@ void CodeGenModule::Release() { if (LangOpts.EHAsynch) getModule().addModuleFlag(llvm::Module::Warning, "eh-asynch", 1); + // Emit Import Call section. + if (CodeGenOpts.ImportCallOptimization) + getModule().addModuleFlag(llvm::Module::Warning, "import-call-optimization", + 1); + // Indicate whether this Module was compiled with -fopenmp if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd) getModule().addModuleFlag(llvm::Module::Max, "openmp", LangOpts.OpenMP); @@ -3760,7 +3769,7 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject( auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), /*isConstant=*/true, Linkage, Init, Name); setGVProperties(GV, TPO); - if (supportsCOMDAT()) + if (supportsCOMDAT() && Linkage == llvm::GlobalValue::LinkOnceODRLinkage) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV); @@ -4010,7 +4019,8 @@ namespace { unsigned BuiltinID = FD->getBuiltinID(); if (!BuiltinID || !BI.isLibFunction(BuiltinID)) return false; - StringRef BuiltinName = BI.getName(BuiltinID); + std::string BuiltinNameStr = BI.getName(BuiltinID); + StringRef BuiltinName = BuiltinNameStr; if (BuiltinName.starts_with("__builtin_") && Name == BuiltinName.slice(strlen("__builtin_"), StringRef::npos)) { return true; @@ -4424,7 +4434,7 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { GlobalDecl ResolverGD; if (getTarget().supportsIFunc()) { ResolverType = llvm::FunctionType::get( - llvm::PointerType::get(DeclTy, + llvm::PointerType::get(getLLVMContext(), getTypes().getTargetAddressSpace(FD->getType())), false); } @@ -4596,8 +4606,8 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // cpu_dispatch will be emitted in this translation unit. if (ShouldReturnIFunc) { unsigned AS = getTypes().getTargetAddressSpace(FD->getType()); - llvm::Type *ResolverType = - llvm::FunctionType::get(llvm::PointerType::get(DeclTy, AS), false); + llvm::Type *ResolverType = llvm::FunctionType::get( + llvm::PointerType::get(getLLVMContext(), AS), false); llvm::Constant *Resolver = GetOrCreateLLVMFunction( MangledName + ".resolver", ResolverType, GlobalDecl{}, /*ForVTable=*/false); @@ -7014,9 +7024,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::VarTemplateSpecialization: EmitGlobal(cast(D)); if (auto *DD = dyn_cast(D)) - for (auto *B : DD->bindings()) + for (auto *B : DD->flat_bindings()) if (auto *HD = B->getHoldingVar()) EmitGlobal(HD); + break; // Indirect fields from global anonymous structs and unions can be diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 1aa5d483d49c0..0956296e2d5d8 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -647,6 +647,9 @@ class CodeGenModule : public CodeGenTypeCache { /// void @llvm.lifetime.end(i64 %size, i8* nocapture ) llvm::Function *LifetimeEndFn = nullptr; + /// void @llvm.fake.use(...) + llvm::Function *FakeUseFn = nullptr; + std::unique_ptr SanitizerMD; llvm::MapVector DeferredEmptyCoverageMappingDecls; @@ -1326,6 +1329,7 @@ class CodeGenModule : public CodeGenTypeCache { llvm::Function *getLLVMLifetimeStartFn(); llvm::Function *getLLVMLifetimeEndFn(); + llvm::Function *getLLVMFakeUseFn(); // Make sure that this type is translated. void UpdateCompletedType(const TagDecl *TD); diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 75e66bae79afd..3f1a24791ddd8 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -226,6 +226,14 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { PtrDepth++; Ty = Ty->getPointeeType()->getBaseElementTypeUnsafe(); } while (Ty->isPointerType()); + + // While there are no special rules in the standards regarding void pointers + // and strict aliasing, emitting distinct tags for void pointers break some + // common idioms and there is no good alternative to re-write the code + // without strict-aliasing violations. + if (Ty->isVoidType()) + return AnyPtr; + assert(!isa(Ty)); // When the underlying type is a builtin type, we compute the pointee type // string recursively, which is implicitly more forgiving than the standards diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 09191a4901f49..405242e97e75c 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -505,15 +505,18 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case BuiltinType::Id: #define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \ case BuiltinType::Id: -#define AARCH64_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \ - case BuiltinType::Id: -#define SVE_OPAQUE_TYPE(Name, MangledName, Id, SingletonId) +#define SVE_TYPE(Name, Id, SingletonId) #include "clang/Basic/AArch64SVEACLETypes.def" { ASTContext::BuiltinVectorTypeInfo Info = Context.getBuiltinVectorTypeInfo(cast(Ty)); - auto VTy = - llvm::VectorType::get(ConvertType(Info.ElementType), Info.EC); + // The `__mfp8` type maps to `<1 x i8>` which can't be used to build + // a vector type, hence bypass the call to `ConvertType` for + // the element type and create the vector type directly. + auto *EltTy = Info.ElementType->isMFloat8Type() + ? llvm::Type::getInt8Ty(getLLVMContext()) + : ConvertType(Info.ElementType); + auto *VTy = llvm::VectorType::get(EltTy, Info.EC); switch (Info.NumVectors) { default: llvm_unreachable("Expected 1, 2, 3 or 4 vectors!"); @@ -529,6 +532,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { } case BuiltinType::SveCount: return llvm::TargetExtType::get(getLLVMContext(), "aarch64.svcount"); + case BuiltinType::MFloat8: + return llvm::VectorType::get(llvm::Type::getInt8Ty(getLLVMContext()), 1, + false); #define PPC_VECTOR_TYPE(Name, Id, Size) \ case BuiltinType::Id: \ ResultType = \ @@ -650,6 +656,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { // An ext_vector_type of Bool is really a vector of bits. llvm::Type *IRElemTy = VT->isExtVectorBoolType() ? llvm::Type::getInt1Ty(getLLVMContext()) + : VT->getElementType()->isMFloat8Type() + ? llvm::Type::getInt8Ty(getLLVMContext()) : ConvertType(VT->getElementType()); ResultType = llvm::FixedVectorType::get(IRElemTy, VT->getNumElements()); break; diff --git a/clang/lib/CodeGen/EHScopeStack.h b/clang/lib/CodeGen/EHScopeStack.h index 0c667e80bb6d8..ed11dc2bb05d7 100644 --- a/clang/lib/CodeGen/EHScopeStack.h +++ b/clang/lib/CodeGen/EHScopeStack.h @@ -87,6 +87,11 @@ enum CleanupKind : unsigned { LifetimeMarker = 0x8, NormalEHLifetimeMarker = LifetimeMarker | NormalAndEHCleanup, + + // FakeUse needs to be recognized as a special cleanup similar to lifetime + // markers chiefly to be ignored in most contexts. + FakeUse = 0x10, + NormalFakeUse = FakeUse | NormalCleanup, }; /// A stack of scopes which respond to exceptions, including cleanups @@ -352,8 +357,8 @@ class EHScopeStack { void popTerminate(); // Returns true iff the current scope is either empty or contains only - // lifetime markers, i.e. no real cleanup code - bool containsOnlyLifetimeMarkers(stable_iterator Old) const; + // noop cleanups, i.e. lifetime markers and fake uses. + bool containsOnlyNoopCleanups(stable_iterator Old) const; /// Determines whether the exception-scopes stack is empty. bool empty() const { return StartOfData == EndOfBuffer; } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 7c463f51f63dc..7375a511809b9 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2239,8 +2239,8 @@ CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) { - auto *CE = E.dyn_cast(); - auto *D = E.dyn_cast(); + auto *CE = dyn_cast(E); + auto *D = dyn_cast(E); assert((CE != nullptr) ^ (D != nullptr)); assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 0d53e8cb45fe7..4a2630e83b62d 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1996,8 +1996,8 @@ CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) { - auto *CE = E.dyn_cast(); - auto *D = E.dyn_cast(); + auto *CE = dyn_cast(E); + auto *D = dyn_cast(E); assert((CE != nullptr) ^ (D != nullptr)); assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 7db67ecba07c8..dc3a1d4287be1 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -147,8 +147,8 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { CGM.getTarget().parseTargetAttr(TA->getFeaturesStr()); if (!Attr.BranchProtection.empty()) { StringRef Error; - (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection, - Attr.CPU, BPI, Error); + (void)CGM.getTarget().validateBranchProtection( + Attr.BranchProtection, Attr.CPU, BPI, CGM.getLangOpts(), Error); assert(Error.empty()); } } @@ -244,6 +244,7 @@ AArch64ABIInfo::convertFixedToScalableVectorType(const VectorType *VT) const { case BuiltinType::SChar: case BuiltinType::UChar: + case BuiltinType::MFloat8: return llvm::ScalableVectorType::get( llvm::Type::getInt8Ty(getVMContext()), 16); @@ -383,10 +384,6 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn, NSRN = std::min(NSRN + 1, 8u); else { switch (BT->getKind()) { - case BuiltinType::MFloat8x8: - case BuiltinType::MFloat8x16: - NSRN = std::min(NSRN + 1, 8u); - break; case BuiltinType::SveBool: case BuiltinType::SveCount: NPRN = std::min(NPRN + 1, 4u); @@ -418,18 +415,21 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn, CGCXXABI::RAA_DirectInMemory); } - // Empty records are always ignored on Darwin, but actually passed in C++ mode - // elsewhere for GNU compatibility. + // Empty records: uint64_t Size = getContext().getTypeSize(Ty); bool IsEmpty = isEmptyRecord(getContext(), Ty, true); if (!Ty->isSVESizelessBuiltinType() && (IsEmpty || Size == 0)) { + // Empty records are ignored in C mode, and in C++ on Darwin. if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS()) return ABIArgInfo::getIgnore(); - // GNU C mode. The only argument that gets ignored is an empty one with size - // 0. - if (IsEmpty && Size == 0) + // In C++ mode, arguments which have sizeof() == 0 (which are non-standard + // C++) are ignored. This isn't defined by any standard, so we copy GCC's + // behaviour here. + if (Size == 0) return ABIArgInfo::getIgnore(); + + // Otherwise, they are passed as if they have a size of 1 byte. return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext())); } @@ -629,8 +629,7 @@ bool AArch64ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { // but with the difference that any floating-point type is allowed, // including __fp16. if (const BuiltinType *BT = Ty->getAs()) { - if (BT->isFloatingPoint() || BT->getKind() == BuiltinType::MFloat8x16 || - BT->getKind() == BuiltinType::MFloat8x8) + if (BT->isFloatingPoint()) return true; } else if (const VectorType *VT = Ty->getAs()) { if (auto Kind = VT->getVectorKind(); @@ -781,8 +780,10 @@ bool AArch64ABIInfo::passAsPureScalableType( NPred += Info.NumVectors; else NVec += Info.NumVectors; - auto VTy = llvm::ScalableVectorType::get(CGT.ConvertType(Info.ElementType), - Info.EC.getKnownMinValue()); + llvm::Type *EltTy = Info.ElementType->isMFloat8Type() + ? llvm::Type::getInt8Ty(getVMContext()) + : CGT.ConvertType(Info.ElementType); + auto *VTy = llvm::ScalableVectorType::get(EltTy, Info.EC.getKnownMinValue()); if (CoerceToSeq.size() + Info.NumVectors > 12) return false; @@ -842,7 +843,7 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty, llvm::Type *BaseTy = CGF.ConvertType(Ty); if (IsIndirect) - BaseTy = llvm::PointerType::getUnqual(BaseTy); + BaseTy = llvm::PointerType::getUnqual(BaseTy->getContext()); else if (AI.getCoerceToType()) BaseTy = AI.getCoerceToType(); @@ -960,7 +961,7 @@ RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty, if (IsIndirect) { // If it's been passed indirectly (actually a struct), whatever we find from // stored registers or on the stack will actually be a struct **. - MemTy = llvm::PointerType::getUnqual(MemTy); + MemTy = llvm::PointerType::getUnqual(MemTy->getContext()); } const Type *Base = nullptr; diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp index 2d858fa2f3c3a..77641ce10e3d3 100644 --- a/clang/lib/CodeGen/Targets/ARM.cpp +++ b/clang/lib/CodeGen/Targets/ARM.cpp @@ -71,6 +71,7 @@ class ARMABIInfo : public ABIInfo { unsigned functionCallConv) const; ABIArgInfo classifyHomogeneousAggregate(QualType Ty, const Type *Base, uint64_t Members) const; + bool shouldIgnoreEmptyArg(QualType Ty) const; ABIArgInfo coerceIllegalVector(QualType Ty) const; bool isIllegalVectorType(QualType Ty) const; bool containsAnyFP16Vectors(QualType Ty) const; @@ -148,8 +149,8 @@ class ARMTargetCodeGenInfo : public TargetCodeGenInfo { StringRef DiagMsg; StringRef Arch = Attr.CPU.empty() ? CGM.getTarget().getTargetOpts().CPU : Attr.CPU; - if (!CGM.getTarget().validateBranchProtection(Attr.BranchProtection, - Arch, BPI, DiagMsg)) { + if (!CGM.getTarget().validateBranchProtection( + Attr.BranchProtection, Arch, BPI, CGM.getLangOpts(), DiagMsg)) { CGM.getDiags().Report( D->getLocation(), diag::warn_target_unsupported_branch_protection_attribute) @@ -328,6 +329,31 @@ ABIArgInfo ARMABIInfo::classifyHomogeneousAggregate(QualType Ty, return ABIArgInfo::getDirect(nullptr, 0, nullptr, false, Align); } +bool ARMABIInfo::shouldIgnoreEmptyArg(QualType Ty) const { + uint64_t Size = getContext().getTypeSize(Ty); + assert((isEmptyRecord(getContext(), Ty, true) || Size == 0) && + "Arg is not empty"); + + // Empty records are ignored in C mode, and in C++ on WatchOS. + if (!getContext().getLangOpts().CPlusPlus || + getABIKind() == ARMABIKind::AAPCS16_VFP) + return true; + + // In C++ mode, arguments which have sizeof() == 0 are ignored. This is not a + // situation which is defined by any C++ standard or ABI, but this matches + // GCC's de facto ABI. + if (Size == 0) + return true; + + // Clang 19.0 and earlier always ignored empty struct arguments in C++ mode. + if (getContext().getLangOpts().getClangABICompat() <= + LangOptions::ClangABI::Ver19) + return true; + + // Otherwise, they are passed as if they have a size of 1 byte. + return false; +} + ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic, unsigned functionCallConv) const { // 6.1.2.1 The following argument types are VFP CPRCs: @@ -366,9 +392,15 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic, return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); } - // Ignore empty records. - if (isEmptyRecord(getContext(), Ty, true)) - return ABIArgInfo::getIgnore(); + // Empty records are either ignored completely or passed as if they were a + // 1-byte object, depending on the ABI and language standard. + if (isEmptyRecord(getContext(), Ty, true) || + getContext().getTypeSize(Ty) == 0) { + if (shouldIgnoreEmptyArg(Ty)) + return ABIArgInfo::getIgnore(); + else + return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext())); + } if (IsAAPCS_VFP) { // Homogeneous Aggregates need to be expanded when we can fit the aggregate @@ -588,7 +620,8 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic, // Otherwise this is an AAPCS variant. - if (isEmptyRecord(getContext(), RetTy, true)) + if (isEmptyRecord(getContext(), RetTy, true) || + getContext().getTypeSize(RetTy) == 0) return ABIArgInfo::getIgnore(); // Check for homogeneous aggregates with AAPCS-VFP. @@ -752,7 +785,9 @@ RValue ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, CharUnits SlotSize = CharUnits::fromQuantity(4); // Empty records are ignored for parameter passing purposes. - if (isEmptyRecord(getContext(), Ty, true)) + uint64_t Size = getContext().getTypeSize(Ty); + bool IsEmpty = isEmptyRecord(getContext(), Ty, true); + if ((IsEmpty || Size == 0) && shouldIgnoreEmptyArg(Ty)) return Slot.asRValue(); CharUnits TySize = getContext().getTypeSizeInChars(Ty); diff --git a/clang/lib/CodeGen/Targets/Hexagon.cpp b/clang/lib/CodeGen/Targets/Hexagon.cpp index 8fd2a81494d99..aada8d0d61303 100644 --- a/clang/lib/CodeGen/Targets/Hexagon.cpp +++ b/clang/lib/CodeGen/Targets/Hexagon.cpp @@ -336,10 +336,6 @@ Address HexagonABIInfo::EmitVAArgForHexagonLinux(CodeGenFunction &CGF, // Implement the block where argument is in register saved area CGF.EmitBlock(InRegBlock); - llvm::Type *PTy = CGF.ConvertType(Ty); - llvm::Value *__saved_reg_area_p = CGF.Builder.CreateBitCast( - __current_saved_reg_area_pointer, llvm::PointerType::getUnqual(PTy)); - CGF.Builder.CreateStore(__new_saved_reg_area_pointer, __current_saved_reg_area_pointer_p); @@ -388,22 +384,16 @@ Address HexagonABIInfo::EmitVAArgForHexagonLinux(CodeGenFunction &CGF, CGF.Builder.CreateStore(__new_overflow_area_pointer, __current_saved_reg_area_pointer_p); - // Bitcast the overflow area pointer to the type of argument. - llvm::Type *OverflowPTy = CGF.ConvertTypeForMem(Ty); - llvm::Value *__overflow_area_p = CGF.Builder.CreateBitCast( - __overflow_area_pointer, llvm::PointerType::getUnqual(OverflowPTy)); - CGF.EmitBranch(ContBlock); - // Get the correct pointer to load the variable argument // Implement the ContBlock CGF.EmitBlock(ContBlock); llvm::Type *MemTy = CGF.ConvertTypeForMem(Ty); - llvm::Type *MemPTy = llvm::PointerType::getUnqual(MemTy); - llvm::PHINode *ArgAddr = CGF.Builder.CreatePHI(MemPTy, 2, "vaarg.addr"); - ArgAddr->addIncoming(__saved_reg_area_p, InRegBlock); - ArgAddr->addIncoming(__overflow_area_p, OnStackBlock); + llvm::PHINode *ArgAddr = CGF.Builder.CreatePHI( + llvm::PointerType::getUnqual(MemTy->getContext()), 2, "vaarg.addr"); + ArgAddr->addIncoming(__current_saved_reg_area_pointer, InRegBlock); + ArgAddr->addIncoming(__overflow_area_pointer, OnStackBlock); return Address(ArgAddr, MemTy, CharUnits::fromQuantity(ArgAlign)); } diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 2b70f2bd3f38b..2c48ba37fd206 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -367,8 +367,8 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty) const { const auto *VT = Ty->castAs(); assert(VT->getElementType()->isBuiltinType() && "expected builtin type!"); - auto VScale = - getContext().getTargetInfo().getVScaleRange(getContext().getLangOpts()); + auto VScale = getContext().getTargetInfo().getVScaleRange( + getContext().getLangOpts(), false); unsigned NumElts = VT->getNumElements(); llvm::Type *EltType = llvm::Type::getInt1Ty(getVMContext()); diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp index 23c96fa5cf98c..9bb8ddbc548d2 100644 --- a/clang/lib/CodeGen/Targets/SystemZ.cpp +++ b/clang/lib/CodeGen/Targets/SystemZ.cpp @@ -272,7 +272,7 @@ RValue SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM(), /*IsParam*/true); if (IsIndirect) { - DirectTy = llvm::PointerType::getUnqual(DirectTy); + DirectTy = llvm::PointerType::getUnqual(DirectTy->getContext()); UnpaddedSize = DirectAlign = CharUnits::fromQuantity(8); } else { if (AI.getCoerceToType()) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 5ee5179dd0f3e..7e470abe078f5 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -1334,6 +1334,15 @@ class X86_64ABIInfo : public ABIInfo { return T.isOSLinux() || T.isOSNetBSD(); } + bool returnCXXRecordGreaterThan128InMem() const { + // Clang <= 20.0 did not do this. + if (getContext().getLangOpts().getClangABICompat() <= + LangOptions::ClangABI::Ver20) + return false; + + return true; + } + X86AVXABILevel AVXLevel; // Some ABIs (e.g. X32 ABI and Native Client OS) use 32 bit pointers on // 64-bit hardware. @@ -2067,6 +2076,13 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, classify(I.getType(), Offset, FieldLo, FieldHi, isNamedArg); Lo = merge(Lo, FieldLo); Hi = merge(Hi, FieldHi); + if (returnCXXRecordGreaterThan128InMem() && + (Size > 128 && (Size != getContext().getTypeSize(I.getType()) || + Size > getNativeVectorSizeForAVXABI(AVXLevel)))) { + // The only case a 256(or 512)-bit wide vector could be used to return + // is when CXX record contains a single 256(or 512)-bit element. + Lo = Memory; + } if (Lo == Memory || Hi == Memory) { postMerge(Size, Lo, Hi); return; diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp index ced4981fd124f..b7824bde5f55a 100644 --- a/clang/lib/CodeGen/Targets/XCore.cpp +++ b/clang/lib/CodeGen/Targets/XCore.cpp @@ -149,7 +149,7 @@ RValue XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, llvm::Type *ArgTy = CGT.ConvertType(Ty); if (AI.canHaveCoerceToType() && !AI.getCoerceToType()) AI.setCoerceToType(ArgTy); - llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy); + llvm::Type *ArgPtrTy = llvm::PointerType::getUnqual(ArgTy->getContext()); Address Val = Address::invalid(); CharUnits ArgSize = CharUnits::Zero(); diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp index 9faf2a8a17341..ad2ebb6cd6e6c 100644 --- a/clang/lib/CrossTU/CrossTranslationUnit.cpp +++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp @@ -453,7 +453,8 @@ CrossTranslationUnitContext::ASTUnitStorage::getASTUnitForFunction( return std::move(IndexLoadError); // Check if there is an entry in the index for the function. - if (!NameFileMap.count(FunctionName)) { + auto It = NameFileMap.find(FunctionName); + if (It == NameFileMap.end()) { ++NumNotInOtherTU; return llvm::make_error(index_error_code::missing_definition); } @@ -461,7 +462,7 @@ CrossTranslationUnitContext::ASTUnitStorage::getASTUnitForFunction( // Search in the index for the filename where the definition of FunctionName // resides. if (llvm::Expected FoundForFile = - getASTUnitForFile(NameFileMap[FunctionName], DisplayCTUProgress)) { + getASTUnitForFile(It->second, DisplayCTUProgress)) { // Update the cache. NameASTUnitMap[FunctionName] = *FoundForFile; diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index 23dbcebc9a1ca..0899b8ef00152 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -27,8 +27,8 @@ const char *Action::getClassName(ActionClass AC) { case PrecompileJobClass: return "precompiler"; case ExtractAPIJobClass: return "api-extractor"; - case AnalyzeJobClass: return "analyzer"; - case MigrateJobClass: return "migrator"; + case AnalyzeJobClass: + return "analyzer"; case CompileJobClass: return "compiler"; case BackendJobClass: return "backend"; case AssembleJobClass: return "assembler"; @@ -373,11 +373,6 @@ void AnalyzeJobAction::anchor() {} AnalyzeJobAction::AnalyzeJobAction(Action *Input, types::ID OutputType) : JobAction(AnalyzeJobClass, Input, OutputType) {} -void MigrateJobAction::anchor() {} - -MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType) - : JobAction(MigrateJobClass, Input, OutputType) {} - void CompileJobAction::anchor() {} CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 87855fdb79971..50941d2aaa429 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -413,12 +413,12 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || - (PhaseArg = DAL.getLastArg(options::OPT_print_enabled_extensions)) || + (PhaseArg = + DAL.getLastArg(options::OPT_print_enabled_extensions)) || (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || - (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || (PhaseArg = DAL.getLastArg(options::OPT__analyze)) || (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) || (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { @@ -637,6 +637,10 @@ static llvm::Triple computeTargetTriple(const Driver &D, } } + // Currently the only architecture supported by *-uefi triples are x86_64. + if (Target.isUEFI() && Target.getArch() != llvm::Triple::x86_64) + D.Diag(diag::err_target_unknown_triple) << Target.str(); + // The `-maix[32|64]` flags are only valid for AIX targets. if (Arg *A = Args.getLastArgNoClaim(options::OPT_maix32, options::OPT_maix64); A && !Target.isOSAIX()) @@ -882,27 +886,21 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, return; } if (IsCuda && !UseLLVMOffload) { - const ToolChain *HostTC = C.getSingleOffloadToolChain(); - const llvm::Triple &HostTriple = HostTC->getTriple(); - auto OFK = Action::OFK_Cuda; - auto CudaTriple = - getNVIDIAOffloadTargetTriple(*this, C.getInputArgs(), HostTriple); + auto CudaTriple = getNVIDIAOffloadTargetTriple( + *this, C.getInputArgs(), C.getDefaultToolChain().getTriple()); if (!CudaTriple) return; - // Use the CUDA and host triples as the key into the ToolChains map, - // because the device toolchain we create depends on both. - auto &CudaTC = ToolChains[CudaTriple->str() + "/" + HostTriple.str()]; - if (!CudaTC) { - CudaTC = std::make_unique( - *this, *CudaTriple, *HostTC, C.getInputArgs()); - - // Emit a warning if the detected CUDA version is too new. - CudaInstallationDetector &CudaInstallation = - static_cast(*CudaTC).CudaInstallation; - if (CudaInstallation.isValid()) - CudaInstallation.WarnIfUnsupportedVersion(); - } - C.addOffloadDeviceToolChain(CudaTC.get(), OFK); + + auto &TC = + getOffloadToolChain(C.getInputArgs(), Action::OFK_Cuda, *CudaTriple, + C.getDefaultToolChain().getTriple()); + + // Emit a warning if the detected CUDA version is too new. + const CudaInstallationDetector &CudaInstallation = + static_cast(TC).CudaInstallation; + if (CudaInstallation.isValid()) + CudaInstallation.WarnIfUnsupportedVersion(); + C.addOffloadDeviceToolChain(&TC, Action::OFK_Cuda); } else if (IsHIP && !UseLLVMOffload) { if (auto *OMPTargetArg = C.getInputArgs().getLastArg(options::OPT_fopenmp_targets_EQ)) { @@ -910,14 +908,15 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, << OMPTargetArg->getSpelling() << "HIP"; return; } - const ToolChain *HostTC = C.getSingleOffloadToolChain(); - auto OFK = Action::OFK_HIP; + auto HIPTriple = getHIPOffloadTargetTriple(*this, C.getInputArgs()); if (!HIPTriple) return; - auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple, - *HostTC, OFK); - C.addOffloadDeviceToolChain(HIPTC, OFK); + + auto &TC = + getOffloadToolChain(C.getInputArgs(), Action::OFK_HIP, *HIPTriple, + C.getDefaultToolChain().getTriple()); + C.addOffloadDeviceToolChain(&TC, Action::OFK_HIP); } if (IsCuda || IsHIP) @@ -1034,40 +1033,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, FoundNormalizedTriples[NormalizedName] = Val; // If the specified target is invalid, emit a diagnostic. - if (TT.getArch() == llvm::Triple::UnknownArch) + if (TT.getArch() == llvm::Triple::UnknownArch) { Diag(clang::diag::err_drv_invalid_omp_target) << Val; - else { - const ToolChain *TC; - // Device toolchains have to be selected differently. They pair host - // and device in their implementation. - if (TT.isNVPTX() || TT.isAMDGCN() || TT.isSPIRV()) { - const ToolChain *HostTC = - C.getSingleOffloadToolChain(); - assert(HostTC && "Host toolchain should be always defined."); - auto &DeviceTC = - ToolChains[TT.str() + "/" + HostTC->getTriple().normalize()]; - if (!DeviceTC) { - if (TT.isNVPTX()) - DeviceTC = std::make_unique( - *this, TT, *HostTC, C.getInputArgs()); - else if (TT.isAMDGCN()) - DeviceTC = std::make_unique( - *this, TT, *HostTC, C.getInputArgs()); - else if (TT.isSPIRV()) - DeviceTC = std::make_unique( - *this, TT, *HostTC, C.getInputArgs()); - else - assert(DeviceTC && "Device toolchain not defined."); - } - - TC = DeviceTC.get(); - } else - TC = &getToolChain(C.getInputArgs(), TT); - C.addOffloadDeviceToolChain(TC, Action::OFK_OpenMP); - auto It = DerivedArchs.find(TT.getTriple()); - if (It != DerivedArchs.end()) - KnownArchs[TC] = It->second; + continue; } + + auto &TC = getOffloadToolChain(C.getInputArgs(), Action::OFK_OpenMP, TT, + C.getDefaultToolChain().getTriple()); + C.addOffloadDeviceToolChain(&TC, Action::OFK_OpenMP); + auto It = DerivedArchs.find(TT.getTriple()); + if (It != DerivedArchs.end()) + KnownArchs[&TC] = It->second; } } else if (C.getInputArgs().hasArg(options::OPT_fopenmp_targets_EQ)) { Diag(clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets); @@ -1099,9 +1075,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C, // getOffloadingDeviceToolChain, because the device toolchains we're // going to create will depend on both. const ToolChain *HostTC = C.getSingleOffloadToolChain(); - for (const auto &TargetTriple : UniqueSYCLTriplesVec) { - auto SYCLTC = &getOffloadingDeviceToolChain( - C.getInputArgs(), TargetTriple, *HostTC, Action::OFK_SYCL); + for (const auto &TT : UniqueSYCLTriplesVec) { + auto SYCLTC = &getOffloadToolChain(C.getInputArgs(), Action::OFK_SYCL, TT, + HostTC->getTriple()); C.addOffloadDeviceToolChain(SYCLTC, Action::OFK_SYCL); } } @@ -3405,7 +3381,9 @@ class OffloadingActionBuilder final { // Collect all offload arch parameters, removing duplicates. std::set GpuArchs; bool Error = false; - for (Arg *A : Args) { + const ToolChain &TC = *ToolChains.front(); + for (Arg *A : C.getArgsForToolChain(&TC, /*BoundArch=*/"", + AssociatedOffloadKind)) { if (!(A->getOption().matches(options::OPT_offload_arch_EQ) || A->getOption().matches(options::OPT_no_offload_arch_EQ))) continue; @@ -3416,7 +3394,6 @@ class OffloadingActionBuilder final { ArchStr == "all") { GpuArchs.clear(); } else if (ArchStr == "native") { - const ToolChain &TC = *ToolChains.front(); auto GPUsOrErr = ToolChains.front()->getSystemGPUArchs(Args); if (!GPUsOrErr) { TC.getDriver().Diag(diag::err_drv_undetermined_gpu_arch) @@ -4708,23 +4685,7 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, return KnownArchs.lookup(TC); llvm::DenseSet Archs; - for (auto *Arg : Args) { - // Extract any '--[no-]offload-arch' arguments intended for this toolchain. - std::unique_ptr ExtractedArg = nullptr; - if (Arg->getOption().matches(options::OPT_Xopenmp_target_EQ) && - ToolChain::getOpenMPTriple(Arg->getValue(0)) == TC->getTriple()) { - Arg->claim(); - unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1)); - unsigned Prev = Index; - ExtractedArg = getOpts().ParseOneArg(Args, Index); - if (!ExtractedArg || Index > Prev + 1) { - TC->getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args) - << Arg->getAsString(Args); - continue; - } - Arg = ExtractedArg.get(); - } - + for (auto *Arg : C.getArgsForToolChain(TC, /*BoundArch=*/"", Kind)) { // Add or remove the seen architectures in order of appearance. If an // invalid architecture is given we simply exit. if (Arg->getOption().matches(options::OPT_offload_arch_EQ)) { @@ -4781,14 +4742,31 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, return Archs; if (Archs.empty()) { - if (Kind == Action::OFK_Cuda) + if (Kind == Action::OFK_Cuda) { Archs.insert(OffloadArchToString(OffloadArch::CudaDefault)); - else if (Kind == Action::OFK_HIP) + } else if (Kind == Action::OFK_HIP) { Archs.insert(OffloadArchToString(OffloadArch::HIPDefault)); - else if (Kind == Action::OFK_OpenMP) - Archs.insert(StringRef()); - else if (Kind == Action::OFK_SYCL) + } else if (Kind == Action::OFK_SYCL) { Archs.insert(StringRef()); + } else if (Kind == Action::OFK_OpenMP) { + // Accept legacy `-march` device arguments for OpenMP. + if (auto *Arg = C.getArgsForToolChain(TC, /*BoundArch=*/"", Kind) + .getLastArg(options::OPT_march_EQ)) { + Archs.insert(Arg->getValue()); + } else { + auto ArchsOrErr = TC->getSystemGPUArchs(Args); + if (!ArchsOrErr) { + TC->getDriver().Diag(diag::err_drv_undetermined_gpu_arch) + << llvm::Triple::getArchTypeName(TC->getArch()) + << llvm::toString(ArchsOrErr.takeError()) << "--offload-arch"; + } else if (!ArchsOrErr->empty()) { + for (auto Arch : *ArchsOrErr) + Archs.insert(Args.MakeArgStringRef(Arch)); + } else { + Archs.insert(StringRef()); + } + } + } } else { Args.ClaimAllArgs(options::OPT_offload_arch_EQ); Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ); @@ -5078,8 +5056,6 @@ Action *Driver::ConstructPhaseAction( types::TY_RewrittenLegacyObjC); if (Args.hasArg(options::OPT__analyze)) return C.MakeAction(Input, types::TY_Plist); - if (Args.hasArg(options::OPT__migrate)) - return C.MakeAction(Input, types::TY_Remap); if (Args.hasArg(options::OPT_emit_ast)) return C.MakeAction(Input, types::TY_AST); if (Args.hasArg(options::OPT_emit_cir)) @@ -6601,6 +6577,73 @@ std::string Driver::GetClPchPath(Compilation &C, StringRef BaseName) const { return std::string(Output); } +const ToolChain &Driver::getOffloadToolChain( + const llvm::opt::ArgList &Args, const Action::OffloadKind Kind, + const llvm::Triple &Target, const llvm::Triple &AuxTarget) const { + std::unique_ptr &TC = + ToolChains[Target.str() + "/" + AuxTarget.str()]; + std::unique_ptr &HostTC = ToolChains[AuxTarget.str()]; + + assert(HostTC && "Host toolchain for offloading doesn't exit?"); + if (!TC) { + // Detect the toolchain based off of the target operating system. + switch (Target.getOS()) { + case llvm::Triple::CUDA: + TC = std::make_unique(*this, Target, *HostTC, + Args); + break; + case llvm::Triple::AMDHSA: + if (Kind == Action::OFK_HIP) + TC = std::make_unique(*this, Target, + *HostTC, Args); + else if (Kind == Action::OFK_OpenMP) + TC = std::make_unique(*this, Target, + *HostTC, Args); + break; + default: + break; + } + } + if (!TC) { + // Detect the toolchain based off of the target architecture if that failed. + switch (Target.getArch()) { + case llvm::Triple::spir: + case llvm::Triple::spir64: + case llvm::Triple::spirv: + case llvm::Triple::spirv32: + case llvm::Triple::spirv64: + switch (Kind) { + case Action::OFK_SYCL: + TC = std::make_unique(*this, Target, *HostTC, + Args); + break; + case Action::OFK_HIP: + TC = std::make_unique(*this, Target, + *HostTC, Args); + break; + case Action::OFK_OpenMP: + TC = std::make_unique(*this, Target, + *HostTC, Args); + break; + case Action::OFK_Cuda: + TC = std::make_unique(*this, Target, *HostTC, + Args); + break; + default: + break; + } + break; + default: + break; + } + } + + // If all else fails, just look up the normal toolchain for the target. + if (!TC) + return getToolChain(Args, Target); + return *TC; +} + const ToolChain &Driver::getToolChain(const ArgList &Args, const llvm::Triple &Target) const { @@ -6794,45 +6837,6 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, return *TC; } -const ToolChain &Driver::getOffloadingDeviceToolChain( - const ArgList &Args, const llvm::Triple &Target, const ToolChain &HostTC, - const Action::OffloadKind &TargetDeviceOffloadKind) const { - // Use device / host triples as the key into the ToolChains map because the - // device ToolChain we create depends on both. - auto &TC = ToolChains[Target.str() + "/" + HostTC.getTriple().str()]; - if (!TC) { - // Categorized by offload kind > arch rather than OS > arch like - // the normal getToolChain call, as it seems a reasonable way to categorize - // things. - switch (TargetDeviceOffloadKind) { - case Action::OFK_HIP: { - if (((Target.getArch() == llvm::Triple::amdgcn || - Target.getArch() == llvm::Triple::spirv64) && - Target.getVendor() == llvm::Triple::AMD && - Target.getOS() == llvm::Triple::AMDHSA) || - !Args.hasArgNoClaim(options::OPT_offload_EQ)) - TC = std::make_unique(*this, Target, - HostTC, Args); - else if (Target.getArch() == llvm::Triple::spirv64 && - Target.getVendor() == llvm::Triple::UnknownVendor && - Target.getOS() == llvm::Triple::UnknownOS) - TC = std::make_unique(*this, Target, - HostTC, Args); - break; - } - case Action::OFK_SYCL: - if (Target.isSPIROrSPIRV()) - TC = std::make_unique(*this, Target, HostTC, - Args); - break; - default: - break; - } - } - assert(TC && "Could not create offloading device tool chain."); - return *TC; -} - bool Driver::ShouldUseClangCompiler(const JobAction &JA) const { // Say "no" if there is not exactly one input of a type clang understands. if (JA.size() != 1 || diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index a0d6919c6dc8d..294f637ef6515 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -575,6 +575,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, options::OPT_fstrict_overflow, false); if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S)) Add &= ~SanitizerKind::SignedIntegerOverflow; + if (Args.hasFlagNoClaim(options::OPT_fwrapv_pointer, + options::OPT_fno_wrapv_pointer, S)) + Add &= ~SanitizerKind::PointerOverflow; } Add &= Supported; @@ -829,6 +832,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, CfiICallNormalizeIntegers = Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers); + KcfiArity = Args.hasArg(options::OPT_fsanitize_kcfi_arity); + if (AllAddedKinds & SanitizerKind::CFI && DiagnoseErrors) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize=kcfi" @@ -1383,6 +1388,14 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, if (CfiICallNormalizeIntegers) CmdArgs.push_back("-fsanitize-cfi-icall-experimental-normalize-integers"); + if (KcfiArity) { + if (!TC.getTriple().isOSLinux() || !TC.getTriple().isArch64Bit()) { + TC.getDriver().Diag(clang::diag::err_drv_kcfi_arity_unsupported_target) + << TC.getTriple().str(); + } + CmdArgs.push_back("-fsanitize-kcfi-arity"); + } + if (CfiCanonicalJumpTables) CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables"); diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index acf9d264d631b..56bc500da66b9 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -646,7 +646,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { case Action::PreprocessJobClass: case Action::ExtractAPIJobClass: case Action::AnalyzeJobClass: - case Action::MigrateJobClass: case Action::VerifyPCHJobClass: case Action::BackendJobClass: return getClang(); @@ -1649,9 +1648,11 @@ void ToolChain::TranslateXarchArgs( A->getOption().matches(options::OPT_Xarch_host)) ValuePos = 0; - unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos)); + const InputArgList &BaseArgs = Args.getBaseArgs(); + unsigned Index = BaseArgs.MakeIndex(A->getValue(ValuePos)); unsigned Prev = Index; - std::unique_ptr XarchArg(Opts.ParseOneArg(Args, Index)); + std::unique_ptr XarchArg(Opts.ParseOneArg( + Args, Index, llvm::opt::Visibility(clang::driver::options::ClangOption))); // If the argument parsing failed or more than one argument was // consumed, the -Xarch_ argument's parameter tried to consume @@ -1673,8 +1674,31 @@ void ToolChain::TranslateXarchArgs( Diags.Report(DiagID) << A->getAsString(Args); return; } + XarchArg->setBaseArg(A); A = XarchArg.release(); + + // Linker input arguments require custom handling. The problem is that we + // have already constructed the phase actions, so we can not treat them as + // "input arguments". + if (A->getOption().hasFlag(options::LinkerInput)) { + // Convert the argument into individual Zlinker_input_args. Need to do this + // manually to avoid memory leaks with the allocated arguments. + for (const char *Value : A->getValues()) { + auto Opt = Opts.getOption(options::OPT_Zlinker_input); + unsigned Index = BaseArgs.MakeIndex(Opt.getName(), Value); + auto NewArg = + new Arg(Opt, BaseArgs.MakeArgString(Opt.getPrefix() + Opt.getName()), + Index, BaseArgs.getArgString(Index + 1), A); + + DAL->append(NewArg); + if (!AllocatedArgs) + DAL->AddSynthesizedArg(NewArg); + else + AllocatedArgs->push_back(NewArg); + } + } + if (!AllocatedArgs) DAL->AddSynthesizedArg(A); else @@ -1698,19 +1722,17 @@ llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs( } else if (A->getOption().matches(options::OPT_Xarch_host)) { NeedTrans = !IsDevice; Skip = IsDevice; - } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) { - // Do not translate -Xarch_ options for non CUDA/HIP toolchain since - // they may need special translation. - // Skip this argument unless the architecture matches BoundArch - if (BoundArch.empty() || A->getValue(0) != BoundArch) - Skip = true; - else - NeedTrans = true; + } else if (A->getOption().matches(options::OPT_Xarch__)) { + NeedTrans = A->getValue() == getArchName() || + (!BoundArch.empty() && A->getValue() == BoundArch); + Skip = !NeedTrans; } if (NeedTrans || Skip) Modified = true; - if (NeedTrans) + if (NeedTrans) { + A->claim(); TranslateXarchArgs(Args, A, DAL, AllocatedArgs); + } if (!Skip) DAL->append(A); } diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index a8061ffd9321f..e66e5a32e58ac 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -950,6 +950,11 @@ void ROCMToolChain::addClangTargetOptions( ABIVer)) return; + std::tuple GPUSan( + DriverArgs.hasFlag(options::OPT_fgpu_sanitize, + options::OPT_fno_gpu_sanitize, true), + getSanitizerArgs(DriverArgs)); + bool Wave64 = isWave64(DriverArgs, Kind); // TODO: There are way too many flags that change this. Do we need to check @@ -965,21 +970,19 @@ void ROCMToolChain::addClangTargetOptions( DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt); // Add the OpenCL specific bitcode library. - llvm::SmallVector BCLibs; - BCLibs.push_back(RocmInstallation->getOpenCLPath().str()); + llvm::SmallVector BCLibs; + BCLibs.emplace_back(RocmInstallation->getOpenCLPath().str()); // Add the generic set of libraries. BCLibs.append(RocmInstallation->getCommonBitcodeLibs( DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt, - FastRelaxedMath, CorrectSqrt, ABIVer, false)); + FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, false)); - if (getSanitizerArgs(DriverArgs).needsAsanRt()) { - CC1Args.push_back("-mlink-bitcode-file"); - CC1Args.push_back( - DriverArgs.MakeArgString(RocmInstallation->getAsanRTLPath())); - } - for (StringRef BCFile : BCLibs) { - CC1Args.push_back("-mlink-builtin-bitcode"); + for (auto [BCFile, Internalize] : BCLibs) { + if (Internalize) + CC1Args.push_back("-mlink-builtin-bitcode"); + else + CC1Args.push_back("-mlink-bitcode-file"); CC1Args.push_back(DriverArgs.MakeArgString(BCFile)); } } @@ -1002,18 +1005,35 @@ bool RocmInstallationDetector::checkCommonBitcodeLibs( return true; } -llvm::SmallVector +llvm::SmallVector RocmInstallationDetector::getCommonBitcodeLibs( const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64, bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath, - bool CorrectSqrt, DeviceLibABIVersion ABIVer, bool isOpenMP = false) const { - llvm::SmallVector BCLibs; - - auto AddBCLib = [&](StringRef BCFile) { BCLibs.push_back(BCFile.str()); }; + bool CorrectSqrt, DeviceLibABIVersion ABIVer, + const std::tuple &GPUSan, + bool isOpenMP = false) const { + llvm::SmallVector BCLibs; + + auto GPUSanEnabled = [GPUSan]() { return std::get(GPUSan); }; + auto AddBCLib = [&](ToolChain::BitCodeLibraryInfo BCLib, + bool Internalize = true) { + BCLib.ShouldInternalize = Internalize; + BCLibs.emplace_back(BCLib); + }; + auto AddSanBCLibs = [&]() { + if (GPUSanEnabled()) { + auto SanArgs = std::get(GPUSan); + if (SanArgs.needsAsanRt()) + AddBCLib(getAsanRTLPath(), false); + } + }; + AddSanBCLibs(); AddBCLib(getOCMLPath()); if (!isOpenMP) AddBCLib(getOCKLPath()); + else if (GPUSanEnabled() && isOpenMP) + AddBCLib(getOCKLPath(), false); AddBCLib(getDenormalsAreZeroPath(DAZ)); AddBCLib(getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath)); AddBCLib(getFiniteOnlyPath(FiniteOnly || FastRelaxedMath)); @@ -1027,7 +1047,7 @@ RocmInstallationDetector::getCommonBitcodeLibs( return BCLibs; } -llvm::SmallVector +llvm::SmallVector ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, const std::string &GPUArch, bool isOpenMP) const { @@ -1044,6 +1064,10 @@ ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, // If --hip-device-lib is not set, add the default bitcode libraries. // TODO: There are way too many flags that change this. Do we need to check // them all? + std::tuple GPUSan( + DriverArgs.hasFlag(options::OPT_fgpu_sanitize, + options::OPT_fno_gpu_sanitize, false), + getSanitizerArgs(DriverArgs)); bool DAZ = DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero, options::OPT_fno_gpu_flush_denormals_to_zero, getDefaultDenormsAreZeroForTarget(Kind)); @@ -1061,7 +1085,7 @@ ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, return RocmInstallation->getCommonBitcodeLibs( DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt, - FastRelaxedMath, CorrectSqrt, ABIVer, isOpenMP); + FastRelaxedMath, CorrectSqrt, ABIVer, GPUSan, isOpenMP); } bool AMDGPUToolChain::shouldSkipSanitizeOption( @@ -1075,7 +1099,7 @@ bool AMDGPUToolChain::shouldSkipSanitizeOption( return false; if (!DriverArgs.hasFlag(options::OPT_fgpu_sanitize, - options::OPT_fno_gpu_sanitize, true)) + options::OPT_fno_gpu_sanitize, false)) return true; auto &Diags = TC.getDriver().getDiags(); diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h index a9b4552a1f91a..bc941a40445ad 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.h +++ b/clang/lib/Driver/ToolChains/AMDGPU.h @@ -142,13 +142,28 @@ class LLVM_LIBRARY_VISIBILITY ROCMToolChain : public AMDGPUToolChain { Action::OffloadKind DeviceOffloadKind) const override; // Returns a list of device library names shared by different languages - llvm::SmallVector + llvm::SmallVector getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, const std::string &GPUArch, bool isOpenMP = false) const; + SanitizerMask getSupportedSanitizers() const override { return SanitizerKind::Address; } + + void diagnoseUnsupportedSanitizers(const llvm::opt::ArgList &Args) const { + if (!Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize, + true)) + return; + auto &Diags = getDriver().getDiags(); + for (auto *A : Args.filtered(options::OPT_fsanitize_EQ)) { + SanitizerMask K = + parseSanitizerValue(A->getValue(), /*Allow Groups*/ false); + if (K != SanitizerKind::Address) + Diags.Report(clang::diag::warn_drv_unsupported_option_for_target) + << A->getAsString(Args) << getTriple().str(); + } + } }; } // end namespace toolchains diff --git a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp index 3f0b3f2d86b3e..00bf9c7338edd 100644 --- a/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp @@ -9,7 +9,7 @@ #include "AMDGPUOpenMP.h" #include "AMDGPU.h" #include "CommonArgs.h" -#include "ToolChains/ROCm.h" +#include "ROCm.h" #include "clang/Basic/DiagnosticDriver.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" @@ -37,6 +37,8 @@ AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver &D, // Lookup binaries into the driver directory, this is used to // discover the 'amdgpu-arch' executable. getProgramPaths().push_back(getDriver().Dir); + // Diagnose unsupported sanitizer options only once. + diagnoseUnsupportedSanitizers(Args); } void AMDGPUOpenMPToolChain::addClangTargetOptions( @@ -71,34 +73,10 @@ llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs( const OptTable &Opts = getDriver().getOpts(); - if (DeviceOffloadKind == Action::OFK_OpenMP) { - for (Arg *A : Args) - if (!llvm::is_contained(*DAL, A)) - DAL->append(A); - - if (!DAL->hasArg(options::OPT_march_EQ)) { - StringRef Arch = BoundArch; - if (Arch.empty()) { - auto ArchsOrErr = getSystemGPUArchs(Args); - if (!ArchsOrErr) { - std::string ErrMsg = - llvm::formatv("{0}", llvm::fmt_consume(ArchsOrErr.takeError())); - getDriver().Diag(diag::err_drv_undetermined_gpu_arch) - << llvm::Triple::getArchTypeName(getArch()) << ErrMsg << "-march"; - Arch = OffloadArchToString(OffloadArch::HIPDefault); - } else { - Arch = Args.MakeArgString(ArchsOrErr->front()); - } - } - DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), Arch); - } - - return DAL; - } - - for (Arg *A : Args) { - DAL->append(A); - } + for (Arg *A : Args) + if (!shouldSkipSanitizeOption(*this, Args, BoundArch, A) && + !llvm::is_contained(*DAL, A)) + DAL->append(A); if (!BoundArch.empty()) { DAL->eraseArg(options::OPT_march_EQ); @@ -159,11 +137,6 @@ AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const { if (Args.hasArg(options::OPT_nogpulib)) return {}; - if (!RocmInstallation->hasDeviceLibrary()) { - getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0; - return {}; - } - StringRef GpuArch = getProcessorFromTargetID( getTriple(), Args.getLastArgValue(options::OPT_march_EQ)); diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index b2109e11038fe..47c2c3e23f9fd 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -237,15 +237,18 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, bool IsNegative = Name.consume_front("no-"); -#ifndef NDEBUG - assert(Name.starts_with("avx10.") && "Invalid AVX10 feature name."); StringRef Version, Width; std::tie(Version, Width) = Name.substr(6).split('-'); + assert(Name.starts_with("avx10.") && "Invalid AVX10 feature name."); assert((Version == "1" || Version == "2") && "Invalid AVX10 feature name."); - assert((Width == "256" || Width == "512") && "Invalid AVX10 feature name."); -#endif - Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); + if (Width == "") { + assert(IsNegative && "Only negative options can omit width."); + Features.push_back(Args.MakeArgString("-" + Name + "-256")); + } else { + assert((Width == "256" || Width == "512") && "Invalid vector length."); + Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); + } } // Now add any that the user explicitly requested on the command line, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 518113e20cb06..5deafa2ad0f4a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -580,6 +580,7 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, const ArgList &Args, SanitizerArgs &SanArgs, ArgStringList &CmdArgs) { const Driver &D = TC.getDriver(); + const llvm::Triple &T = TC.getTriple(); auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate, options::OPT_fprofile_generate_EQ, options::OPT_fno_profile_generate); @@ -785,6 +786,34 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, D.Diag(diag::err_drv_unsupported_option_argument) << A->getSpelling() << Val; } + if (const auto *A = Args.getLastArg(options::OPT_fprofile_continuous)) { + if (!PGOGenerateArg && !CSPGOGenerateArg && !ProfileGenerateArg) + D.Diag(clang::diag::err_drv_argument_only_allowed_with) + << A->getSpelling() + << "-fprofile-generate, -fprofile-instr-generate, or " + "-fcs-profile-generate"; + else { + CmdArgs.push_back("-fprofile-continuous"); + // Platforms that require a bias variable: + if (T.isOSBinFormatELF() || T.isOSAIX()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-runtime-counter-relocation"); + } + // -fprofile-instr-generate does not decide the profile file name in the + // FE, and so it does not define the filename symbol + // (__llvm_profile_filename). Instead, the runtime uses the name + // "default.profraw" for the profile file. When continuous mode is ON, we + // will create the filename symbol so that we can insert the "%c" + // modifier. + if (ProfileGenerateArg && + (ProfileGenerateArg->getOption().matches( + options::OPT_fprofile_instr_generate) || + (ProfileGenerateArg->getOption().matches( + options::OPT_fprofile_instr_generate_EQ) && + strlen(ProfileGenerateArg->getValue()) == 0))) + CmdArgs.push_back("-fprofile-instrument-path=default.profraw"); + } + } int FunctionGroups = 1; int SelectedFunctionGroup = 0; @@ -1013,21 +1042,23 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, ArgM = ArgMD; if (ArgM) { - // Determine the output location. - const char *DepFile; - if (Arg *MF = Args.getLastArg(options::OPT_MF)) { - DepFile = MF->getValue(); - C.addFailureResultFile(DepFile, &JA); - } else if (Output.getType() == types::TY_Dependencies) { - DepFile = Output.getFilename(); - } else if (!ArgMD) { - DepFile = "-"; - } else { - DepFile = getDependencyFileName(Args, Inputs); - C.addFailureResultFile(DepFile, &JA); + if (!JA.isDeviceOffloading(Action::OFK_HIP)) { + // Determine the output location. + const char *DepFile; + if (Arg *MF = Args.getLastArg(options::OPT_MF)) { + DepFile = MF->getValue(); + C.addFailureResultFile(DepFile, &JA); + } else if (Output.getType() == types::TY_Dependencies) { + DepFile = Output.getFilename(); + } else if (!ArgMD) { + DepFile = "-"; + } else { + DepFile = getDependencyFileName(Args, Inputs); + C.addFailureResultFile(DepFile, &JA); + } + CmdArgs.push_back("-dependency-file"); + CmdArgs.push_back(DepFile); } - CmdArgs.push_back("-dependency-file"); - CmdArgs.push_back(DepFile); bool HasTarget = false; for (const Arg *A : Args.filtered(options::OPT_MT, options::OPT_MQ)) { @@ -1358,6 +1389,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { return true; return false; + case llvm::Triple::csky: case llvm::Triple::hexagon: case llvm::Triple::msp430: case llvm::Triple::ppcle: @@ -1560,15 +1592,21 @@ static void handlePAuthABI(const ArgList &DriverArgs, ArgStringList &CC1Args) { static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, bool isAArch64) { + const llvm::Triple &Triple = TC.getEffectiveTriple(); const Arg *A = isAArch64 ? Args.getLastArg(options::OPT_msign_return_address_EQ, options::OPT_mbranch_protection_EQ) : Args.getLastArg(options::OPT_mbranch_protection_EQ); - if (!A) + if (!A) { + if (Triple.isOSOpenBSD() && isAArch64) { + CmdArgs.push_back("-msign-return-address=non-leaf"); + CmdArgs.push_back("-msign-return-address-key=a_key"); + CmdArgs.push_back("-mbranch-target-enforce"); + } return; + } const Driver &D = TC.getDriver(); - const llvm::Triple &Triple = TC.getEffectiveTriple(); if (!(isAArch64 || (Triple.isArmT32() && Triple.isArmMClass()))) D.Diag(diag::warn_incompatible_branch_protection_option) << Triple.getArchName(); @@ -1582,7 +1620,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, D.Diag(diag::err_drv_unsupported_option_argument) << A->getSpelling() << Scope; Key = "a_key"; - IndirectBranches = false; + IndirectBranches = Triple.isOSOpenBSD() && isAArch64; BranchProtectionPAuthLR = false; GuardedControlStack = false; } else { @@ -1618,32 +1656,34 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, GuardedControlStack = PBP.GuardedControlStack; } - CmdArgs.push_back( - Args.MakeArgString(Twine("-msign-return-address=") + Scope)); - if (Scope != "none") { + bool HasPtrauthReturns = llvm::any_of(CmdArgs, [](const char *Arg) { + return StringRef(Arg) == "-fptrauth-returns"; + }); + // GCS is currently untested with ptrauth-returns, but enabling this could be + // allowed in future after testing with a suitable system. + if (HasPtrauthReturns && + (Scope != "none" || BranchProtectionPAuthLR || GuardedControlStack)) { if (Triple.getEnvironment() == llvm::Triple::PAuthTest) D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args) << Triple.getTriple(); + else + D.Diag(diag::err_drv_incompatible_options) + << A->getAsString(Args) << "-fptrauth-returns"; + } + + CmdArgs.push_back( + Args.MakeArgString(Twine("-msign-return-address=") + Scope)); + if (Scope != "none") CmdArgs.push_back( Args.MakeArgString(Twine("-msign-return-address-key=") + Key)); - } - if (BranchProtectionPAuthLR) { - if (Triple.getEnvironment() == llvm::Triple::PAuthTest) - D.Diag(diag::err_drv_unsupported_opt_for_target) - << A->getAsString(Args) << Triple.getTriple(); + if (BranchProtectionPAuthLR) CmdArgs.push_back( Args.MakeArgString(Twine("-mbranch-protection-pauth-lr"))); - } if (IndirectBranches) CmdArgs.push_back("-mbranch-target-enforce"); - // GCS is currently untested with PAuthABI, but enabling this could be allowed - // in future after testing with a suitable system. - if (GuardedControlStack) { - if (Triple.getEnvironment() == llvm::Triple::PAuthTest) - D.Diag(diag::err_drv_unsupported_opt_for_target) - << A->getAsString(Args) << Triple.getTriple(); + + if (GuardedControlStack) CmdArgs.push_back("-mguarded-control-stack"); - } } void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, @@ -1822,12 +1862,6 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, CmdArgs.push_back("-aarch64-enable-global-merge=true"); } - // Enable/disable return address signing and indirect branch targets. - CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/); - - if (Triple.getEnvironment() == llvm::Triple::PAuthTest) - handlePAuthABI(Args, CmdArgs); - // Handle -msve_vector_bits= if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { StringRef Val = A->getValue(); @@ -1896,6 +1930,12 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, options::OPT_fno_ptrauth_init_fini_address_discrimination); Args.addOptInFlag(CmdArgs, options::OPT_faarch64_jump_table_hardening, options::OPT_fno_aarch64_jump_table_hardening); + + if (Triple.getEnvironment() == llvm::Triple::PAuthTest) + handlePAuthABI(Args, CmdArgs); + + // Enable/disable return address signing and indirect branch targets. + CollectARMPACBTIOptions(getToolChain(), Args, CmdArgs, true /*isAArch64*/); } void Clang::AddLoongArchTargetArgs(const ArgList &Args, @@ -3958,78 +3998,6 @@ static void RenderOpenACCOptions(const Driver &D, const ArgList &Args, } } -static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args, - ArgStringList &CmdArgs) { - bool ARCMTEnabled = false; - if (!Args.hasArg(options::OPT_fno_objc_arc, options::OPT_fobjc_arc)) { - if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check, - options::OPT_ccc_arcmt_modify, - options::OPT_ccc_arcmt_migrate)) { - ARCMTEnabled = true; - switch (A->getOption().getID()) { - default: llvm_unreachable("missed a case"); - case options::OPT_ccc_arcmt_check: - CmdArgs.push_back("-arcmt-action=check"); - break; - case options::OPT_ccc_arcmt_modify: - CmdArgs.push_back("-arcmt-action=modify"); - break; - case options::OPT_ccc_arcmt_migrate: - CmdArgs.push_back("-arcmt-action=migrate"); - CmdArgs.push_back("-mt-migrate-directory"); - CmdArgs.push_back(A->getValue()); - - Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output); - Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_emit_arc_errors); - break; - } - } - } else { - Args.ClaimAllArgs(options::OPT_ccc_arcmt_check); - Args.ClaimAllArgs(options::OPT_ccc_arcmt_modify); - Args.ClaimAllArgs(options::OPT_ccc_arcmt_migrate); - } - - if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) { - if (ARCMTEnabled) - D.Diag(diag::err_drv_argument_not_allowed_with) - << A->getAsString(Args) << "-ccc-arcmt-migrate"; - - CmdArgs.push_back("-mt-migrate-directory"); - CmdArgs.push_back(A->getValue()); - - if (!Args.hasArg(options::OPT_objcmt_migrate_literals, - options::OPT_objcmt_migrate_subscripting, - options::OPT_objcmt_migrate_property)) { - // None specified, means enable them all. - CmdArgs.push_back("-objcmt-migrate-literals"); - CmdArgs.push_back("-objcmt-migrate-subscripting"); - CmdArgs.push_back("-objcmt-migrate-property"); - } else { - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); - } - } else { - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_all); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readonly_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_readwrite_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_property_dot_syntax); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_annotation); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_instancetype); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_nsmacros); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_protocol_conformance); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_designated_init); - Args.AddLastArg(CmdArgs, options::OPT_objcmt_allowlist_dir_path); - } -} - static void RenderBuiltinOptions(const ToolChain &TC, const llvm::Triple &T, const ArgList &Args, ArgStringList &CmdArgs) { // -fbuiltin is default unless -mkernel is used. @@ -5319,8 +5287,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (isa(JA)) { assert(JA.getType() == types::TY_Plist && "Invalid output type."); CmdArgs.push_back("-analyze"); - } else if (isa(JA)) { - CmdArgs.push_back("-migrate"); } else if (isa(JA)) { if (Output.getType() == types::TY_Dependencies) CmdArgs.push_back("-Eonly"); @@ -5654,6 +5620,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_static)) CmdArgs.push_back("-static-define"); + Args.AddLastArg(CmdArgs, options::OPT_static_libclosure); + if (Args.hasArg(options::OPT_municode)) CmdArgs.push_back("-DUNICODE"); @@ -6445,8 +6413,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_working_directory); - RenderARCMigrateToolOptions(D, Args, CmdArgs); - // Add preprocessing options like -I, -D, etc. if we are using the // preprocessor. // @@ -7040,6 +7006,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings); Args.AddLastArg(CmdArgs, options::OPT_funroll_loops, options::OPT_fno_unroll_loops); + Args.AddLastArg(CmdArgs, options::OPT_floop_interchange, + options::OPT_fno_loop_interchange); Args.AddLastArg(CmdArgs, options::OPT_fstrict_flex_arrays_EQ); @@ -7130,6 +7098,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *SA = Args.getLastArg(options::OPT_mcf_branch_label_scheme_EQ)) CmdArgs.push_back(Args.MakeArgString(Twine("-mcf-branch-label-scheme=") + SA->getValue())); + } else if (Triple.isOSOpenBSD() && Triple.getArch() == llvm::Triple::x86_64) { + // Emit IBT endbr64 instructions by default + CmdArgs.push_back("-fcf-protection=branch"); + // jump-table can generate indirect jumps, which are not permitted + CmdArgs.push_back("-fno-jump-tables"); } if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ)) @@ -7502,20 +7475,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.addOptOutFlag(CmdArgs, options::OPT_fassume_unique_vtables, options::OPT_fno_assume_unique_vtables); - // -frelaxed-template-template-args is deprecated. - if (Arg *A = - Args.getLastArg(options::OPT_frelaxed_template_template_args, - options::OPT_fno_relaxed_template_template_args)) { - if (A->getOption().matches( - options::OPT_fno_relaxed_template_template_args)) { - D.Diag(diag::warn_drv_deprecated_arg_no_relaxed_template_template_args); - CmdArgs.push_back("-fno-relaxed-template-template-args"); - } else { - D.Diag(diag::warn_drv_deprecated_arg) - << A->getAsString(Args) << /*hasReplacement=*/false; - } - } - // -fsized-deallocation is on by default in C++14 onwards and otherwise off // by default. Args.addLastArg(CmdArgs, options::OPT_fsized_deallocation, @@ -7706,6 +7665,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fretain_comments_from_system_headers)) CmdArgs.push_back("-fretain-comments-from-system-headers"); + Args.AddLastArg(CmdArgs, options::OPT_fextend_variable_liveness_EQ); + // Forward -fcomment-block-commands to -cc1. Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands); // Forward -fparse-all-comments to -cc1. @@ -9202,7 +9163,7 @@ void OffloadPackager::ConstructJob(Compilation &C, const JobAction &JA, SmallVector Parts{ "file=" + File.str(), "triple=" + TC->getTripleString(), - "arch=" + Arch.str(), + "arch=" + (Arch.empty() ? "generic" : Arch.str()), "kind=" + Kind.str(), }; @@ -9224,81 +9185,81 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - const Driver &D = getToolChain().getDriver(); - const llvm::Triple TheTriple = getToolChain().getTriple(); - ArgStringList CmdArgs; + using namespace options; + + // A list of permitted options that will be forwarded to the embedded device + // compilation job. + const llvm::DenseSet CompilerOptions{ + OPT_v, + OPT_cuda_path_EQ, + OPT_rocm_path_EQ, + OPT_O_Group, + OPT_g_Group, + OPT_g_flags_Group, + OPT_R_value_Group, + OPT_R_Group, + OPT_Xcuda_ptxas, + OPT_ftime_report, + OPT_ftime_trace, + OPT_ftime_trace_EQ, + OPT_ftime_trace_granularity_EQ, + OPT_ftime_trace_verbose, + OPT_opt_record_file, + OPT_opt_record_format, + OPT_opt_record_passes, + OPT_fsave_optimization_record, + OPT_fsave_optimization_record_EQ, + OPT_fno_save_optimization_record, + OPT_foptimization_record_file_EQ, + OPT_foptimization_record_passes_EQ, + OPT_save_temps, + OPT_save_temps_EQ, + OPT_mcode_object_version_EQ, + OPT_load, + OPT_fno_lto, + OPT_flto, + OPT_flto_EQ}; + const llvm::DenseSet LinkerOptions{OPT_mllvm, OPT_Zlinker_input}; + auto ShouldForward = [&](const llvm::DenseSet &Set, Arg *A) { + return Set.contains(A->getOption().getID()) || + (A->getOption().getGroup().isValid() && + Set.contains(A->getOption().getGroup().getID())); + }; - // Pass the CUDA path to the linker wrapper tool. + ArgStringList CmdArgs; for (Action::OffloadKind Kind : {Action::OFK_Cuda, Action::OFK_OpenMP}) { auto TCRange = C.getOffloadToolChains(Kind); for (auto &I : llvm::make_range(TCRange)) { const ToolChain *TC = I.second; - if (TC->getTriple().isNVPTX()) { - CudaInstallationDetector CudaInstallation(D, TheTriple, Args); - if (CudaInstallation.isValid()) - CmdArgs.push_back(Args.MakeArgString( - "--cuda-path=" + CudaInstallation.getInstallPath())); - break; + + // We do not use a bound architecture here so options passed only to a + // specific architecture via -Xarch_ will not be forwarded. + ArgStringList CompilerArgs; + ArgStringList LinkerArgs; + for (Arg *A : C.getArgsForToolChain(TC, /*BoundArch=*/"", Kind)) { + if (A->getOption().matches(OPT_Zlinker_input)) + LinkerArgs.emplace_back(A->getValue()); + else if (ShouldForward(CompilerOptions, A)) + A->render(Args, CompilerArgs); + else if (ShouldForward(LinkerOptions, A)) + A->render(Args, LinkerArgs); } - } - } - // Pass in the optimization level to use for LTO. - if (const Arg *A = Args.getLastArg(options::OPT_O_Group)) { - StringRef OOpt; - if (A->getOption().matches(options::OPT_O4) || - A->getOption().matches(options::OPT_Ofast)) - OOpt = "3"; - else if (A->getOption().matches(options::OPT_O)) { - OOpt = A->getValue(); - if (OOpt == "g") - OOpt = "1"; - else if (OOpt == "s" || OOpt == "z") - OOpt = "2"; - } else if (A->getOption().matches(options::OPT_O0)) - OOpt = "0"; - if (!OOpt.empty()) - CmdArgs.push_back(Args.MakeArgString(Twine("--opt-level=O") + OOpt)); + // Forward all of these to the appropriate toolchain. + for (StringRef Arg : CompilerArgs) + CmdArgs.push_back(Args.MakeArgString( + "--device-compiler=" + TC->getTripleString() + "=" + Arg)); + for (StringRef Arg : LinkerArgs) + CmdArgs.push_back(Args.MakeArgString( + "--device-linker=" + TC->getTripleString() + "=" + Arg)); + } } CmdArgs.push_back( - Args.MakeArgString("--host-triple=" + TheTriple.getTriple())); + Args.MakeArgString("--host-triple=" + getToolChain().getTripleString())); if (Args.hasArg(options::OPT_v)) CmdArgs.push_back("--wrapper-verbose"); - if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { - if (!A->getOption().matches(options::OPT_g0)) - CmdArgs.push_back("--device-debug"); - } - - // code-object-version=X needs to be passed to clang-linker-wrapper to ensure - // that it is used by lld. - if (const Arg *A = Args.getLastArg(options::OPT_mcode_object_version_EQ)) { - CmdArgs.push_back(Args.MakeArgString("-mllvm")); - CmdArgs.push_back(Args.MakeArgString( - Twine("--amdhsa-code-object-version=") + A->getValue())); - } - - for (const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas)) - CmdArgs.push_back(Args.MakeArgString("--ptxas-arg=" + A)); - - // Forward remarks passes to the LLVM backend in the wrapper. - if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ)) - CmdArgs.push_back(Args.MakeArgString(Twine("--offload-opt=-pass-remarks=") + - A->getValue())); - if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ)) - CmdArgs.push_back(Args.MakeArgString( - Twine("--offload-opt=-pass-remarks-missed=") + A->getValue())); - if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ)) - CmdArgs.push_back(Args.MakeArgString( - Twine("--offload-opt=-pass-remarks-analysis=") + A->getValue())); - - if (Args.getLastArg(options::OPT_ftime_report)) - CmdArgs.push_back("--device-compiler=-ftime-report"); - - if (Args.getLastArg(options::OPT_save_temps_EQ)) - CmdArgs.push_back("--save-temps"); - // Construct the link job so we can wrap around it. Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput); const auto &LinkCommand = C.getJobs().getJobs().back(); @@ -9322,12 +9283,10 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_openmp_target_jit, false)) CmdArgs.push_back("--embed-bitcode"); - // Forward `-mllvm` arguments to the LLVM invocations if present. - for (Arg *A : Args.filtered(options::OPT_mllvm)) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back(A->getValue()); - A->claim(); - } + // Save temporary files created by the linker wrapper. + if (Args.hasArg(options::OPT_save_temps_EQ) || + Args.hasArg(options::OPT_save_temps)) + CmdArgs.push_back("--save-temps"); // Pass in the C library for GPUs if present and not disabled. if (!Args.hasArg(options::OPT_nostdlib, options::OPT_r, options::OPT_nogpulib, @@ -9354,11 +9313,6 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, }); } - // If we disable the GPU C library support it needs to be forwarded to the - // link job. - if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, true)) - CmdArgs.push_back("--device-compiler=-nolibc"); - // Add the linker arguments to be forwarded by the wrapper. CmdArgs.push_back(Args.MakeArgString(Twine("--linker-path=") + LinkCommand->getExecutable())); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index c045069c34424..9a4d3f55c911c 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1321,7 +1321,7 @@ void tools::addOpenMPHostOffloadingArgs(const Compilation &C, /// Add Fortran runtime libs void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { - // Link FortranRuntime and FortranDecimal + // Link flang_rt.runtime // These are handled earlier on Windows by telling the frontend driver to // add the correct libraries to link against as dependents in the object // file. @@ -1330,16 +1330,20 @@ void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, F128LibName.consume_front_insensitive("lib"); if (!F128LibName.empty()) { bool AsNeeded = !TC.getTriple().isOSAIX(); - CmdArgs.push_back("-lFortranFloat128Math"); + CmdArgs.push_back("-lflang_rt.quadmath"); if (AsNeeded) addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/true); CmdArgs.push_back(Args.MakeArgString("-l" + F128LibName)); if (AsNeeded) addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/false); } - CmdArgs.push_back("-lFortranRuntime"); - CmdArgs.push_back("-lFortranDecimal"); + CmdArgs.push_back("-lflang_rt.runtime"); addArchSpecificRPath(TC, Args, CmdArgs); + + // needs libexecinfo for backtrace functions + if (TC.getTriple().isOSFreeBSD() || TC.getTriple().isOSNetBSD() || + TC.getTriple().isOSOpenBSD() || TC.getTriple().isOSDragonFly()) + CmdArgs.push_back("-lexecinfo"); } // libomp needs libatomic for atomic operations if using libgcc @@ -1440,13 +1444,12 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, CmdArgs.push_back("-lm"); // There's no libdl on all OSes. if (!TC.getTriple().isOSFreeBSD() && !TC.getTriple().isOSNetBSD() && - !TC.getTriple().isOSOpenBSD() && + !TC.getTriple().isOSOpenBSD() && !TC.getTriple().isOSDragonFly() && TC.getTriple().getOS() != llvm::Triple::RTEMS) CmdArgs.push_back("-ldl"); // Required for backtrace on some OSes - if (TC.getTriple().isOSFreeBSD() || - TC.getTriple().isOSNetBSD() || - TC.getTriple().isOSOpenBSD()) + if (TC.getTriple().isOSFreeBSD() || TC.getTriple().isOSNetBSD() || + TC.getTriple().isOSOpenBSD() || TC.getTriple().isOSDragonFly()) CmdArgs.push_back("-lexecinfo"); // There is no libresolv on Android, FreeBSD, OpenBSD, etc. On musl // libresolv.a, even if exists, is an empty archive to satisfy POSIX -lresolv @@ -3093,14 +3096,39 @@ bool tools::shouldRecordCommandLine(const ToolChain &TC, void tools::renderCommonIntegerOverflowOptions(const ArgList &Args, ArgStringList &CmdArgs) { - // -fno-strict-overflow implies -fwrapv if it isn't disabled, but - // -fstrict-overflow won't turn off an explicitly enabled -fwrapv. - if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) { - if (A->getOption().matches(options::OPT_fwrapv)) - CmdArgs.push_back("-fwrapv"); - } else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow, - options::OPT_fno_strict_overflow)) { - if (A->getOption().matches(options::OPT_fno_strict_overflow)) - CmdArgs.push_back("-fwrapv"); + bool use_fwrapv = false; + bool use_fwrapv_pointer = false; + for (const Arg *A : Args.filtered( + options::OPT_fstrict_overflow, options::OPT_fno_strict_overflow, + options::OPT_fwrapv, options::OPT_fno_wrapv, + options::OPT_fwrapv_pointer, options::OPT_fno_wrapv_pointer)) { + A->claim(); + switch (A->getOption().getID()) { + case options::OPT_fstrict_overflow: + use_fwrapv = false; + use_fwrapv_pointer = false; + break; + case options::OPT_fno_strict_overflow: + use_fwrapv = true; + use_fwrapv_pointer = true; + break; + case options::OPT_fwrapv: + use_fwrapv = true; + break; + case options::OPT_fno_wrapv: + use_fwrapv = false; + break; + case options::OPT_fwrapv_pointer: + use_fwrapv_pointer = true; + break; + case options::OPT_fno_wrapv_pointer: + use_fwrapv_pointer = false; + break; + } } + + if (use_fwrapv) + CmdArgs.push_back("-fwrapv"); + if (use_fwrapv_pointer) + CmdArgs.push_back("-fwrapv-pointer"); } diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index 0922a97ed7c19..d6487d4bc274d 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -123,7 +123,7 @@ CudaVersion parseCudaHFile(llvm::StringRef Input) { } } // namespace -void CudaInstallationDetector::WarnIfUnsupportedVersion() { +void CudaInstallationDetector::WarnIfUnsupportedVersion() const { if (Version > CudaVersion::PARTIALLY_SUPPORTED) { std::string VersionString = CudaVersionToString(Version); if (!VersionString.empty()) @@ -639,9 +639,6 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back( Args.MakeArgString("--plugin-opt=-mattr=" + llvm::join(Features, ","))); - // Enable ctor / dtor lowering for the direct / freestanding NVPTX target. - CmdArgs.append({"-mllvm", "--nvptx-lower-global-ctor-dtor"}); - // Add paths for the default clang library path. SmallString<256> DefaultLibPath = llvm::sys::path::parent_path(TC.getDriver().Dir); @@ -726,9 +723,8 @@ void NVPTX::getNVPTXTargetFeatures(const Driver &D, const llvm::Triple &Triple, /// toolchain. NVPTXToolChain::NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::Triple &HostTriple, - const ArgList &Args, bool Freestanding = false) - : ToolChain(D, Triple, Args), CudaInstallation(D, HostTriple, Args), - Freestanding(Freestanding) { + const ArgList &Args) + : ToolChain(D, Triple, Args), CudaInstallation(D, HostTriple, Args) { if (CudaInstallation.isValid()) getProgramPaths().push_back(std::string(CudaInstallation.getBinPath())); // Lookup binaries into the driver directory, this is used to @@ -740,8 +736,7 @@ NVPTXToolChain::NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, /// system's default triple if not provided. NVPTXToolChain::NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : NVPTXToolChain(D, Triple, llvm::Triple(LLVM_HOST_TRIPLE), Args, - /*Freestanding=*/true) {} + : NVPTXToolChain(D, Triple, llvm::Triple(LLVM_HOST_TRIPLE), Args) {} llvm::opt::DerivedArgList * NVPTXToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, @@ -782,13 +777,7 @@ NVPTXToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, void NVPTXToolChain::addClangTargetOptions( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, - Action::OffloadKind DeviceOffloadingKind) const { - // If we are compiling with a standalone NVPTX toolchain we want to try to - // mimic a standard environment as much as possible. So we enable lowering - // ctor / dtor functions to global symbols that can be registered. - if (Freestanding && !getDriver().isUsingLTO()) - CC1Args.append({"-mllvm", "--nvptx-lower-global-ctor-dtor"}); -} + Action::OffloadKind DeviceOffloadingKind) const {} bool NVPTXToolChain::supportsDebugInfoOption(const llvm::opt::Arg *A) const { const Option &O = A->getOption(); @@ -969,34 +958,6 @@ CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, const OptTable &Opts = getDriver().getOpts(); - // For OpenMP device offloading, append derived arguments. Make sure - // flags are not duplicated. - // Also append the compute capability. - if (DeviceOffloadKind == Action::OFK_OpenMP) { - for (Arg *A : Args) - if (!llvm::is_contained(*DAL, A)) - DAL->append(A); - - if (!DAL->hasArg(options::OPT_march_EQ)) { - StringRef Arch = BoundArch; - if (Arch.empty()) { - auto ArchsOrErr = getSystemGPUArchs(Args); - if (!ArchsOrErr) { - std::string ErrMsg = - llvm::formatv("{0}", llvm::fmt_consume(ArchsOrErr.takeError())); - getDriver().Diag(diag::err_drv_undetermined_gpu_arch) - << llvm::Triple::getArchTypeName(getArch()) << ErrMsg << "-march"; - Arch = OffloadArchToString(OffloadArch::CudaDefault); - } else { - Arch = Args.MakeArgString(ArchsOrErr->front()); - } - } - DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), Arch); - } - - return DAL; - } - for (Arg *A : Args) { // Make sure flags are not duplicated. if (!llvm::is_contained(*DAL, A)) { diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h index 7a6a6fb209012..259eda6ebcadf 100644 --- a/clang/lib/Driver/ToolChains/Cuda.h +++ b/clang/lib/Driver/ToolChains/Cuda.h @@ -74,7 +74,7 @@ class CudaInstallationDetector { std::string getLibDeviceFile(StringRef Gpu) const { return LibDeviceMap.lookup(Gpu); } - void WarnIfUnsupportedVersion(); + void WarnIfUnsupportedVersion() const; }; namespace tools { @@ -132,8 +132,8 @@ namespace toolchains { class LLVM_LIBRARY_VISIBILITY NVPTXToolChain : public ToolChain { public: NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, - const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args, - bool Freestanding); + const llvm::Triple &HostTriple, + const llvm::opt::ArgList &Args); NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); @@ -179,9 +179,6 @@ class LLVM_LIBRARY_VISIBILITY NVPTXToolChain : public ToolChain { protected: Tool *buildAssembler() const override; // ptxas. Tool *buildLinker() const override; // nvlink. - -private: - bool Freestanding = false; }; class LLVM_LIBRARY_VISIBILITY CudaToolChain : public NVPTXToolChain { diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 55c55bad73934..b26c5bf1a909e 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -588,20 +588,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, // more information. ArgStringList CmdArgs; - /// Hack(tm) to ignore linking errors when we are doing ARC migration. - if (Args.hasArg(options::OPT_ccc_arcmt_check, - options::OPT_ccc_arcmt_migrate)) { - for (const auto &Arg : Args) - Arg->claim(); - const char *Exec = - Args.MakeArgString(getToolChain().GetProgramPath("touch")); - CmdArgs.push_back(Output.getFilename()); - C.addCommand(std::make_unique(JA, *this, - ResponseFileSupport::None(), Exec, - CmdArgs, std::nullopt, Output)); - return; - } - VersionTuple Version = getMachOToolChain().getLinkerVersion(Args); bool LinkerIsLLD; @@ -2791,30 +2777,6 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, // and try to push it down into tool specific logic. for (Arg *A : Args) { - if (A->getOption().matches(options::OPT_Xarch__)) { - // Skip this argument unless the architecture matches either the toolchain - // triple arch, or the arch being bound. - StringRef XarchArch = A->getValue(0); - if (!(XarchArch == getArchName() || - (!BoundArch.empty() && XarchArch == BoundArch))) - continue; - - Arg *OriginalArg = A; - TranslateXarchArgs(Args, A, DAL); - - // Linker input arguments require custom handling. The problem is that we - // have already constructed the phase actions, so we can not treat them as - // "input arguments". - if (A->getOption().hasFlag(options::LinkerInput)) { - // Convert the argument into individual Zlinker_input_args. - for (const char *Value : A->getValues()) { - DAL->AddSeparateArg( - OriginalArg, Opts.getOption(options::OPT_Zlinker_input), Value); - } - continue; - } - } - // Sob. These is strictly gcc compatible for the time being. Apple // gcc translates options twice, which means that self-expanding // options add duplicates. diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 45d05ed3e2485..591003f56e8bb 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -42,6 +42,7 @@ void Flang::addFortranDialectOptions(const ArgList &Args, options::OPT_fopenacc, options::OPT_finput_charset_EQ, options::OPT_fimplicit_none, + options::OPT_fimplicit_none_ext, options::OPT_fno_implicit_none, options::OPT_fbackslash, options::OPT_fno_backslash, @@ -58,7 +59,8 @@ void Flang::addFortranDialectOptions(const ArgList &Args, options::OPT_fhermetic_module_files, options::OPT_frealloc_lhs, options::OPT_fno_realloc_lhs, - options::OPT_fsave_main_program}); + options::OPT_fsave_main_program, + options::OPT_fno_save_main_program}); } void Flang::addPreprocessingOptions(const ArgList &Args, @@ -344,11 +346,15 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { assert(TC.getTriple().isKnownWindowsMSVCEnvironment() && "can only add VS runtime library on Windows!"); - // if -fno-fortran-main has been passed, skip linking Fortran_main.a - if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { - CmdArgs.push_back(Args.MakeArgString( - "--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins"))); - } + + // Flang/Clang (including clang-cl) -compiled programs targeting the MSVC ABI + // should only depend on msv(u)crt. LLVM still emits libgcc/compiler-rt + // functions in some cases like 128-bit integer math (__udivti3, __modti3, + // __fixsfti, __floattidf, ...) that msvc does not support. We are injecting a + // dependency to Compiler-RT's builtin library where these are implemented. + CmdArgs.push_back(Args.MakeArgString( + "--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins"))); + unsigned RTOptionID = options::OPT__SLASH_MT; if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { RTOptionID = llvm::StringSwitch(rtl->getValue()) @@ -362,30 +368,26 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, case options::OPT__SLASH_MT: CmdArgs.push_back("-D_MT"); CmdArgs.push_back("--dependent-lib=libcmt"); - CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib"); - CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib"); + CmdArgs.push_back("--dependent-lib=flang_rt.runtime.static.lib"); break; case options::OPT__SLASH_MTd: CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("--dependent-lib=libcmtd"); - CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib"); - CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib"); + CmdArgs.push_back("--dependent-lib=flang_rt.runtime.static_dbg.lib"); break; case options::OPT__SLASH_MD: CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrt"); - CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib"); - CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib"); + CmdArgs.push_back("--dependent-lib=flang_rt.runtime.dynamic.lib"); break; case options::OPT__SLASH_MDd: CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrtd"); - CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib"); - CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib"); + CmdArgs.push_back("--dependent-lib=flang_rt.runtime.dynamic_dbg.lib"); break; } } diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp index ccee065b59064..0e50eddd6b3d2 100644 --- a/clang/lib/Driver/ToolChains/HIPAMD.cpp +++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp @@ -216,17 +216,8 @@ HIPAMDToolChain::HIPAMDToolChain(const Driver &D, const llvm::Triple &Triple, // Lookup binaries into the driver directory, this is used to // discover the clang-offload-bundler executable. getProgramPaths().push_back(getDriver().Dir); - // Diagnose unsupported sanitizer options only once. - if (!Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize, - true)) - return; - for (auto *A : Args.filtered(options::OPT_fsanitize_EQ)) { - SanitizerMask K = parseSanitizerValue(A->getValue(), /*AllowGroups=*/false); - if (K != SanitizerKind::Address) - D.getDiags().Report(clang::diag::warn_drv_unsupported_option_for_target) - << A->getAsString(Args) << getTriple().str(); - } + diagnoseUnsupportedSanitizers(Args); } void HIPAMDToolChain::addClangTargetOptions( @@ -382,7 +373,7 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { llvm::sys::path::append(Path, BCName); FullName = Path; if (llvm::sys::fs::exists(FullName)) { - BCLibs.push_back(FullName); + BCLibs.emplace_back(FullName); return; } } @@ -396,28 +387,11 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { StringRef GpuArch = getGPUArch(DriverArgs); assert(!GpuArch.empty() && "Must have an explicit GPU arch."); - // If --hip-device-lib is not set, add the default bitcode libraries. - if (DriverArgs.hasFlag(options::OPT_fgpu_sanitize, - options::OPT_fno_gpu_sanitize, true) && - getSanitizerArgs(DriverArgs).needsAsanRt()) { - auto AsanRTL = RocmInstallation->getAsanRTLPath(); - if (AsanRTL.empty()) { - unsigned DiagID = getDriver().getDiags().getCustomDiagID( - DiagnosticsEngine::Error, - "AMDGPU address sanitizer runtime library (asanrtl) is not found. " - "Please install ROCm device library which supports address " - "sanitizer"); - getDriver().Diag(DiagID); - return {}; - } else - BCLibs.emplace_back(AsanRTL, /*ShouldInternalize=*/false); - } - // Add the HIP specific bitcode library. - BCLibs.push_back(RocmInstallation->getHIPPath()); + BCLibs.emplace_back(RocmInstallation->getHIPPath()); // Add common device libraries like ocml etc. - for (StringRef N : getCommonDeviceLibNames(DriverArgs, GpuArch.str())) + for (auto N : getCommonDeviceLibNames(DriverArgs, GpuArch.str())) BCLibs.emplace_back(N); // Add instrument lib. @@ -426,7 +400,7 @@ HIPAMDToolChain::getDeviceLibs(const llvm::opt::ArgList &DriverArgs) const { if (InstLib.empty()) return BCLibs; if (llvm::sys::fs::exists(InstLib)) - BCLibs.push_back(InstLib); + BCLibs.emplace_back(InstLib); else getDriver().Diag(diag::err_drv_no_such_file) << InstLib; } diff --git a/clang/lib/Driver/ToolChains/Hexagon.cpp b/clang/lib/Driver/ToolChains/Hexagon.cpp index 76cedf312d68a..7ca5ab9af8810 100644 --- a/clang/lib/Driver/ToolChains/Hexagon.cpp +++ b/clang/lib/Driver/ToolChains/Hexagon.cpp @@ -802,9 +802,7 @@ bool HexagonToolChain::isAutoHVXEnabled(const llvm::opt::ArgList &Args) { // Returns the default CPU for Hexagon. This is the default compilation target // if no Hexagon processor is selected at the command-line. // -StringRef HexagonToolChain::GetDefaultCPU() { - return "hexagonv60"; -} +StringRef HexagonToolChain::GetDefaultCPU() { return "hexagonv68"; } StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) { Arg *CpuArg = nullptr; diff --git a/clang/lib/Driver/ToolChains/ROCm.h b/clang/lib/Driver/ToolChains/ROCm.h index dceb0ab036693..681c242b0678e 100644 --- a/clang/lib/Driver/ToolChains/ROCm.h +++ b/clang/lib/Driver/ToolChains/ROCm.h @@ -13,6 +13,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Driver/Driver.h" #include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/Option/ArgList.h" @@ -173,12 +174,11 @@ class RocmInstallationDetector { /// Get file paths of default bitcode libraries common to AMDGPU based /// toolchains. - llvm::SmallVector - getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs, - StringRef LibDeviceFile, bool Wave64, bool DAZ, - bool FiniteOnly, bool UnsafeMathOpt, - bool FastRelaxedMath, bool CorrectSqrt, - DeviceLibABIVersion ABIVer, bool isOpenMP) const; + llvm::SmallVector getCommonBitcodeLibs( + const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, + bool Wave64, bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, + bool FastRelaxedMath, bool CorrectSqrt, DeviceLibABIVersion ABIVer, + const std::tuple &GPUSan, bool isOpenMP) const; /// Check file paths of default bitcode libraries common to AMDGPU based /// toolchains. \returns false if there are invalid or missing files. bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile, diff --git a/clang/lib/Driver/ToolChains/UEFI.h b/clang/lib/Driver/ToolChains/UEFI.h index 7e038b5cb8b18..4474c2fcc6939 100644 --- a/clang/lib/Driver/ToolChains/UEFI.h +++ b/clang/lib/Driver/ToolChains/UEFI.h @@ -55,6 +55,10 @@ class LLVM_LIBRARY_VISIBILITY UEFI : public ToolChain { void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + + llvm::codegenoptions::DebugInfoFormat getDefaultDebugFormat() const override { + return llvm::codegenoptions::DIF_CodeView; + } }; } // namespace toolchains diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp index eebe3becada65..bd25fd1a8933a 100644 --- a/clang/lib/Driver/ToolChains/WebAssembly.cpp +++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -344,12 +344,15 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, } } + bool HasBannedIncompatibleOptionsForWasmEHSjLj = false; + bool HasEnabledFeaturesForWasmEHSjLj = false; + // Bans incompatible options for Wasm EH / SjLj. We don't allow using // different modes for EH and SjLj. auto BanIncompatibleOptionsForWasmEHSjLj = [&](StringRef CurOption) { - static bool HasRun = false; - if (HasRun) + if (HasBannedIncompatibleOptionsForWasmEHSjLj) return; + HasBannedIncompatibleOptionsForWasmEHSjLj = true; if (DriverArgs.hasFlag(options::OPT_mno_exception_handing, options::OPT_mexception_handing, false)) getDriver().Diag(diag::err_drv_argument_not_allowed_with) @@ -373,14 +376,13 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, << CurOption << Option; } } - HasRun = true; }; // Enable necessary features for Wasm EH / SjLj in the backend. auto EnableFeaturesForWasmEHSjLj = [&]() { - static bool HasRun = false; - if (HasRun) + if (HasEnabledFeaturesForWasmEHSjLj) return; + HasEnabledFeaturesForWasmEHSjLj = true; CC1Args.push_back("-target-feature"); CC1Args.push_back("+exception-handling"); // The standardized Wasm EH spec requires multivalue and reference-types. @@ -390,7 +392,6 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, CC1Args.push_back("+reference-types"); // Backend needs '-exception-model=wasm' to use Wasm EH instructions CC1Args.push_back("-exception-model=wasm"); - HasRun = true; }; if (DriverArgs.getLastArg(options::OPT_fwasm_exceptions)) { diff --git a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index 81797c8c4dc75..32f5ebb55155e 100644 --- a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -1085,6 +1085,7 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg, llvm_unreachable("OpenCL-specific cast in Objective-C?"); case CK_HLSLVectorTruncation: + case CK_HLSLElementwiseCast: llvm_unreachable("HLSL-specific cast in Objective-C?"); break; diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index c311deaa17bb0..3e51b4aab1082 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -356,6 +356,16 @@ bool ContinuationIndenter::canBreak(const LineState &State) { return CurrentState.BreakBeforeClosingBrace; } + // Allow breaking before the right parens with block indentation if there was + // a break after the left parens, which is tracked by BreakBeforeClosingParen. + if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && + Current.is(tok::r_paren)) { + return CurrentState.BreakBeforeClosingParen; + } + + if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser)) + return CurrentState.BreakBeforeClosingAngle; + // If binary operators are moved to the next line (including commas for some // styles of constructor initializers), that's always ok. if (!Current.isOneOf(TT_BinaryOperator, tok::comma) && @@ -407,6 +417,8 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { } if (CurrentState.BreakBeforeClosingParen && Current.is(tok::r_paren)) return true; + if (CurrentState.BreakBeforeClosingAngle && Current.is(TT_TemplateCloser)) + return true; if (Style.Language == FormatStyle::LK_ObjC && Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && @@ -1236,6 +1248,9 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State, Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent; } + if (PreviousNonComment && PreviousNonComment->is(TT_TemplateOpener)) + CurrentState.BreakBeforeClosingAngle = Style.BreakBeforeTemplateCloser; + if (CurrentState.AvoidBinPacking) { // If we are breaking after '(', '{', '<', or this is the break after a ':' // to start a member initializer list in a constructor, this should not @@ -1372,6 +1387,10 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) { State.Stack.size() > 1) { return State.Stack[State.Stack.size() - 2].LastSpace; } + if (Style.BreakBeforeTemplateCloser && Current.is(TT_TemplateCloser) && + State.Stack.size() > 1) { + return State.Stack[State.Stack.size() - 2].LastSpace; + } if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope()) return State.Stack[State.Stack.size() - 2].LastSpace; // Field labels in a nested type should be aligned to the brace. For example diff --git a/clang/lib/Format/ContinuationIndenter.h b/clang/lib/Format/ContinuationIndenter.h index 18441e10a1249..ac354aa96f86e 100644 --- a/clang/lib/Format/ContinuationIndenter.h +++ b/clang/lib/Format/ContinuationIndenter.h @@ -200,14 +200,15 @@ struct ParenState { : Tok(Tok), Indent(Indent), LastSpace(LastSpace), NestedBlockIndent(Indent), IsAligned(false), BreakBeforeClosingBrace(false), BreakBeforeClosingParen(false), - AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false), - NoLineBreak(NoLineBreak), NoLineBreakInOperand(false), - LastOperatorWrapped(true), ContainsLineBreak(false), - ContainsUnwrappedBuilder(false), AlignColons(true), - ObjCSelectorNameFound(false), HasMultipleNestedBlocks(false), - NestedBlockInlined(false), IsInsideObjCArrayLiteral(false), - IsCSharpGenericTypeConstraint(false), IsChainedConditional(false), - IsWrappedConditional(false), UnindentOperator(false) {} + BreakBeforeClosingAngle(false), AvoidBinPacking(AvoidBinPacking), + BreakBeforeParameter(false), NoLineBreak(NoLineBreak), + NoLineBreakInOperand(false), LastOperatorWrapped(true), + ContainsLineBreak(false), ContainsUnwrappedBuilder(false), + AlignColons(true), ObjCSelectorNameFound(false), + HasMultipleNestedBlocks(false), NestedBlockInlined(false), + IsInsideObjCArrayLiteral(false), IsCSharpGenericTypeConstraint(false), + IsChainedConditional(false), IsWrappedConditional(false), + UnindentOperator(false) {} /// \brief The token opening this parenthesis level, or nullptr if this level /// is opened by fake parenthesis. @@ -280,6 +281,9 @@ struct ParenState { /// was a newline after the beginning left paren. bool BreakBeforeClosingParen : 1; + /// Whether a newline needs to be inserted before a closing angle `>`. + bool BreakBeforeClosingAngle : 1; + /// Avoid bin packing, i.e. multiple parameters/elements on multiple /// lines, in this context. bool AvoidBinPacking : 1; @@ -367,6 +371,8 @@ struct ParenState { return BreakBeforeClosingBrace; if (BreakBeforeClosingParen != Other.BreakBeforeClosingParen) return BreakBeforeClosingParen; + if (BreakBeforeClosingAngle != Other.BreakBeforeClosingAngle) + return BreakBeforeClosingAngle; if (QuestionColumn != Other.QuestionColumn) return QuestionColumn < Other.QuestionColumn; if (AvoidBinPacking != Other.AvoidBinPacking) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index c25d9bf7c2251..0898b69528ebc 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -995,6 +995,7 @@ template <> struct MappingTraits { Style.AlwaysBreakBeforeMultilineStrings); IO.mapOptional("AttributeMacros", Style.AttributeMacros); IO.mapOptional("BinPackArguments", Style.BinPackArguments); + IO.mapOptional("BinPackLongBracedList", Style.BinPackLongBracedList); IO.mapOptional("BinPackParameters", Style.BinPackParameters); IO.mapOptional("BitFieldColonSpacing", Style.BitFieldColonSpacing); IO.mapOptional("BracedInitializerIndentWidth", @@ -1014,6 +1015,8 @@ template <> struct MappingTraits { IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); IO.mapOptional("BreakBeforeInlineASMColon", Style.BreakBeforeInlineASMColon); + IO.mapOptional("BreakBeforeTemplateCloser", + Style.BreakBeforeTemplateCloser); IO.mapOptional("BreakBeforeTernaryOperators", Style.BreakBeforeTernaryOperators); IO.mapOptional("BreakBinaryOperations", Style.BreakBinaryOperations); @@ -1091,6 +1094,8 @@ template <> struct MappingTraits { IO.mapOptional("PenaltyBreakAssignment", Style.PenaltyBreakAssignment); IO.mapOptional("PenaltyBreakBeforeFirstCallParameter", Style.PenaltyBreakBeforeFirstCallParameter); + IO.mapOptional("PenaltyBreakBeforeMemberAccess", + Style.PenaltyBreakBeforeMemberAccess); IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment); IO.mapOptional("PenaltyBreakFirstLessLess", Style.PenaltyBreakFirstLessLess); @@ -1503,6 +1508,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; LLVMStyle.AttributeMacros.push_back("__capability"); LLVMStyle.BinPackArguments = true; + LLVMStyle.BinPackLongBracedList = true; LLVMStyle.BinPackParameters = FormatStyle::BPPS_BinPack; LLVMStyle.BitFieldColonSpacing = FormatStyle::BFCS_Both; LLVMStyle.BracedInitializerIndentWidth = std::nullopt; @@ -1533,6 +1539,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always; LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline; + LLVMStyle.BreakBeforeTemplateCloser = false; LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakBinaryOperations = FormatStyle::BBO_Never; LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon; @@ -1659,6 +1666,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { LLVMStyle.PenaltyBreakAssignment = prec::Assignment; LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19; + LLVMStyle.PenaltyBreakBeforeMemberAccess = 150; LLVMStyle.PenaltyBreakComment = 300; LLVMStyle.PenaltyBreakFirstLessLess = 120; LLVMStyle.PenaltyBreakOpenParenthesis = 0; diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp index 963e8f87793fa..fb040a0043602 100644 --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -42,11 +42,12 @@ static SmallVector CppNonKeywordTypes = { }; bool FormatToken::isTypeName(const LangOptions &LangOpts) const { + if (is(TT_TypeName) || Tok.isSimpleTypeSpecifier(LangOpts)) + return true; const bool IsCpp = LangOpts.CXXOperatorNames; - return is(TT_TypeName) || Tok.isSimpleTypeSpecifier(LangOpts) || - (IsCpp && is(tok::identifier) && - std::binary_search(CppNonKeywordTypes.begin(), - CppNonKeywordTypes.end(), TokenText)); + return IsCpp && is(tok::identifier) && + std::binary_search(CppNonKeywordTypes.begin(), + CppNonKeywordTypes.end(), TokenText); } bool FormatToken::isTypeOrIdentifier(const LangOptions &LangOpts) const { @@ -174,7 +175,7 @@ void CommaSeparatedList::precomputeFormattingInfos(const FormatToken *Token) { // have many items (20 or more) or we allow bin-packing of function call // arguments. if (Style.Cpp11BracedListStyle && !Style.BinPackArguments && - Commas.size() < 19) { + (Commas.size() < 19 || !Style.BinPackLongBracedList)) { return; } diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index d97b6522f1fef..29aba281ae103 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -44,6 +44,8 @@ namespace format { TYPE(CaseLabelColon) \ TYPE(CastRParen) \ TYPE(ClassLBrace) \ + /* Name of class/struct/union/interface definition. */ \ + TYPE(ClassHeadName) \ TYPE(ClassRBrace) \ TYPE(CompoundRequirementLBrace) \ /* ternary ?: expression */ \ diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp b/clang/lib/Format/QualifierAlignmentFixer.cpp index 21fb5074b4928..23e8b44eee15c 100644 --- a/clang/lib/Format/QualifierAlignmentFixer.cpp +++ b/clang/lib/Format/QualifierAlignmentFixer.cpp @@ -132,8 +132,10 @@ static void rotateTokens(const SourceManager &SourceMgr, // Then move through the other tokens. auto *Tok = Begin; while (Tok != End) { - if (!NewText.empty() && !endsWithSpace(NewText)) + if (!NewText.empty() && !endsWithSpace(NewText) && + Tok->isNot(tok::coloncolon)) { NewText += " "; + } NewText += Tok->TokenText; Tok = Tok->Next; @@ -412,6 +414,14 @@ const FormatToken *LeftRightQualifierAlignmentFixer::analyzeLeft( // The case `const long long volatile int` -> `const volatile long long int` // The case `long volatile long int const` -> `const volatile long long int` if (TypeToken->isTypeName(LangOpts)) { + for (const auto *Prev = TypeToken->Previous; + Prev && Prev->is(tok::coloncolon); Prev = Prev->Previous) { + TypeToken = Prev; + Prev = Prev->Previous; + if (!(Prev && Prev->is(tok::identifier))) + break; + TypeToken = Prev; + } const FormatToken *LastSimpleTypeSpecifier = TypeToken; while (isConfiguredQualifierOrType( LastSimpleTypeSpecifier->getPreviousNonComment(), diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index f36cf7b638e0d..b3540f39e6f69 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -252,10 +252,10 @@ class AnnotatingParser { // parameters. // FIXME: This is getting out of hand, write a decent parser. if (MaybeAngles && InExpr && !Line.startsWith(tok::kw_template) && - Prev.is(TT_BinaryOperator)) { - const auto Precedence = Prev.getPrecedence(); - if (Precedence > prec::Conditional && Precedence < prec::Relational) - MaybeAngles = false; + Prev.is(TT_BinaryOperator) && + (Prev.isOneOf(tok::pipepipe, tok::ampamp) || + Prev.getPrecedence() == prec::Equality)) { + MaybeAngles = false; } if (Prev.isOneOf(tok::question, tok::colon) && !Style.isProto()) SeenTernaryOperator = true; @@ -477,8 +477,9 @@ class AnnotatingParser { FormatToken *PossibleObjCForInToken = nullptr; while (CurrentToken) { const auto &Prev = *CurrentToken->Previous; + const auto *PrevPrev = Prev.Previous; if (Prev.is(TT_PointerOrReference) && - Prev.Previous->isOneOf(tok::l_paren, tok::coloncolon)) { + PrevPrev->isOneOf(tok::l_paren, tok::coloncolon)) { ProbablyFunctionType = true; } if (CurrentToken->is(tok::comma)) @@ -486,8 +487,10 @@ class AnnotatingParser { if (Prev.is(TT_BinaryOperator)) Contexts.back().IsExpression = true; if (CurrentToken->is(tok::r_paren)) { - if (Prev.is(TT_PointerOrReference) && Prev.Previous == &OpeningParen) + if (Prev.is(TT_PointerOrReference) && + (PrevPrev == &OpeningParen || PrevPrev->is(tok::coloncolon))) { MightBeFunctionType = true; + } if (OpeningParen.isNot(TT_CppCastLParen) && MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next && (CurrentToken->Next->is(tok::l_paren) || @@ -1115,7 +1118,7 @@ class AnnotatingParser { } if (!CurrentToken || CurrentToken->isNot(tok::l_paren)) return false; - skipToNextNonComment(); + next(); // FIXME: Hack using inheritance to child context Contexts.back().IsTableGenBangOpe = true; bool Result = parseParens(); @@ -1124,12 +1127,10 @@ class AnnotatingParser { } // SimpleValue 9: Cond operator if (Tok->is(TT_TableGenCondOperator)) { - Tok = CurrentToken; - skipToNextNonComment(); - if (!Tok || Tok->isNot(tok::l_paren)) + if (!CurrentToken || CurrentToken->isNot(tok::l_paren)) return false; - bool Result = parseParens(); - return Result; + next(); + return parseParens(); } // We have to check identifier at the last because the kind of bang/cond // operators are also identifier. @@ -1567,7 +1568,8 @@ class AnnotatingParser { if (const auto *Previous = Tok->Previous; !Previous || (!Previous->isAttribute() && - !Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation))) { + !Previous->isOneOf(TT_RequiresClause, TT_LeadingJavaAnnotation, + TT_BinaryOperator))) { Line.MightBeFunctionDecl = true; Tok->MightBeFunctionDeclParen = true; } @@ -2582,9 +2584,14 @@ class AnnotatingParser { if (Style.isVerilog()) return false; - if (Tok.isNot(tok::identifier) || !Tok.Previous) + if (!Tok.Previous || Tok.isNot(tok::identifier) || Tok.is(TT_ClassHeadName)) return false; + if ((Style.isJavaScript() || Style.Language == FormatStyle::LK_Java) && + Tok.is(Keywords.kw_extends)) { + return false; + } + if (const auto *NextNonComment = Tok.getNextNonComment(); (!NextNonComment && !Line.InMacroBody) || (NextNonComment && @@ -3784,7 +3791,7 @@ static bool isFunctionDeclarationName(const LangOptions &LangOpts, return Next; if (Next->is(TT_OverloadedOperator)) continue; - if (Next->isOneOf(tok::kw_new, tok::kw_delete)) { + if (Next->isOneOf(tok::kw_new, tok::kw_delete, tok::kw_co_await)) { // For 'new[]' and 'delete[]'. if (Next->Next && Next->Next->startsSequence(tok::l_square, tok::r_square)) { @@ -4315,9 +4322,11 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, // // aaaaaaa // .aaaaaaaaa.bbbbbbbb(cccccccc); - return !Right.NextOperator || !Right.NextOperator->Previous->closesScope() - ? 150 - : 35; + const auto *NextOperator = Right.NextOperator; + const auto Penalty = Style.PenaltyBreakBeforeMemberAccess; + return NextOperator && NextOperator->Previous->closesScope() + ? std::min(Penalty, 35u) + : Penalty; } if (Right.is(TT_TrailingAnnotation) && @@ -6174,6 +6183,9 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, return false; } + if (Right.is(TT_TemplateCloser)) + return Style.BreakBeforeTemplateCloser; + if (Left.is(tok::at)) return false; if (Left.Tok.getObjCKeywordID() == tok::objc_interface) @@ -6322,8 +6334,6 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, if (Right.is(TT_ImplicitStringLiteral)) return false; - if (Right.is(TT_TemplateCloser)) - return false; if (Right.is(tok::r_square) && Right.MatchingParen && Right.MatchingParen->is(TT_LambdaLSquare)) { return false; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 4258329136348..4e040183f2f0a 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3632,7 +3632,7 @@ void UnwrappedLineParser::parseRequiresClause(FormatToken *RequiresToken) { // It could be inlined into here. parseConstraintExpression(); - if (!InRequiresExpression) + if (!InRequiresExpression && FormatTok->Previous) FormatTok->Previous->ClosesRequiresClause = true; } @@ -4029,7 +4029,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { const FormatToken &InitialToken = *FormatTok; nextToken(); - const FormatToken *ClassName = nullptr; + FormatToken *ClassName = nullptr; bool IsDerived = false; auto IsNonMacroIdentifier = [](const FormatToken *Tok) { return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper(); @@ -4059,7 +4059,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { } if (FormatTok->is(tok::l_square) && handleCppAttributes()) continue; - const auto *Previous = FormatTok; + auto *Previous = FormatTok; nextToken(); switch (FormatTok->Tok.getKind()) { case tok::l_paren: @@ -4074,8 +4074,12 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { case tok::hashhash: break; default: - if (!JSPastExtendsOrImplements && !ClassName && - Previous->is(tok::identifier) && Previous->isNot(TT_AttributeMacro)) { + if (JSPastExtendsOrImplements || ClassName || + Previous->isNot(tok::identifier) || Previous->is(TT_AttributeMacro)) { + break; + } + if (const auto Text = Previous->TokenText; + Text.size() == 1 || Text != Text.upper()) { ClassName = Previous; } } @@ -4102,7 +4106,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { if (AngleNestingLevel == 0) { if (FormatTok->is(tok::colon)) { IsDerived = true; - } else if (FormatTok->is(tok::identifier) && + } else if (!IsDerived && FormatTok->is(tok::identifier) && FormatTok->Previous->is(tok::coloncolon)) { ClassName = FormatTok; } else if (FormatTok->is(tok::l_paren) && @@ -4159,6 +4163,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { if (FormatTok->is(tok::l_brace)) { if (IsListInitialization()) return; + if (ClassName) + ClassName->setFinalizedType(TT_ClassHeadName); auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken); FormatTok->setFinalizedType(OpenBraceType); if (ParseAsExpr) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3bf124e4827be..014e629c959e2 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1665,6 +1665,11 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1) GenerateArg(Consumer, OPT_fno_unroll_loops); + if (Opts.InterchangeLoops) + GenerateArg(Consumer, OPT_floop_interchange); + else + GenerateArg(Consumer, OPT_fno_loop_interchange); + if (!Opts.BinutilsVersion.empty()) GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion); @@ -1843,6 +1848,9 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts, GenerateArg(Consumer, OPT_fno_finite_loops); break; } + + if (Opts.StaticClosure) + GenerateArg(Consumer, OPT_static_libclosure); } bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, @@ -1968,6 +1976,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, Opts.UnrollLoops = Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops, (Opts.OptimizationLevel > 1)); + Opts.InterchangeLoops = + Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, false); Opts.BinutilsVersion = std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ)); @@ -2330,6 +2340,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs) Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans); + Opts.StaticClosure = Args.hasArg(options::OPT_static_libclosure); + return Diags.getNumErrors() == NumErrorsBefore; } @@ -2756,7 +2768,6 @@ static const auto &getFrontendActionTable() { {frontend::RewriteObjC, OPT_rewrite_objc}, {frontend::RewriteTest, OPT_rewrite_test}, {frontend::RunAnalysis, OPT_analyze}, - {frontend::MigrateSource, OPT_migrate}, {frontend::RunPreprocessorOnly, OPT_Eonly}, {frontend::PrintDependencyDirectivesSourceMinimizerOutput, OPT_print_dependency_directives_minimized_source}, @@ -3099,12 +3110,6 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_aux_target_feature)) Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature); - if (Opts.ARCMTAction != FrontendOptions::ARCMT_None && - Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) { - Diags.Report(diag::err_drv_argument_not_allowed_with) - << "ARC migration" << "ObjC migration"; - } - InputKind DashX(Language::Unknown); if (const Arg *A = Args.getLastArg(OPT_x)) { StringRef XValue = A->getValue(); @@ -3721,6 +3726,8 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) { GenerateArg(Consumer, OPT_fwrapv); } + if (Opts.PointerOverflowDefined) + GenerateArg(Consumer, OPT_fwrapv_pointer); if (Opts.MSCompatibilityVersion != 0) { unsigned Major = Opts.MSCompatibilityVersion / 10000000; @@ -3893,6 +3900,9 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, case LangOptions::ClangABI::Ver19: GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0"); break; + case LangOptions::ClangABI::Ver20: + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "20.0"); + break; case LangOptions::ClangABI::Latest: break; } @@ -4138,6 +4148,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, } else if (Args.hasArg(OPT_fwrapv)) Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); + if (Args.hasArg(OPT_fwrapv_pointer)) + Opts.PointerOverflowDefined = true; Opts.MSCompatibilityVersion = 0; if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) { @@ -4211,7 +4223,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, } } - // Check if -fopenmp is specified and set default version to 5.0. + // Check if -fopenmp is specified and set default version to 5.1. Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0; // Check if -fopenmp-simd is specified. bool IsSimdSpecified = @@ -4409,7 +4421,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, // y or y.0 (4 <= y <= current version). if (!VerParts.first.starts_with("0") && !VerParts.first.getAsInteger(10, Major) && 3 <= Major && - Major <= CLANG_VERSION_MAJOR && + Major <= MAX_CLANG_ABI_COMPAT_VERSION && (Major == 3 ? VerParts.second.size() == 1 && !VerParts.second.getAsInteger(10, Minor) @@ -4635,7 +4647,6 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::RewriteTest: case frontend::RunAnalysis: case frontend::TemplightDump: - case frontend::MigrateSource: return false; case frontend::DumpCompilerOptions: diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 29723b573e771..77833f5d1defb 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -253,6 +253,8 @@ static void DefineExactWidthIntType(const LangOptions &LangOpts, StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty)); Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix); + Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C(c)", + ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c"); } static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty, @@ -727,8 +729,8 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, } if (LangOpts.AlignedAllocation && !LangOpts.AlignedAllocationUnavailable) Builder.defineMacro("__cpp_aligned_new", "201606L"); - if (LangOpts.RelaxedTemplateTemplateArgs) - Builder.defineMacro("__cpp_template_template_args", "201611L"); + + Builder.defineMacro("__cpp_template_template_args", "201611L"); // C++20 features. if (LangOpts.CPlusPlus20) { @@ -1164,12 +1166,16 @@ static void InitializePredefinedMacros(const TargetInfo &TI, DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder); DefineFmt(LangOpts, "__INTMAX", TI.getIntMaxType(), TI, Builder); - Builder.defineMacro("__INTMAX_C_SUFFIX__", - TI.getTypeConstantSuffix(TI.getIntMaxType())); + StringRef ConstSuffix(TI.getTypeConstantSuffix(TI.getIntMaxType())); + Builder.defineMacro("__INTMAX_C_SUFFIX__", ConstSuffix); + Builder.defineMacro("__INTMAX_C(c)", + ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c"); DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder); DefineFmt(LangOpts, "__UINTMAX", TI.getUIntMaxType(), TI, Builder); - Builder.defineMacro("__UINTMAX_C_SUFFIX__", - TI.getTypeConstantSuffix(TI.getUIntMaxType())); + ConstSuffix = TI.getTypeConstantSuffix(TI.getUIntMaxType()); + Builder.defineMacro("__UINTMAX_C_SUFFIX__", ConstSuffix); + Builder.defineMacro("__UINTMAX_C(c)", + ConstSuffix.size() ? Twine("c##") + ConstSuffix : "c"); DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder); DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI, Builder); @@ -1460,9 +1466,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI, case 50: Builder.defineMacro("_OPENMP", "201811"); break; + case 51: + Builder.defineMacro("_OPENMP", "202011"); + break; case 52: Builder.defineMacro("_OPENMP", "202111"); break; + case 60: + Builder.defineMacro("_OPENMP", "202411"); + break; default: // case 51: // Default version is OpenMP 5.1 Builder.defineMacro("_OPENMP", "202011"); diff --git a/clang/lib/Frontend/LogDiagnosticPrinter.cpp b/clang/lib/Frontend/LogDiagnosticPrinter.cpp index 469d1c22633aa..4e963af837f01 100644 --- a/clang/lib/Frontend/LogDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/LogDiagnosticPrinter.cpp @@ -129,7 +129,8 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level, DE.DiagnosticLevel = Level; DE.WarningOption = - std::string(DiagnosticIDs::getWarningOptionForDiag(DE.DiagnosticID)); + std::string(Info.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag( + DE.DiagnosticID)); // Format the message. SmallString<100> MessageStr; @@ -160,4 +161,3 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level, // Record the diagnostic entry. Entries.push_back(DE); } - diff --git a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp index 0887b5a504f05..02aa3e8e4d984 100644 --- a/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -202,7 +202,7 @@ class SDiagsWriter : public DiagnosticConsumer { /// Emit the string information for diagnostic flags. unsigned getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel, - unsigned DiagID = 0); + const Diagnostic *Diag = nullptr); unsigned getEmitDiagnosticFlag(StringRef DiagName); @@ -536,11 +536,13 @@ unsigned SDiagsWriter::getEmitCategory(unsigned int category) { } unsigned SDiagsWriter::getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel, - unsigned DiagID) { - if (DiagLevel == DiagnosticsEngine::Note) + const Diagnostic *Diag) { + if (!Diag || DiagLevel == DiagnosticsEngine::Note) return 0; // No flag for notes. - StringRef FlagName = DiagnosticIDs::getWarningOptionForDiag(DiagID); + StringRef FlagName = + Diag->getDiags()->getDiagnosticIDs()->getWarningOptionForDiag( + Diag->getID()); return getEmitDiagnosticFlag(FlagName); } @@ -650,12 +652,12 @@ void SDiagsWriter::EmitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc, Record.push_back(getStableLevel(Level)); AddLocToRecord(Loc, PLoc, Record); - if (const Diagnostic *Info = D.dyn_cast()) { + if (const Diagnostic *Info = dyn_cast_if_present(D)) { // Emit the category string lazily and get the category ID. unsigned DiagID = DiagnosticIDs::getCategoryNumberForDiag(Info->getID()); Record.push_back(getEmitCategory(DiagID)); // Emit the diagnostic flag string lazily and get the mapped ID. - Record.push_back(getEmitDiagnosticFlag(Level, Info->getID())); + Record.push_back(getEmitDiagnosticFlag(Level, Info)); } else { Record.push_back(getEmitCategory()); Record.push_back(getEmitDiagnosticFlag(Level)); diff --git a/clang/lib/Frontend/TextDiagnosticPrinter.cpp b/clang/lib/Frontend/TextDiagnosticPrinter.cpp index dac5c44fe9256..28f7218dc23f5 100644 --- a/clang/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/clang/lib/Frontend/TextDiagnosticPrinter.cpp @@ -70,13 +70,17 @@ static void printDiagnosticOptions(raw_ostream &OS, // flag it as such. Note that diagnostics could also have been mapped by a // pragma, but we don't currently have a way to distinguish this. if (Level == DiagnosticsEngine::Error && - DiagnosticIDs::isBuiltinWarningOrExtension(Info.getID()) && - !DiagnosticIDs::isDefaultMappingAsError(Info.getID())) { + Info.getDiags()->getDiagnosticIDs()->isWarningOrExtension( + Info.getID()) && + !Info.getDiags()->getDiagnosticIDs()->isDefaultMappingAsError( + Info.getID())) { OS << " [-Werror"; Started = true; } - StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID()); + StringRef Opt = + Info.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag( + Info.getID()); if (!Opt.empty()) { OS << (Started ? "," : " [") << (Level == DiagnosticsEngine::Remark ? "-R" : "-W") << Opt; diff --git a/clang/lib/FrontendTool/CMakeLists.txt b/clang/lib/FrontendTool/CMakeLists.txt index bfc7652b4c118..d7a3699361f0a 100644 --- a/clang/lib/FrontendTool/CMakeLists.txt +++ b/clang/lib/FrontendTool/CMakeLists.txt @@ -21,12 +21,6 @@ if(CLANG_ENABLE_CIR) ) endif() -if(CLANG_ENABLE_ARCMT) - list(APPEND link_libs - clangARCMigrate - ) -endif() - if(CLANG_ENABLE_STATIC_ANALYZER) list(APPEND link_libs clangStaticAnalyzerFrontend diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 3f95a1efb2eed..c8d004163b96d 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -11,7 +11,6 @@ // //===----------------------------------------------------------------------===// -#include "clang/ARCMigrate/ARCMTActions.h" #include "clang/CodeGen/CodeGenAction.h" #include "clang/Config/config.h" #include "clang/Driver/Options.h" @@ -72,7 +71,13 @@ CreateFrontendBaseAction(CompilerInstance &CI) { llvm_unreachable("CIR suppport not built into clang"); #endif case EmitHTML: return std::make_unique(); - case EmitLLVM: return std::make_unique(); + case EmitLLVM: { +#if CLANG_ENABLE_CIR + if (UseCIR) + return std::make_unique(); +#endif + return std::make_unique(); + } case EmitLLVMOnly: return std::make_unique(); case EmitCodeGenOnly: return std::make_unique(); case EmitObj: return std::make_unique(); @@ -131,12 +136,6 @@ CreateFrontendBaseAction(CompilerInstance &CI) { #else case RewriteObjC: Action = "RewriteObjC"; break; #endif -#if CLANG_ENABLE_ARCMT - case MigrateSource: - return std::make_unique(); -#else - case MigrateSource: Action = "MigrateSource"; break; -#endif #if CLANG_ENABLE_STATIC_ANALYZER case RunAnalysis: return std::make_unique(); #else @@ -147,8 +146,7 @@ CreateFrontendBaseAction(CompilerInstance &CI) { return std::make_unique(); } -#if !CLANG_ENABLE_ARCMT || !CLANG_ENABLE_STATIC_ANALYZER \ - || !CLANG_ENABLE_OBJC_REWRITER +#if !CLANG_ENABLE_STATIC_ANALYZER || !CLANG_ENABLE_OBJC_REWRITER CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action; return 0; #else @@ -169,35 +167,6 @@ CreateFrontendAction(CompilerInstance &CI) { Act = std::make_unique(std::move(Act)); } -#if CLANG_ENABLE_ARCMT - if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource && - CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) { - // Potentially wrap the base FE action in an ARC Migrate Tool action. - switch (FEOpts.ARCMTAction) { - case FrontendOptions::ARCMT_None: - break; - case FrontendOptions::ARCMT_Check: - Act = std::make_unique(std::move(Act)); - break; - case FrontendOptions::ARCMT_Modify: - Act = std::make_unique(std::move(Act)); - break; - case FrontendOptions::ARCMT_Migrate: - Act = std::make_unique(std::move(Act), - FEOpts.MTMigrateDir, - FEOpts.ARCMTMigrateReportOut, - FEOpts.ARCMTMigrateEmitARCErrors); - break; - } - - if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) { - Act = std::make_unique(std::move(Act), - FEOpts.MTMigrateDir, - FEOpts.ObjCMTAction); - } - } -#endif - // Wrap the base FE action in an extract api action to generate // symbol graph as a biproduct of compilation (enabled with // --emit-symbol-graph option) diff --git a/clang/lib/Headers/amdgpuintrin.h b/clang/lib/Headers/amdgpuintrin.h index 720674a85f52c..9dad99ffe9439 100644 --- a/clang/lib/Headers/amdgpuintrin.h +++ b/clang/lib/Headers/amdgpuintrin.h @@ -145,29 +145,33 @@ _DEFAULT_FN_ATTRS static __inline__ void __gpu_sync_lane(uint64_t __lane_mask) { // Shuffles the the lanes inside the wavefront according to the given index. _DEFAULT_FN_ATTRS static __inline__ uint32_t -__gpu_shuffle_idx_u32(uint64_t __lane_mask, uint32_t __idx, uint32_t __x) { - return __builtin_amdgcn_ds_bpermute(__idx << 2, __x); +__gpu_shuffle_idx_u32(uint64_t __lane_mask, uint32_t __idx, uint32_t __x, + uint32_t __width) { + uint32_t __lane = __idx + (__gpu_lane_id() & ~(__width - 1)); + return __builtin_amdgcn_ds_bpermute(__lane << 2, __x); } // Shuffles the the lanes inside the wavefront according to the given index. _DEFAULT_FN_ATTRS static __inline__ uint64_t -__gpu_shuffle_idx_u64(uint64_t __lane_mask, uint32_t __idx, uint64_t __x) { +__gpu_shuffle_idx_u64(uint64_t __lane_mask, uint32_t __idx, uint64_t __x, + uint32_t __width) { uint32_t __hi = (uint32_t)(__x >> 32ull); uint32_t __lo = (uint32_t)(__x & 0xFFFFFFFF); - return ((uint64_t)__builtin_amdgcn_ds_bpermute(__idx << 2, __hi) << 32ull) | - ((uint64_t)__builtin_amdgcn_ds_bpermute(__idx << 2, __lo)); + return ((uint64_t)__gpu_shuffle_idx_u32(__lane_mask, __idx, __hi, __width) + << 32ull) | + ((uint64_t)__gpu_shuffle_idx_u32(__lane_mask, __idx, __lo, __width)); } -// Returns true if the flat pointer points to CUDA 'shared' memory. +// Returns true if the flat pointer points to AMDGPU 'shared' memory. _DEFAULT_FN_ATTRS static __inline__ bool __gpu_is_ptr_local(void *ptr) { - return __builtin_amdgcn_is_shared((void __attribute__((address_space(0))) *)(( + return __builtin_amdgcn_is_shared((void [[clang::address_space(0)]] *)(( void [[clang::opencl_generic]] *)ptr)); } -// Returns true if the flat pointer points to CUDA 'local' memory. +// Returns true if the flat pointer points to AMDGPU 'private' memory. _DEFAULT_FN_ATTRS static __inline__ bool __gpu_is_ptr_private(void *ptr) { - return __builtin_amdgcn_is_private((void __attribute__(( - address_space(0))) *)((void [[clang::opencl_generic]] *)ptr)); + return __builtin_amdgcn_is_private((void [[clang::address_space(0)]] *)(( + void [[clang::opencl_generic]] *)ptr)); } // Terminates execution of the associated wavefront. diff --git a/clang/lib/Headers/amxtf32transposeintrin.h b/clang/lib/Headers/amxtf32transposeintrin.h index 60336f953ecb7..e1b90c1adfb22 100644 --- a/clang/lib/Headers/amxtf32transposeintrin.h +++ b/clang/lib/Headers/amxtf32transposeintrin.h @@ -8,7 +8,7 @@ */ #ifndef __IMMINTRIN_H #error \ - "Never use directly; include instead." + "Never use directly; include instead." #endif // __IMMINTRIN_H #ifndef __AMX_TF32TRANSPOSEINTRIN_H diff --git a/clang/lib/Headers/avx10_2_512convertintrin.h b/clang/lib/Headers/avx10_2_512convertintrin.h index 0b5fca5cda522..516ccc68672d6 100644 --- a/clang/lib/Headers/avx10_2_512convertintrin.h +++ b/clang/lib/Headers/avx10_2_512convertintrin.h @@ -213,19 +213,19 @@ _mm512_maskz_cvts2ph_hf8(__mmask64 __U, __m512h __A, __m512h __B) { (__v64qi)(__m512i)_mm512_setzero_si512()); } -static __inline__ __m512h __DEFAULT_FN_ATTRS512 _mm512_cvthf8(__m256i __A) { +static __inline__ __m512h __DEFAULT_FN_ATTRS512 _mm512_cvthf8_ph(__m256i __A) { return (__m512h)__builtin_ia32_vcvthf8_2ph512_mask( (__v32qi)__A, (__v32hf)(__m512h)_mm512_undefined_ph(), (__mmask32)-1); } static __inline__ __m512h __DEFAULT_FN_ATTRS512 -_mm512_mask_cvthf8(__m512h __W, __mmask32 __U, __m256i __A) { +_mm512_mask_cvthf8_ph(__m512h __W, __mmask32 __U, __m256i __A) { return (__m512h)__builtin_ia32_vcvthf8_2ph512_mask( (__v32qi)__A, (__v32hf)(__m512h)__W, (__mmask32)__U); } static __inline__ __m512h __DEFAULT_FN_ATTRS512 -_mm512_maskz_cvthf8(__mmask32 __U, __m256i __A) { +_mm512_maskz_cvthf8_ph(__mmask32 __U, __m256i __A) { return (__m512h)__builtin_ia32_vcvthf8_2ph512_mask( (__v32qi)__A, (__v32hf)(__m512h)_mm512_setzero_ph(), (__mmask32)__U); } diff --git a/clang/lib/Headers/avx10_2convertintrin.h b/clang/lib/Headers/avx10_2convertintrin.h index c67a5b890f195..07722090c30ee 100644 --- a/clang/lib/Headers/avx10_2convertintrin.h +++ b/clang/lib/Headers/avx10_2convertintrin.h @@ -260,13 +260,13 @@ static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_cvt2ph_bf8(__m256h __A, static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_mask_cvt2ph_bf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvt2ph_bf8(__A, __B), (__v32qi)__W); + (__mmask32)__U, (__v32qi)_mm256_cvt2ph_bf8(__A, __B), (__v32qi)__W); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_maskz_cvt2ph_bf8(__mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvt2ph_bf8(__A, __B), + (__mmask32)__U, (__v32qi)_mm256_cvt2ph_bf8(__A, __B), (__v32qi)(__m256i)_mm256_setzero_si256()); } @@ -297,13 +297,13 @@ _mm256_cvts2ph_bf8(__m256h __A, __m256h __B) { static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_mask_cvts2ph_bf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvts2ph_bf8(__A, __B), (__v32qi)__W); + (__mmask32)__U, (__v32qi)_mm256_cvts2ph_bf8(__A, __B), (__v32qi)__W); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_maskz_cvts2ph_bf8(__mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvts2ph_bf8(__A, __B), + (__mmask32)__U, (__v32qi)_mm256_cvts2ph_bf8(__A, __B), (__v32qi)(__m256i)_mm256_setzero_si256()); } @@ -334,13 +334,13 @@ static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_cvt2ph_hf8(__m256h __A, static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_mask_cvt2ph_hf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvt2ph_hf8(__A, __B), (__v32qi)__W); + (__mmask32)__U, (__v32qi)_mm256_cvt2ph_hf8(__A, __B), (__v32qi)__W); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_maskz_cvt2ph_hf8(__mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvt2ph_hf8(__A, __B), + (__mmask32)__U, (__v32qi)_mm256_cvt2ph_hf8(__A, __B), (__v32qi)(__m256i)_mm256_setzero_si256()); } @@ -371,47 +371,46 @@ _mm256_cvts2ph_hf8(__m256h __A, __m256h __B) { static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_mask_cvts2ph_hf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvts2ph_hf8(__A, __B), (__v32qi)__W); + (__mmask32)__U, (__v32qi)_mm256_cvts2ph_hf8(__A, __B), (__v32qi)__W); } static __inline__ __m256i __DEFAULT_FN_ATTRS256 _mm256_maskz_cvts2ph_hf8(__mmask32 __U, __m256h __A, __m256h __B) { return (__m256i)__builtin_ia32_selectb_256( - (__mmask16)__U, (__v32qi)_mm256_cvts2ph_hf8(__A, __B), + (__mmask32)__U, (__v32qi)_mm256_cvts2ph_hf8(__A, __B), (__v32qi)(__m256i)_mm256_setzero_si256()); } -static __inline__ __m128h __DEFAULT_FN_ATTRS128 _mm_cvthf8(__m128i __A) { +static __inline__ __m128h __DEFAULT_FN_ATTRS128 _mm_cvthf8_ph(__m128i __A) { return (__m128h)__builtin_ia32_vcvthf8_2ph128_mask( (__v16qi)__A, (__v8hf)(__m128h)_mm_undefined_ph(), (__mmask8)-1); } -static __inline__ __m128h __DEFAULT_FN_ATTRS128 _mm_mask_cvthf8(__m128h __W, - __mmask8 __U, - __m128i __A) { +static __inline__ __m128h __DEFAULT_FN_ATTRS128 +_mm_mask_cvthf8_ph(__m128h __W, __mmask8 __U, __m128i __A) { return (__m128h)__builtin_ia32_vcvthf8_2ph128_mask( (__v16qi)__A, (__v8hf)(__m128h)__W, (__mmask8)__U); } -static __inline__ __m128h __DEFAULT_FN_ATTRS128 _mm_maskz_cvthf8(__mmask8 __U, - __m128i __A) { +static __inline__ __m128h __DEFAULT_FN_ATTRS128 +_mm_maskz_cvthf8_ph(__mmask8 __U, __m128i __A) { return (__m128h)__builtin_ia32_vcvthf8_2ph128_mask( (__v16qi)__A, (__v8hf)(__m128h)_mm_setzero_ph(), (__mmask8)__U); } -static __inline__ __m256h __DEFAULT_FN_ATTRS256 _mm256_cvthf8(__m128i __A) { +static __inline__ __m256h __DEFAULT_FN_ATTRS256 _mm256_cvthf8_ph(__m128i __A) { return (__m256h)__builtin_ia32_vcvthf8_2ph256_mask( (__v16qi)__A, (__v16hf)(__m256h)_mm256_undefined_ph(), (__mmask16)-1); } static __inline__ __m256h __DEFAULT_FN_ATTRS256 -_mm256_mask_cvthf8(__m256h __W, __mmask16 __U, __m128i __A) { +_mm256_mask_cvthf8_ph(__m256h __W, __mmask16 __U, __m128i __A) { return (__m256h)__builtin_ia32_vcvthf8_2ph256_mask( (__v16qi)__A, (__v16hf)(__m256h)__W, (__mmask16)__U); } static __inline__ __m256h __DEFAULT_FN_ATTRS256 -_mm256_maskz_cvthf8(__mmask16 __U, __m128i __A) { +_mm256_maskz_cvthf8_ph(__mmask16 __U, __m128i __A) { return (__m256h)__builtin_ia32_vcvthf8_2ph256_mask( (__v16qi)__A, (__v16hf)(__m256h)_mm256_setzero_ph(), (__mmask16)__U); } diff --git a/clang/lib/Headers/gpuintrin.h b/clang/lib/Headers/gpuintrin.h index 4c463c333308f..11c87e85cd497 100644 --- a/clang/lib/Headers/gpuintrin.h +++ b/clang/lib/Headers/gpuintrin.h @@ -133,18 +133,21 @@ __gpu_read_first_lane_f64(uint64_t __lane_mask, double __x) { // Shuffles the the lanes according to the given index. _DEFAULT_FN_ATTRS static __inline__ float -__gpu_shuffle_idx_f32(uint64_t __lane_mask, uint32_t __idx, float __x) { +__gpu_shuffle_idx_f32(uint64_t __lane_mask, uint32_t __idx, float __x, + uint32_t __width) { return __builtin_bit_cast( float, __gpu_shuffle_idx_u32(__lane_mask, __idx, - __builtin_bit_cast(uint32_t, __x))); + __builtin_bit_cast(uint32_t, __x), __width)); } // Shuffles the the lanes according to the given index. _DEFAULT_FN_ATTRS static __inline__ double -__gpu_shuffle_idx_f64(uint64_t __lane_mask, uint32_t __idx, double __x) { +__gpu_shuffle_idx_f64(uint64_t __lane_mask, uint32_t __idx, double __x, + uint32_t __width) { return __builtin_bit_cast( - double, __gpu_shuffle_idx_u64(__lane_mask, __idx, - __builtin_bit_cast(uint64_t, __x))); + double, + __gpu_shuffle_idx_u64(__lane_mask, __idx, + __builtin_bit_cast(uint64_t, __x), __width)); } // Gets the sum of all lanes inside the warp or wavefront. @@ -153,7 +156,8 @@ __gpu_shuffle_idx_f64(uint64_t __lane_mask, uint32_t __idx, double __x) { uint64_t __lane_mask, __type __x) { \ for (uint32_t __step = __gpu_num_lanes() / 2; __step > 0; __step /= 2) { \ uint32_t __index = __step + __gpu_lane_id(); \ - __x += __gpu_shuffle_idx_##__suffix(__lane_mask, __index, __x); \ + __x += __gpu_shuffle_idx_##__suffix(__lane_mask, __index, __x, \ + __gpu_num_lanes()); \ } \ return __gpu_read_first_lane_##__suffix(__lane_mask, __x); \ } @@ -171,10 +175,10 @@ __DO_LANE_SUM(double, f64); // double __gpu_lane_sum_f64(m, x) uint32_t __index = __gpu_lane_id() - __step; \ __bitmask_type bitmask = __gpu_lane_id() >= __step; \ __x += __builtin_bit_cast( \ - __type, \ - -bitmask & __builtin_bit_cast(__bitmask_type, \ - __gpu_shuffle_idx_##__suffix( \ - __lane_mask, __index, __x))); \ + __type, -bitmask & __builtin_bit_cast(__bitmask_type, \ + __gpu_shuffle_idx_##__suffix( \ + __lane_mask, __index, __x, \ + __gpu_num_lanes()))); \ } \ return __x; \ } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index d1e4eb08aa764..513639ed1b81d 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -138,6 +138,27 @@ _HLSL_BUILTIN_ALIAS(__builtin_elementwise_acos) float4 acos(float4); //===----------------------------------------------------------------------===// +// AddUint64 builtins +//===----------------------------------------------------------------------===// + +/// \fn T AddUint64(T a, T b) +/// \brief Implements unsigned 64-bit integer addition using pairs of unsigned +/// 32-bit integers. +/// \param x [in] The first unsigned 32-bit integer pair(s) +/// \param y [in] The second unsigned 32-bit integer pair(s) +/// +/// This function takes one or two pairs (low, high) of unsigned 32-bit integer +/// values and returns pairs (low, high) of unsigned 32-bit integer +/// values representing the result of unsigned 64-bit integer addition. + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_adduint64) +uint32_t2 AddUint64(uint32_t2, uint32_t2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_adduint64) +uint32_t4 AddUint64(uint32_t4, uint32_t4); + +// //===----------------------------------------------------------------------===// // all builtins //===----------------------------------------------------------------------===// @@ -2468,6 +2489,105 @@ __attribute__((convergent)) double3 WaveReadLaneAt(double3, int32_t); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_read_lane_at) __attribute__((convergent)) double4 WaveReadLaneAt(double4, int32_t); +//===----------------------------------------------------------------------===// +// WaveActiveMax builtins +//===----------------------------------------------------------------------===// + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) half WaveActiveMax(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) half2 WaveActiveMax(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) half3 WaveActiveMax(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) half4 WaveActiveMax(half4); + +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int16_t WaveActiveMax(int16_t); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int16_t2 WaveActiveMax(int16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int16_t3 WaveActiveMax(int16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int16_t4 WaveActiveMax(int16_t4); + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint16_t WaveActiveMax(uint16_t); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint16_t2 WaveActiveMax(uint16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint16_t3 WaveActiveMax(uint16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint16_t4 WaveActiveMax(uint16_t4); +#endif + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int WaveActiveMax(int); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int2 WaveActiveMax(int2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int3 WaveActiveMax(int3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int4 WaveActiveMax(int4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint WaveActiveMax(uint); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint2 WaveActiveMax(uint2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint3 WaveActiveMax(uint3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint4 WaveActiveMax(uint4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int64_t WaveActiveMax(int64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int64_t2 WaveActiveMax(int64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int64_t3 WaveActiveMax(int64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) int64_t4 WaveActiveMax(int64_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint64_t WaveActiveMax(uint64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint64_t2 WaveActiveMax(uint64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint64_t3 WaveActiveMax(uint64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) uint64_t4 WaveActiveMax(uint64_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) float WaveActiveMax(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) float2 WaveActiveMax(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) float3 WaveActiveMax(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) float4 WaveActiveMax(float4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) double WaveActiveMax(double); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) double2 WaveActiveMax(double2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) double3 WaveActiveMax(double3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) +__attribute__((convergent)) double4 WaveActiveMax(double4); + //===----------------------------------------------------------------------===// // WaveActiveSum builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Headers/nvptxintrin.h b/clang/lib/Headers/nvptxintrin.h index 962dca9cf0312..40fa2edebe975 100644 --- a/clang/lib/Headers/nvptxintrin.h +++ b/clang/lib/Headers/nvptxintrin.h @@ -149,25 +149,23 @@ _DEFAULT_FN_ATTRS static __inline__ void __gpu_sync_lane(uint64_t __lane_mask) { // Shuffles the the lanes inside the warp according to the given index. _DEFAULT_FN_ATTRS static __inline__ uint32_t -__gpu_shuffle_idx_u32(uint64_t __lane_mask, uint32_t __idx, uint32_t __x) { +__gpu_shuffle_idx_u32(uint64_t __lane_mask, uint32_t __idx, uint32_t __x, + uint32_t __width) { uint32_t __mask = (uint32_t)__lane_mask; - uint32_t __bitmask = (__mask >> __idx) & 1u; - return -__bitmask & - __nvvm_shfl_sync_idx_i32(__mask, __x, __idx, __gpu_num_lanes() - 1u); + return __nvvm_shfl_sync_idx_i32(__mask, __x, __idx, + ((__gpu_num_lanes() - __width) << 8u) | 0x1f); } // Shuffles the the lanes inside the warp according to the given index. _DEFAULT_FN_ATTRS static __inline__ uint64_t -__gpu_shuffle_idx_u64(uint64_t __lane_mask, uint32_t __idx, uint64_t __x) { +__gpu_shuffle_idx_u64(uint64_t __lane_mask, uint32_t __idx, uint64_t __x, + uint32_t __width) { uint32_t __hi = (uint32_t)(__x >> 32ull); uint32_t __lo = (uint32_t)(__x & 0xFFFFFFFF); uint32_t __mask = (uint32_t)__lane_mask; - uint64_t __bitmask = (__mask >> __idx) & 1u; - return -__bitmask & ((uint64_t)__nvvm_shfl_sync_idx_i32( - __mask, __hi, __idx, __gpu_num_lanes() - 1u) - << 32ull) | - ((uint64_t)__nvvm_shfl_sync_idx_i32(__mask, __lo, __idx, - __gpu_num_lanes() - 1u)); + return ((uint64_t)__gpu_shuffle_idx_u32(__mask, __idx, __hi, __width) + << 32ull) | + ((uint64_t)__gpu_shuffle_idx_u32(__mask, __idx, __lo, __width)); } // Returns true if the flat pointer points to CUDA 'shared' memory. diff --git a/clang/lib/Index/FileIndexRecord.cpp b/clang/lib/Index/FileIndexRecord.cpp index 449c33637eb7e..cf40a596f5094 100644 --- a/clang/lib/Index/FileIndexRecord.cpp +++ b/clang/lib/Index/FileIndexRecord.cpp @@ -55,7 +55,7 @@ void FileIndexRecord::removeHeaderGuardMacros() { void FileIndexRecord::print(llvm::raw_ostream &OS, SourceManager &SM) const { OS << "DECLS BEGIN ---\n"; for (auto &DclInfo : Decls) { - if (const auto *D = DclInfo.DeclOrMacro.dyn_cast()) { + if (const auto *D = dyn_cast(DclInfo.DeclOrMacro)) { SourceLocation Loc = SM.getFileLoc(D->getLocation()); PresumedLoc PLoc = SM.getPresumedLoc(Loc); OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' diff --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp index c18daf7faa749..f1dc4d5831ce7 100644 --- a/clang/lib/Index/IndexBody.cpp +++ b/clang/lib/Index/IndexBody.cpp @@ -130,6 +130,9 @@ class BodyIndexer : public RecursiveASTVisitor { void addCallRole(SymbolRoleSet &Roles, SmallVectorImpl &Relations) { + if (isa(ParentDC)) + return; + Roles |= (unsigned)SymbolRole::Call; if (auto *FD = dyn_cast(ParentDC)) Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, FD); diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp index 493123459a5a4..1e54b413dc59c 100644 --- a/clang/lib/Index/USRGeneration.cpp +++ b/clang/lib/Index/USRGeneration.cpp @@ -763,9 +763,10 @@ void USRGenerator::VisitType(QualType T) { Out << "@BT@OCLReserveID"; break; case BuiltinType::OCLSampler: Out << "@BT@OCLSampler"; break; -#define SVE_TYPE(Name, Id, SingletonId) \ - case BuiltinType::Id: \ - Out << "@BT@" << Name; break; +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: \ + Out << "@BT@" << #Name; \ + break; #include "clang/Basic/AArch64SVEACLETypes.def" #define PPC_VECTOR_TYPE(Name, Id, Size) \ case BuiltinType::Id: \ diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index ccf94f6345ff2..998e2b977d109 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -2928,9 +2928,10 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) { ActiveModule->InferExplicitSubmodules = Explicit; } else { // We'll be inferring framework modules for this directory. - Map.InferredDirectories[Directory].InferModules = true; - Map.InferredDirectories[Directory].Attrs = Attrs; - Map.InferredDirectories[Directory].ModuleMapFID = ModuleMapFID; + auto &InfDir = Map.InferredDirectories[Directory]; + InfDir.InferModules = true; + InfDir.Attrs = Attrs; + InfDir.ModuleMapFID = ModuleMapFID; // FIXME: Handle the 'framework' keyword. } diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 9cf29668f251f..944966a791add 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1798,58 +1798,55 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { return II && HasExtension(*this, II->getName()); }); } else if (II == Ident__has_builtin) { - EvaluateFeatureLikeBuiltinMacro(OS, Tok, II, *this, false, - [this](Token &Tok, bool &HasLexedNextToken) -> int { - IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this, - diag::err_feature_check_malformed); - if (!II) - return false; - auto BuiltinID = II->getBuiltinID(); - if (BuiltinID != 0) { - switch (BuiltinID) { - case Builtin::BI__builtin_cpu_is: - return getTargetInfo().supportsCpuIs(); - case Builtin::BI__builtin_cpu_init: - return getTargetInfo().supportsCpuInit(); - case Builtin::BI__builtin_cpu_supports: - return getTargetInfo().supportsCpuSupports(); - case Builtin::BI__builtin_operator_new: - case Builtin::BI__builtin_operator_delete: - // denotes date of behavior change to support calling arbitrary - // usual allocation and deallocation functions. Required by libc++ - return 201802; - default: - // __has_builtin should return false for aux builtins. - if (getBuiltinInfo().isAuxBuiltinID(BuiltinID)) - return false; - return Builtin::evaluateRequiredTargetFeatures( - getBuiltinInfo().getRequiredFeatures(BuiltinID), - getTargetInfo().getTargetOpts().FeatureMap); + EvaluateFeatureLikeBuiltinMacro( + OS, Tok, II, *this, false, + [this](Token &Tok, bool &HasLexedNextToken) -> int { + IdentifierInfo *II = ExpectFeatureIdentifierInfo( + Tok, *this, diag::err_feature_check_malformed); + if (!II) + return false; + else if (II->getBuiltinID() != 0) { + switch (II->getBuiltinID()) { + case Builtin::BI__builtin_cpu_is: + return getTargetInfo().supportsCpuIs(); + case Builtin::BI__builtin_cpu_init: + return getTargetInfo().supportsCpuInit(); + case Builtin::BI__builtin_cpu_supports: + return getTargetInfo().supportsCpuSupports(); + case Builtin::BI__builtin_operator_new: + case Builtin::BI__builtin_operator_delete: + // denotes date of behavior change to support calling arbitrary + // usual allocation and deallocation functions. Required by libc++ + return 201802; + default: + return Builtin::evaluateRequiredTargetFeatures( + getBuiltinInfo().getRequiredFeatures(II->getBuiltinID()), + getTargetInfo().getTargetOpts().FeatureMap); + } + return true; + } else if (IsBuiltinTrait(Tok)) { + return true; + } else if (II->getTokenID() != tok::identifier && + II->getName().starts_with("__builtin_")) { + return true; + } else { + return llvm::StringSwitch(II->getName()) + // Report builtin templates as being builtins. + .Case("__make_integer_seq", getLangOpts().CPlusPlus) + .Case("__type_pack_element", getLangOpts().CPlusPlus) + .Case("__builtin_common_type", getLangOpts().CPlusPlus) + // Likewise for some builtin preprocessor macros. + // FIXME: This is inconsistent; we usually suggest detecting + // builtin macros via #ifdef. Don't add more cases here. + .Case("__is_target_arch", true) + .Case("__is_target_vendor", true) + .Case("__is_target_os", true) + .Case("__is_target_environment", true) + .Case("__is_target_variant_os", true) + .Case("__is_target_variant_environment", true) + .Default(false); } - return true; - } else if (IsBuiltinTrait(Tok)) { - return true; - } else if (II->getTokenID() != tok::identifier && - II->getName().starts_with("__builtin_")) { - return true; - } else { - return llvm::StringSwitch(II->getName()) - // Report builtin templates as being builtins. - .Case("__make_integer_seq", getLangOpts().CPlusPlus) - .Case("__type_pack_element", getLangOpts().CPlusPlus) - .Case("__builtin_common_type", getLangOpts().CPlusPlus) - // Likewise for some builtin preprocessor macros. - // FIXME: This is inconsistent; we usually suggest detecting - // builtin macros via #ifdef. Don't add more cases here. - .Case("__is_target_arch", true) - .Case("__is_target_vendor", true) - .Case("__is_target_os", true) - .Case("__is_target_environment", true) - .Case("__is_target_variant_os", true) - .Case("__is_target_variant_environment", true) - .Default(false); - } - }); + }); } else if (II == Ident__has_constexpr_builtin) { EvaluateFeatureLikeBuiltinMacro( OS, Tok, II, *this, false, diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index f136d5007e8a5..75b5e11f8327c 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -7315,15 +7315,16 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { // If this doesn't look like a structured binding, maybe it's a misplaced // array declarator. - if (!(Tok.is(tok::identifier) && + if (!(Tok.isOneOf(tok::identifier, tok::ellipsis) && NextToken().isOneOf(tok::comma, tok::r_square, tok::kw_alignas, - tok::l_square)) && + tok::identifier, tok::l_square, tok::ellipsis)) && !(Tok.is(tok::r_square) && NextToken().isOneOf(tok::equal, tok::l_brace))) { PA.Revert(); return ParseMisplacedBracketDeclarator(D); } + SourceLocation PrevEllipsisLoc; SmallVector Bindings; while (Tok.isNot(tok::r_square)) { if (!Bindings.empty()) { @@ -7338,11 +7339,11 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { Diag(Tok, diag::err_expected_comma_or_rsquare); } - SkipUntil(tok::r_square, tok::comma, tok::identifier, + SkipUntil({tok::r_square, tok::comma, tok::identifier, tok::ellipsis}, StopAtSemi | StopBeforeMatch); if (Tok.is(tok::comma)) ConsumeToken(); - else if (Tok.isNot(tok::identifier)) + else if (Tok.is(tok::r_square)) break; } } @@ -7350,6 +7351,21 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { if (isCXX11AttributeSpecifier()) DiagnoseAndSkipCXX11Attributes(); + SourceLocation EllipsisLoc; + + if (Tok.is(tok::ellipsis)) { + Diag(Tok, getLangOpts().CPlusPlus26 ? diag::warn_cxx23_compat_binding_pack + : diag::ext_cxx_binding_pack); + if (PrevEllipsisLoc.isValid()) { + Diag(Tok, diag::err_binding_multiple_ellipses); + Diag(PrevEllipsisLoc, diag::note_previous_ellipsis); + break; + } + EllipsisLoc = Tok.getLocation(); + PrevEllipsisLoc = EllipsisLoc; + ConsumeToken(); + } + if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected) << tok::identifier; break; @@ -7359,6 +7375,13 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { SourceLocation Loc = Tok.getLocation(); ConsumeToken(); + if (Tok.is(tok::ellipsis) && !PrevEllipsisLoc.isValid()) { + DiagnoseMisplacedEllipsis(Tok.getLocation(), Loc, EllipsisLoc.isValid(), + true); + EllipsisLoc = Tok.getLocation(); + ConsumeToken(); + } + ParsedAttributes Attrs(AttrFactory); if (isCXX11AttributeSpecifier()) { Diag(Tok, getLangOpts().CPlusPlus26 @@ -7367,7 +7390,7 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { MaybeParseCXX11Attributes(Attrs); } - Bindings.push_back({II, Loc, std::move(Attrs)}); + Bindings.push_back({II, Loc, std::move(Attrs), EllipsisLoc}); } if (Tok.isNot(tok::r_square)) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index fddb8a5729ee8..43db715ac6d70 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1813,7 +1813,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, tok::kw___is_pointer, tok::kw___is_polymorphic, tok::kw___is_reference, - tok::kw___is_referenceable, tok::kw___is_rvalue_expr, tok::kw___is_rvalue_reference, tok::kw___is_same, diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index aa8b3870a188c..da5f2ccf3a0c6 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -824,7 +824,6 @@ bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II, REVERTIBLE_TYPE_TRAIT(__is_pointer); REVERTIBLE_TYPE_TRAIT(__is_polymorphic); REVERTIBLE_TYPE_TRAIT(__is_reference); - REVERTIBLE_TYPE_TRAIT(__is_referenceable); REVERTIBLE_TYPE_TRAIT(__is_rvalue_expr); REVERTIBLE_TYPE_TRAIT(__is_rvalue_reference); REVERTIBLE_TYPE_TRAIT(__is_same); diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index 98fd61913e5a4..d036971d2fc31 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -156,14 +156,14 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) { // second part of the directive. OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) { if (!Tok.is(tok::identifier)) - return OpenACCAtomicKind::Invalid; + return OpenACCAtomicKind::None; return llvm::StringSwitch( Tok.getIdentifierInfo()->getName()) .Case("read", OpenACCAtomicKind::Read) .Case("write", OpenACCAtomicKind::Write) .Case("update", OpenACCAtomicKind::Update) .Case("capture", OpenACCAtomicKind::Capture) - .Default(OpenACCAtomicKind::Invalid); + .Default(OpenACCAtomicKind::None); } OpenACCDefaultClauseKind getOpenACCDefaultClauseKind(Token Tok) { @@ -398,17 +398,16 @@ OpenACCAtomicKind ParseOpenACCAtomicKind(Parser &P) { // #pragma acc atomic is equivilent to update: if (AtomicClauseToken.isAnnotation()) - return OpenACCAtomicKind::Update; + return OpenACCAtomicKind::None; OpenACCAtomicKind AtomicKind = getOpenACCAtomicKind(AtomicClauseToken); - // If we don't know what this is, treat it as 'nothing', and treat the rest of - // this as a clause list, which, despite being invalid, is likely what the - // user was trying to do. - if (AtomicKind == OpenACCAtomicKind::Invalid) - return OpenACCAtomicKind::Update; + // If this isn't a valid atomic-kind, don't consume the token, and treat the + // rest as a clause list, which despite there being no permissible clauses, + // will diagnose as a clause. + if (AtomicKind != OpenACCAtomicKind::None) + P.ConsumeToken(); - P.ConsumeToken(); return AtomicKind; } @@ -570,12 +569,19 @@ void SkipUntilEndOfDirective(Parser &P) { bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) { switch (DirKind) { - default: + case OpenACCDirectiveKind::Routine: + // FIXME: Routine MIGHT end up needing to be 'true' here, as it needs a way + // to capture a lambda-expression on the next line. + case OpenACCDirectiveKind::Cache: + case OpenACCDirectiveKind::Declare: + case OpenACCDirectiveKind::Set: case OpenACCDirectiveKind::EnterData: case OpenACCDirectiveKind::ExitData: case OpenACCDirectiveKind::Wait: case OpenACCDirectiveKind::Init: case OpenACCDirectiveKind::Shutdown: + case OpenACCDirectiveKind::Update: + case OpenACCDirectiveKind::Invalid: return false; case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: @@ -586,6 +592,7 @@ bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) { case OpenACCDirectiveKind::Loop: case OpenACCDirectiveKind::Data: case OpenACCDirectiveKind::HostData: + case OpenACCDirectiveKind::Atomic: return true; } llvm_unreachable("Unhandled directive->assoc stmt"); @@ -1428,6 +1435,7 @@ Parser::ParseOpenACCDirective() { SourceLocation DirLoc = getCurToken().getLocation(); OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this); Parser::OpenACCWaitParseInfo WaitInfo; + OpenACCAtomicKind AtomicKind = OpenACCAtomicKind::None; getActions().OpenACC().ActOnConstruct(DirKind, DirLoc); @@ -1435,7 +1443,7 @@ Parser::ParseOpenACCDirective() { // specifiers that need to be taken care of. Atomic has an 'atomic-clause' // that needs to be parsed. if (DirKind == OpenACCDirectiveKind::Atomic) - ParseOpenACCAtomicKind(*this); + AtomicKind = ParseOpenACCAtomicKind(*this); // We've successfully parsed the construct/directive name, however a few of // the constructs have optional parens that contain further details. @@ -1490,6 +1498,7 @@ Parser::ParseOpenACCDirective() { T.getCloseLocation(), /*EndLoc=*/SourceLocation{}, WaitInfo.QueuesLoc, + AtomicKind, WaitInfo.getAllExprs(), ParseOpenACCClauseList(DirKind)}; @@ -1538,11 +1547,12 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() { ParseScope ACCScope(this, getOpenACCScopeFlags(DirInfo.DirKind)); AssocStmt = getActions().OpenACC().ActOnAssociatedStmt( - DirInfo.StartLoc, DirInfo.DirKind, DirInfo.Clauses, ParseStatement()); + DirInfo.StartLoc, DirInfo.DirKind, DirInfo.AtomicKind, DirInfo.Clauses, + ParseStatement()); } return getActions().OpenACC().ActOnEndStmtDirective( DirInfo.DirKind, DirInfo.StartLoc, DirInfo.DirLoc, DirInfo.LParenLoc, - DirInfo.MiscLoc, DirInfo.Exprs, DirInfo.RParenLoc, DirInfo.EndLoc, - DirInfo.Clauses, AssocStmt); + DirInfo.MiscLoc, DirInfo.Exprs, DirInfo.AtomicKind, DirInfo.RParenLoc, + DirInfo.EndLoc, DirInfo.Clauses, AssocStmt); } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 89b83938f352d..a455659ca8f2c 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -888,7 +888,18 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty, TIProperty.Kind = TraitProperty::invalid; SourceLocation NameLoc = Tok.getLocation(); - StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL); + StringRef Name; + if (Selector == llvm::omp::TraitSelector::target_device_device_num) { + Name = "number"; + TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name); + ExprResult DeviceNumExprResult = ParseExpression(); + if (DeviceNumExprResult.isUsable()) { + Expr *DeviceNumExpr = DeviceNumExprResult.get(); + Actions.OpenMP().ActOnOpenMPDeviceNum(DeviceNumExpr); + } + return; + } + Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL); if (Name.empty()) { Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options) << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector); @@ -918,7 +929,8 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty, << "()"; return; } - TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name); + TraitSelector SelectorForName = + getOpenMPContextTraitSelectorKind(Name, SetForName); if (SelectorForName != TraitSelector::invalid) { Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a) << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL; @@ -935,7 +947,7 @@ void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty, } for (const auto &PotentialSet : {TraitSet::construct, TraitSet::user, TraitSet::implementation, - TraitSet::device}) { + TraitSet::device, TraitSet::target_device}) { TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name); if (PropertyForName == TraitProperty::invalid) @@ -1062,7 +1074,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector, return; } - TISelector.Kind = getOpenMPContextTraitSelectorKind(Name); + TISelector.Kind = getOpenMPContextTraitSelectorKind(Name, Set); if (TISelector.Kind != TraitSelector::invalid) { if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL)) TISelector.Kind = TraitSelector::invalid; @@ -1084,7 +1096,7 @@ void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector, } for (const auto &PotentialSet : {TraitSet::construct, TraitSet::user, TraitSet::implementation, - TraitSet::device}) { + TraitSet::device, TraitSet::target_device}) { TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind( PotentialSet, TraitSelector::invalid, Name); if (PropertyForName == TraitProperty::invalid) @@ -1259,7 +1271,8 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet, // It follows diagnosis and helping notes. Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name; - TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name); + TraitSelector SelectorForName = + getOpenMPContextTraitSelectorKind(Name, TISet.Kind); if (SelectorForName != TraitSelector::invalid) { Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a) << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL; @@ -1276,7 +1289,7 @@ void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet, } for (const auto &PotentialSet : {TraitSet::construct, TraitSet::user, TraitSet::implementation, - TraitSet::device}) { + TraitSet::device, TraitSet::target_device}) { TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind( PotentialSet, TraitSelector::invalid, Name); if (PropertyForName == TraitProperty::invalid) @@ -1680,6 +1693,7 @@ void Parser::ParseOpenMPClauses(OpenMPDirectiveKind DKind, /// 'holds' '(' scalar-expression ')' /// 'no_openmp' /// 'no_openmp_routines' +/// 'no_openmp_constructs' (OpenMP 6.0) /// 'no_parallelism' /// void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind, @@ -2253,7 +2267,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( TargetOMPContext OMPCtx( ASTCtx, std::move(DiagUnknownTrait), /* CurrentFunctionDecl */ nullptr, - /* ConstructTraits */ ArrayRef()); + /* ConstructTraits */ ArrayRef(), + Actions.OpenMP().getOpenMPDeviceNum()); if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) { Actions.OpenMP().ActOnOpenMPBeginDeclareVariant(Loc, TI); @@ -2805,7 +2820,8 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( }; TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait), /* CurrentFunctionDecl */ nullptr, - ArrayRef()); + ArrayRef(), + Actions.OpenMP().getOpenMPDeviceNum()); // A single match is returned for OpenMP 5.0 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); @@ -3459,6 +3475,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, } case OMPC_no_openmp: case OMPC_no_openmp_routines: + case OMPC_no_openmp_constructs: case OMPC_no_parallelism: { if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt index 19cf3a2db00fd..1a351684d133e 100644 --- a/clang/lib/Sema/CMakeLists.txt +++ b/clang/lib/Sema/CMakeLists.txt @@ -71,6 +71,7 @@ add_clang_library(clangSema SemaObjC.cpp SemaObjCProperty.cpp SemaOpenACC.cpp + SemaOpenACCAtomic.cpp SemaOpenACCClause.cpp SemaOpenCL.cpp SemaOpenMP.cpp diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp index 2a726fe51d355..3af4d001d6c1a 100644 --- a/clang/lib/Sema/HeuristicResolver.cpp +++ b/clang/lib/Sema/HeuristicResolver.cpp @@ -71,8 +71,17 @@ class HeuristicResolverImpl { // Helper function for HeuristicResolver::resolveDependentMember() // which takes a possibly-dependent type `T` and heuristically - // resolves it to a CXXRecordDecl in which we can try name lookup. - CXXRecordDecl *resolveTypeToRecordDecl(const Type *T); + // resolves it to a TagDecl in which we can try name lookup. + TagDecl *resolveTypeToTagDecl(const Type *T); + + // Helper function for simplifying a type. + // `Type` is the type to simplify. + // `E` is the expression whose type `Type` is, if known. This sometimes + // contains information relevant to the type that's not stored in `Type` + // itself. + // If `UnwrapPointer` is true, exactly only pointer type will be unwrapped + // during simplification, and the operation fails if no pointer type is found. + QualType simplifyType(QualType Type, const Expr *E, bool UnwrapPointer); // This is a reimplementation of CXXRecordDecl::lookupDependentName() // so that the implementation can call into other HeuristicResolver helpers. @@ -130,7 +139,7 @@ TemplateName getReferencedTemplateName(const Type *T) { // Helper function for HeuristicResolver::resolveDependentMember() // which takes a possibly-dependent type `T` and heuristically // resolves it to a CXXRecordDecl in which we can try name lookup. -CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) { +TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(const Type *T) { assert(T); // Unwrap type sugar such as type aliases. @@ -144,8 +153,9 @@ CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) { T = T->getCanonicalTypeInternal().getTypePtr(); } - if (const auto *RT = T->getAs()) - return dyn_cast(RT->getDecl()); + if (auto *TT = T->getAs()) { + return TT->getDecl(); + } if (const auto *ICNT = T->getAs()) T = ICNT->getInjectedSpecializationType().getTypePtrOrNull(); @@ -197,6 +207,70 @@ QualType HeuristicResolverImpl::getPointeeType(QualType T) { return FirstArg.getAsType(); } +QualType HeuristicResolverImpl::simplifyType(QualType Type, const Expr *E, + bool UnwrapPointer) { + bool DidUnwrapPointer = false; + // A type, together with an optional expression whose type it represents + // which may have additional information about the expression's type + // not stored in the QualType itself. + struct TypeExprPair { + QualType Type; + const Expr *E = nullptr; + }; + TypeExprPair Current{Type, E}; + auto SimplifyOneStep = [UnwrapPointer, &DidUnwrapPointer, + this](TypeExprPair T) -> TypeExprPair { + if (UnwrapPointer) { + if (QualType Pointee = getPointeeType(T.Type); !Pointee.isNull()) { + DidUnwrapPointer = true; + return {Pointee}; + } + } + if (const auto *RT = T.Type->getAs()) { + // Does not count as "unwrap pointer". + return {RT->getPointeeType()}; + } + if (const auto *BT = T.Type->getAs()) { + // If BaseType is the type of a dependent expression, it's just + // represented as BuiltinType::Dependent which gives us no information. We + // can get further by analyzing the dependent expression. + if (T.E && BT->getKind() == BuiltinType::Dependent) { + return {resolveExprToType(T.E), T.E}; + } + } + if (const auto *AT = T.Type->getContainedAutoType()) { + // If T contains a dependent `auto` type, deduction will not have + // been performed on it yet. In simple cases (e.g. `auto` variable with + // initializer), get the approximate type that would result from + // deduction. + // FIXME: A more accurate implementation would propagate things like the + // `const` in `const auto`. + if (T.E && AT->isUndeducedAutoType()) { + if (const auto *DRE = dyn_cast(T.E)) { + if (const auto *VD = dyn_cast(DRE->getDecl())) { + if (auto *Init = VD->getInit()) + return {resolveExprToType(Init), Init}; + } + } + } + } + return T; + }; + // As an additional protection against infinite loops, bound the number of + // simplification steps. + size_t StepCount = 0; + const size_t MaxSteps = 64; + while (!Current.Type.isNull() && StepCount++ < MaxSteps) { + TypeExprPair New = SimplifyOneStep(Current); + if (New.Type == Current.Type) + break; + Current = New; + } + if (UnwrapPointer && !DidUnwrapPointer) + return QualType(); + return Current.Type; +} + std::vector HeuristicResolverImpl::resolveMemberExpr( const CXXDependentScopeMemberExpr *ME) { // If the expression has a qualifier, try resolving the member inside the @@ -227,28 +301,17 @@ std::vector HeuristicResolverImpl::resolveMemberExpr( } // Try resolving the member inside the expression's base type. + Expr *Base = ME->isImplicitAccess() ? nullptr : ME->getBase(); QualType BaseType = ME->getBaseType(); - if (ME->isArrow()) { - BaseType = getPointeeType(BaseType); - } - if (BaseType.isNull()) - return {}; - if (const auto *BT = BaseType->getAs()) { - // If BaseType is the type of a dependent expression, it's just - // represented as BuiltinType::Dependent which gives us no information. We - // can get further by analyzing the dependent expression. - Expr *Base = ME->isImplicitAccess() ? nullptr : ME->getBase(); - if (Base && BT->getKind() == BuiltinType::Dependent) { - BaseType = resolveExprToType(Base); - } - } + BaseType = simplifyType(BaseType, Base, ME->isArrow()); return resolveDependentMember(BaseType, ME->getMember(), NoFilter); } std::vector HeuristicResolverImpl::resolveDeclRefExpr(const DependentScopeDeclRefExpr *RE) { - return resolveDependentMember(QualType(RE->getQualifier()->getAsType(), 0), - RE->getDeclName(), StaticFilter); + return resolveDependentMember( + resolveNestedNameSpecifierToType(RE->getQualifier()), RE->getDeclName(), + StaticFilter); } std::vector @@ -260,7 +323,7 @@ HeuristicResolverImpl::resolveTypeOfCallExpr(const CallExpr *CE) { CalleeType = FnTypePtr->getPointeeType(); if (const FunctionType *FnType = CalleeType->getAs()) { if (const auto *D = - resolveTypeToRecordDecl(FnType->getReturnType().getTypePtr())) { + resolveTypeToTagDecl(FnType->getReturnType().getTypePtr())) { return {D}; } } @@ -371,11 +434,11 @@ bool findOrdinaryMember(const CXXRecordDecl *RD, CXXBasePath &Path, bool HeuristicResolverImpl::findOrdinaryMemberInDependentClasses( const CXXBaseSpecifier *Specifier, CXXBasePath &Path, DeclarationName Name) { - CXXRecordDecl *RD = - resolveTypeToRecordDecl(Specifier->getType().getTypePtr()); - if (!RD) - return false; - return findOrdinaryMember(RD, Path, Name); + TagDecl *TD = resolveTypeToTagDecl(Specifier->getType().getTypePtr()); + if (const auto *RD = dyn_cast_if_present(TD)) { + return findOrdinaryMember(RD, Path, Name); + } + return false; } std::vector HeuristicResolverImpl::lookupDependentName( @@ -417,11 +480,14 @@ std::vector HeuristicResolverImpl::resolveDependentMember( const Type *T = QT.getTypePtrOrNull(); if (!T) return {}; - if (auto *ET = T->getAs()) { - auto Result = ET->getDecl()->lookup(Name); + TagDecl *TD = resolveTypeToTagDecl(T); + if (!TD) + return {}; + if (auto *ED = dyn_cast(TD)) { + auto Result = ED->lookup(Name); return {Result.begin(), Result.end()}; } - if (auto *RD = resolveTypeToRecordDecl(T)) { + if (auto *RD = dyn_cast(TD)) { if (!RD->hasDefinition()) return {}; RD = RD->getDefinition(); @@ -429,7 +495,8 @@ std::vector HeuristicResolverImpl::resolveDependentMember( if (!Filter(ND)) return false; if (const auto *MD = dyn_cast(ND)) { - return MD->getMethodQualifiers().compatiblyIncludes(QT.getQualifiers(), + return !MD->isInstance() || + MD->getMethodQualifiers().compatiblyIncludes(QT.getQualifiers(), Ctx); } return true; diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index d465599450e7f..edcfffa2b3894 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -561,12 +561,12 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, // implementable but a lot of work which we haven't felt up to doing. ExprWithCleanups *EWC = cast(S); for (unsigned i = 0, e = EWC->getNumObjects(); i != e; ++i) { - if (auto *BDecl = EWC->getObject(i).dyn_cast()) + if (auto *BDecl = dyn_cast(EWC->getObject(i))) for (const auto &CI : BDecl->captures()) { VarDecl *variable = CI.getVariable(); BuildScopeInformation(variable, BDecl, origParentScope); } - else if (auto *CLE = EWC->getObject(i).dyn_cast()) + else if (auto *CLE = dyn_cast(EWC->getObject(i))) BuildScopeInformation(CLE, origParentScope); else llvm_unreachable("unexpected cleanup object type"); @@ -597,15 +597,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, LabelAndGotoScopes[S] = ParentScope; break; - case Stmt::AttributedStmtClass: { - AttributedStmt *AS = cast(S); - if (GetMustTailAttr(AS)) { - LabelAndGotoScopes[AS] = ParentScope; - MustTailStmts.push_back(AS); - } - break; - } - case Stmt::OpenACCComputeConstructClass: { unsigned NewParentScope = Scopes.size(); OpenACCComputeConstruct *CC = cast(S); @@ -649,7 +640,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, continue; } - // Cases, labels, and defaults aren't "scope parents". It's also + // Cases, labels, attributes, and defaults aren't "scope parents". It's also // important to handle these iteratively instead of recursively in // order to avoid blowing out the stack. while (true) { @@ -658,7 +649,13 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, Next = SC->getSubStmt(); else if (LabelStmt *LS = dyn_cast(SubStmt)) Next = LS->getSubStmt(); - else + else if (AttributedStmt *AS = dyn_cast(SubStmt)) { + if (GetMustTailAttr(AS)) { + LabelAndGotoScopes[AS] = ParentScope; + MustTailStmts.push_back(AS); + } + Next = AS->getSubStmt(); + } else break; LabelAndGotoScopes[SubStmt] = ParentScope; @@ -786,8 +783,7 @@ void JumpScopeChecker::VerifyIndirectJumps() { if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(TheLabel->getStmt()))) continue; unsigned LabelScope = LabelAndGotoScopes[TheLabel->getStmt()]; - if (!TargetScopes.contains(LabelScope)) - TargetScopes[LabelScope] = TheLabel; + TargetScopes.try_emplace(LabelScope, TheLabel); } // For each target scope, make sure it's trivially reachable from diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index abb46d3a84e74..15c18f9a4525b 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -478,8 +478,8 @@ void Sema::Initialize() { if (Context.getTargetInfo().hasAArch64SVETypes() || (Context.getAuxTargetInfo() && Context.getAuxTargetInfo()->hasAArch64SVETypes())) { -#define SVE_TYPE(Name, Id, SingletonId) \ - addImplicitTypedef(Name, Context.SingletonId); +#define SVE_TYPE(Name, Id, SingletonId) \ + addImplicitTypedef(#Name, Context.SingletonId); #include "clang/Basic/AArch64SVEACLETypes.def" } @@ -1679,7 +1679,7 @@ void Sema::EmitDiagnostic(unsigned DiagID, const DiagnosticBuilder &DB) { // that is different from the last template instantiation where // we emitted an error, print a template instantiation // backtrace. - if (!DiagnosticIDs::isBuiltinNote(DiagID)) + if (!Diags.getDiagnosticIDs()->isNote(DiagID)) PrintContextStack(); } @@ -1693,7 +1693,8 @@ bool Sema::hasUncompilableErrorOccurred() const { if (Loc == DeviceDeferredDiags.end()) return false; for (auto PDAt : Loc->second) { - if (DiagnosticIDs::isDefaultMappingAsError(PDAt.second.getDiagID())) + if (Diags.getDiagnosticIDs()->isDefaultMappingAsError( + PDAt.second.getDiagID())) return true; } return false; diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index 4f79775bc5e91..b354bb7b06435 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -478,7 +478,7 @@ static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc, const api_notes::FunctionInfo &Info, VersionedInfoMetadata Metadata) { // Find the declaration itself. - FunctionDecl *FD = AnyFunc.dyn_cast(); + FunctionDecl *FD = dyn_cast(AnyFunc); Decl *D = FD; ObjCMethodDecl *MD = nullptr; if (!D) { diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index db418d80e0e09..b4b40f293b28e 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -352,6 +352,8 @@ static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, return Context.DoubleTy; case NeonTypeFlags::BFloat16: return Context.BFloat16Ty; + case NeonTypeFlags::MFloat8: + return Context.MFloat8Ty; } llvm_unreachable("Invalid NeonTypeFlag!"); } @@ -622,20 +624,6 @@ static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall, return true; } -static bool hasArmZAState(const FunctionDecl *FD) { - const auto *T = FD->getType()->getAs(); - return (T && FunctionType::getArmZAState(T->getAArch64SMEAttributes()) != - FunctionType::ARM_None) || - (FD->hasAttr() && FD->getAttr()->isNewZA()); -} - -static bool hasArmZT0State(const FunctionDecl *FD) { - const auto *T = FD->getType()->getAs(); - return (T && FunctionType::getArmZT0State(T->getAArch64SMEAttributes()) != - FunctionType::ARM_None) || - (FD->hasAttr() && FD->getAttr()->isNewZT0()); -} - static ArmSMEState getSMEState(unsigned BuiltinID) { switch (BuiltinID) { default: @@ -648,7 +636,8 @@ static ArmSMEState getSMEState(unsigned BuiltinID) { bool SemaARM::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { - if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) { + if (const FunctionDecl *FD = + SemaRef.getCurFunctionDecl(/*AllowLambda=*/true)) { std::optional BuiltinType; switch (BuiltinID) { @@ -688,7 +677,8 @@ bool SemaARM::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { - if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) { + if (const FunctionDecl *FD = + SemaRef.getCurFunctionDecl(/*AllowLambda=*/true)) { std::optional BuiltinType; switch (BuiltinID) { @@ -717,23 +707,20 @@ bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall) { - if (const FunctionDecl *FD = SemaRef.getCurFunctionDecl()) { + if (const FunctionDecl *FD = + SemaRef.getCurFunctionDecl(/*AllowLambda=*/true)) { + std::optional BuiltinType; switch (BuiltinID) { default: break; -#define GET_NEON_BUILTINS -#define TARGET_BUILTIN(id, ...) case NEON::BI##id: -#define BUILTIN(id, ...) case NEON::BI##id: +#define GET_NEON_STREAMING_COMPAT_FLAG #include "clang/Basic/arm_neon.inc" - if (checkArmStreamingBuiltin(SemaRef, TheCall, FD, ArmNonStreaming, - BuiltinID)) - return true; - break; -#undef TARGET_BUILTIN -#undef BUILTIN -#undef GET_NEON_BUILTINS +#undef GET_NEON_STREAMING_COMPAT_FLAG } + if (BuiltinType && + checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType, BuiltinID)) + return true; } llvm::APSInt Result; diff --git a/clang/lib/Sema/SemaAVR.cpp b/clang/lib/Sema/SemaAVR.cpp index 47368780b6203..389c55404fde3 100644 --- a/clang/lib/Sema/SemaAVR.cpp +++ b/clang/lib/Sema/SemaAVR.cpp @@ -30,6 +30,18 @@ void SemaAVR::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { if (!AL.checkExactlyNumArgs(SemaRef, 0)) return; + // AVR interrupt handlers must have no parameter and be void type. + if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*AVR*/ 3 << /*interrupt*/ 0 << 0; + return; + } + if (!getFunctionOrMethodResultType(D)->isVoidType()) { + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*AVR*/ 3 << /*interrupt*/ 0 << 1; + return; + } + handleSimpleAttribute(*this, D, AL); } @@ -43,6 +55,18 @@ void SemaAVR::handleSignalAttr(Decl *D, const ParsedAttr &AL) { if (!AL.checkExactlyNumArgs(SemaRef, 0)) return; + // AVR signal handlers must have no parameter and be void type. + if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*AVR*/ 3 << /*signal*/ 1 << 0; + return; + } + if (!getFunctionOrMethodResultType(D)->isVoidType()) { + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*AVR*/ 3 << /*signal*/ 1 << 1; + return; + } + handleSimpleAttribute(*this, D, AL); } diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 6907fa91e28c2..37c0546e321d9 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -537,7 +537,6 @@ bool Sema::ConstantFoldAttrArgs(const AttributeCommonInfo &CI, Diag(Note.first, Note.second); return false; } - assert(Eval.Val.hasValue()); E = ConstantExpr::Create(Context, E, Eval.Val); } @@ -1190,6 +1189,11 @@ void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc, void Sema::AddPragmaAttributes(Scope *S, Decl *D) { if (PragmaAttributeStack.empty()) return; + + if (const auto *P = dyn_cast(D)) + if (P->getType()->isVoidType()) + return; + for (auto &Group : PragmaAttributeStack) { for (auto &Entry : Group.Entries) { ParsedAttr *Attribute = Entry.Attribute; diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp index 35f28bf1bd61a..0e1bf727d72d2 100644 --- a/clang/lib/Sema/SemaCUDA.cpp +++ b/clang/lib/Sema/SemaCUDA.cpp @@ -833,7 +833,7 @@ SemaBase::SemaDiagnosticBuilder SemaCUDA::DiagIfDeviceCode(SourceLocation Loc, if (!getLangOpts().CUDAIsDevice) return SemaDiagnosticBuilder::K_Nop; if (SemaRef.IsLastErrorImmediate && - getDiagnostics().getDiagnosticIDs()->isBuiltinNote(DiagID)) + getDiagnostics().getDiagnosticIDs()->isNote(DiagID)) return SemaDiagnosticBuilder::K_Immediate; return (SemaRef.getEmissionStatus(CurFunContext) == Sema::FunctionEmissionStatus::Emitted) @@ -864,7 +864,7 @@ Sema::SemaDiagnosticBuilder SemaCUDA::DiagIfHostCode(SourceLocation Loc, if (getLangOpts().CUDAIsDevice) return SemaDiagnosticBuilder::K_Nop; if (SemaRef.IsLastErrorImmediate && - getDiagnostics().getDiagnosticIDs()->isBuiltinNote(DiagID)) + getDiagnostics().getDiagnosticIDs()->isNote(DiagID)) return SemaDiagnosticBuilder::K_Immediate; return (SemaRef.getEmissionStatus(CurFunContext) == Sema::FunctionEmissionStatus::Emitted) diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 54bc52fa2ac40..23be71ad8e2ae 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -23,6 +23,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Initialization.h" +#include "clang/Sema/SemaHLSL.h" #include "clang/Sema/SemaObjC.h" #include "clang/Sema/SemaRISCV.h" #include "llvm/ADT/SmallVector.h" @@ -2772,6 +2773,22 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, return; } + CheckedConversionKind CCK = FunctionalStyle + ? CheckedConversionKind::FunctionalCast + : CheckedConversionKind::CStyleCast; + // This case should not trigger on regular vector splat + // vector cast, vector truncation, or special hlsl splat cases + QualType SrcTy = SrcExpr.get()->getType(); + if (Self.getLangOpts().HLSL && + Self.HLSL().CanPerformElementwiseCast(SrcExpr.get(), DestType)) { + if (SrcTy->isConstantArrayType()) + SrcExpr = Self.ImpCastExprToType( + SrcExpr.get(), Self.Context.getArrayParameterType(SrcTy), + CK_HLSLArrayRValue, VK_PRValue, nullptr, CCK); + Kind = CK_HLSLElementwiseCast; + return; + } + if (ValueKind == VK_PRValue && !DestType->isRecordType() && !isPlaceholder(BuiltinType::Overload)) { SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get()); @@ -2824,9 +2841,6 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle, if (isValidCast(tcr)) Kind = CK_NoOp; - CheckedConversionKind CCK = FunctionalStyle - ? CheckedConversionKind::FunctionalCast - : CheckedConversionKind::CStyleCast; if (tcr == TC_NotApplicable) { tcr = TryAddressSpaceCast(Self, SrcExpr, DestType, /*CStyle*/ true, msg, Kind); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e440f60526bb3..66c233de4ef30 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1236,7 +1236,9 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, bool IsChkVariant = false; auto GetFunctionName = [&]() { - StringRef FunctionName = getASTContext().BuiltinInfo.getName(BuiltinID); + std::string FunctionNameStr = + getASTContext().BuiltinInfo.getName(BuiltinID); + llvm::StringRef FunctionName = FunctionNameStr; // Skim off the details of whichever builtin was called to produce a better // diagnostic, as it's unlikely that the user wrote the __builtin // explicitly. @@ -1246,7 +1248,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, } else { FunctionName.consume_front("__builtin_"); } - return FunctionName; + return FunctionName.str(); }; switch (BuiltinID) { @@ -1290,7 +1292,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, unsigned SourceSize) { DiagID = diag::warn_fortify_scanf_overflow; unsigned Index = ArgIndex + DataIndex; - StringRef FunctionName = GetFunctionName(); + std::string FunctionName = GetFunctionName(); DiagRuntimeBehavior(TheCall->getArg(Index)->getBeginLoc(), TheCall, PDiag(DiagID) << FunctionName << (Index + 1) << DestSize << SourceSize); @@ -1439,7 +1441,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0) return; - StringRef FunctionName = GetFunctionName(); + std::string FunctionName = GetFunctionName(); SmallString<16> DestinationStr; SmallString<16> SourceStr; @@ -2449,7 +2451,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CheckNonNullArgument(*this, TheCall->getArg(0), TheCall->getExprLoc()); break; } -#define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case Builtin::BI##ID: \ return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID); @@ -4584,7 +4585,7 @@ ExprResult Sema::BuiltinAtomicOverloaded(ExprResult TheCallResult) { // Get the decl for the concrete builtin from this, we can tell what the // concrete integer type we should convert to is. unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; - StringRef NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID); + std::string NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID); FunctionDecl *NewBuiltinDecl; if (NewBuiltinID == BuiltinID) NewBuiltinDecl = FDecl; @@ -8379,7 +8380,7 @@ static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType) { bool EmitHeaderHint = true; const char *HeaderName = nullptr; - StringRef FunctionName; + std::string FunctionName; if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) { FunctionName = "std::abs"; if (ArgType->isIntegralOrEnumerationType()) { @@ -8545,7 +8546,7 @@ void Sema::CheckAbsoluteValueFunction(const CallExpr *Call, // Unsigned types cannot be negative. Suggest removing the absolute value // function call. if (ArgType->isUnsignedIntegerType()) { - StringRef FunctionName = + std::string FunctionName = IsStdAbs ? "std::abs" : Context.BuiltinInfo.getName(AbsKind); Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType; Diag(Call->getExprLoc(), diag::note_remove_abs) @@ -14649,11 +14650,23 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) { _2, _3, _4)); } +// Performs a similar job to Sema::UsualUnaryConversions, but without any +// implicit promotion of integral/enumeration types. +static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E) { + // First, convert to an r-value. + ExprResult Res = S.DefaultFunctionArrayLvalueConversion(E); + if (Res.isInvalid()) + return ExprError(); + + // Promote floating-point types. + return S.UsualUnaryFPConversions(Res.get()); +} + bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) { if (checkArgCount(TheCall, 1)) return true; - ExprResult A = UsualUnaryConversions(TheCall->getArg(0)); + ExprResult A = BuiltinVectorMathConversions(*this, TheCall->getArg(0)); if (A.isInvalid()) return true; @@ -14668,57 +14681,77 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) { } bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) { - QualType Res; - if (BuiltinVectorMath(TheCall, Res, FPOnly)) - return true; - TheCall->setType(Res); - return false; + if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) { + TheCall->setType(*Res); + return false; + } + return true; } bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) { - QualType Res; - if (BuiltinVectorMath(TheCall, Res)) + std::optional Res = BuiltinVectorMath(TheCall); + if (!Res) return true; - if (auto *VecTy0 = Res->getAs()) + if (auto *VecTy0 = (*Res)->getAs()) TheCall->setType(VecTy0->getElementType()); else - TheCall->setType(Res); + TheCall->setType(*Res); return false; } -bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) { +static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, + SourceLocation Loc) { + QualType L = LHS->getEnumCoercedType(S.Context), + R = RHS->getEnumCoercedType(S.Context); + if (L->isUnscopedEnumerationType() && R->isUnscopedEnumerationType() && + !S.Context.hasSameUnqualifiedType(L, R)) { + return S.Diag(Loc, diag::err_conv_mixed_enum_types_cxx26) + << LHS->getSourceRange() << RHS->getSourceRange() + << /*Arithmetic Between*/ 0 << L << R; + } + return false; +} + +std::optional Sema::BuiltinVectorMath(CallExpr *TheCall, + bool FPOnly) { if (checkArgCount(TheCall, 2)) - return true; + return std::nullopt; - ExprResult A = TheCall->getArg(0); - ExprResult B = TheCall->getArg(1); - // Do standard promotions between the two arguments, returning their common - // type. - Res = UsualArithmeticConversions(A, B, TheCall->getExprLoc(), ACK_Comparison); - if (A.isInvalid() || B.isInvalid()) - return true; + if (checkBuiltinVectorMathMixedEnums( + *this, TheCall->getArg(0), TheCall->getArg(1), TheCall->getExprLoc())) + return std::nullopt; - QualType TyA = A.get()->getType(); - QualType TyB = B.get()->getType(); + Expr *Args[2]; + for (int I = 0; I < 2; ++I) { + ExprResult Converted = + BuiltinVectorMathConversions(*this, TheCall->getArg(I)); + if (Converted.isInvalid()) + return std::nullopt; + Args[I] = Converted.get(); + } - if (Res.isNull() || TyA.getCanonicalType() != TyB.getCanonicalType()) - return Diag(A.get()->getBeginLoc(), - diag::err_typecheck_call_different_arg_types) - << TyA << TyB; + SourceLocation LocA = Args[0]->getBeginLoc(); + QualType TyA = Args[0]->getType(); + QualType TyB = Args[1]->getType(); + + if (TyA.getCanonicalType() != TyB.getCanonicalType()) { + Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB; + return std::nullopt; + } if (FPOnly) { - if (checkFPMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1)) - return true; + if (checkFPMathBuiltinElementType(*this, LocA, TyA, 1)) + return std::nullopt; } else { - if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1)) - return true; + if (checkMathBuiltinElementType(*this, LocA, TyA, 1)) + return std::nullopt; } - TheCall->setArg(0, A.get()); - TheCall->setArg(1, B.get()); - return false; + TheCall->setArg(0, Args[0]); + TheCall->setArg(1, Args[1]); + return TyA; } bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall, @@ -14726,9 +14759,17 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall, if (checkArgCount(TheCall, 3)) return true; + SourceLocation Loc = TheCall->getExprLoc(); + if (checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(0), + TheCall->getArg(1), Loc) || + checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(1), + TheCall->getArg(2), Loc)) + return true; + Expr *Args[3]; for (int I = 0; I < 3; ++I) { - ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I)); + ExprResult Converted = + BuiltinVectorMathConversions(*this, TheCall->getArg(I)); if (Converted.isInvalid()) return true; Args[I] = Converted.get(); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 58f3efbe0daf8..80ae87e7c5725 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -137,7 +137,7 @@ class ResultBuilder { ~ShadowMapEntry() { if (DeclIndexPairVector *Vec = - DeclOrVector.dyn_cast()) { + dyn_cast_if_present(DeclOrVector)) { delete Vec; DeclOrVector = ((NamedDecl *)nullptr); } @@ -678,7 +678,7 @@ class ResultBuilder::ShadowMapEntry::iterator { }*/ reference operator*() const { - if (const NamedDecl *ND = DeclOrIterator.dyn_cast()) + if (const NamedDecl *ND = dyn_cast(DeclOrIterator)) return reference(ND, SingleDeclIndex); return *cast(DeclOrIterator); @@ -5796,24 +5796,11 @@ QualType getApproximateType(const Expr *E, HeuristicResolver &Resolver) { return QualType(Common, 0); } } - // A dependent member: approximate-resolve the base, then lookup. + // A dependent member: resolve using HeuristicResolver. if (const auto *CDSME = llvm::dyn_cast(E)) { - QualType Base = CDSME->isImplicitAccess() - ? CDSME->getBaseType() - : getApproximateType(CDSME->getBase(), Resolver); - if (CDSME->isArrow() && !Base.isNull()) - Base = Base->getPointeeType(); // could handle unique_ptr etc here? - auto *RD = - Base.isNull() - ? nullptr - : llvm::dyn_cast_or_null(getAsRecordDecl(Base)); - if (RD && RD->isCompleteDefinition()) { - // Look up member heuristically, including in bases. - for (const auto *Member : RD->lookupDependentName( - CDSME->getMember(), [](const NamedDecl *Member) { - return llvm::isa(Member); - })) { - return llvm::cast(Member)->getType().getNonReferenceType(); + for (const auto *Member : Resolver.resolveMemberExpr(CDSME)) { + if (const auto *VD = dyn_cast(Member)) { + return VD->getType().getNonReferenceType(); } } } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ad49eac66e98e..6eedc77ed20a0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6681,7 +6681,10 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, DiagnoseFunctionSpecifiers(D.getDeclSpec()); if (D.getDeclSpec().isInlineSpecified()) - Diag(D.getDeclSpec().getInlineSpecLoc(), diag::err_inline_non_function) + Diag(D.getDeclSpec().getInlineSpecLoc(), + (getLangOpts().MSVCCompat && !getLangOpts().CPlusPlus) + ? diag::warn_ms_inline_non_function + : diag::err_inline_non_function) << getLangOpts().CPlusPlus17; if (D.getDeclSpec().hasConstexprSpecifier()) Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr) @@ -11380,8 +11383,11 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, return true; // Only allow transition to MultiVersion if it hasn't been used. - if (OldFD && CausesMV && OldFD->isUsed(false)) - return S.Diag(NewFD->getLocation(), diag::err_multiversion_after_used); + if (OldFD && CausesMV && OldFD->isUsed(false)) { + S.Diag(NewFD->getLocation(), diag::err_multiversion_after_used); + S.Diag(OldFD->getLocation(), diag::note_previous_declaration); + return true; + } return S.areMultiversionVariantFunctionsCompatible( OldFD, NewFD, S.PDiag(diag::err_multiversion_noproto), @@ -13374,6 +13380,62 @@ void Sema::checkNonTrivialCUnion(QualType QT, SourceLocation Loc, .visit(QT, nullptr, false); } +bool Sema::GloballyUniqueObjectMightBeAccidentallyDuplicated( + const VarDecl *Dcl) { + if (!getLangOpts().CPlusPlus) + return false; + + // We only need to warn if the definition is in a header file, so wait to + // diagnose until we've seen the definition. + if (!Dcl->isThisDeclarationADefinition()) + return false; + + // If an object is defined in a source file, its definition can't get + // duplicated since it will never appear in more than one TU. + if (Dcl->getASTContext().getSourceManager().isInMainFile(Dcl->getLocation())) + return false; + + // If the variable we're looking at is a static local, then we actually care + // about the properties of the function containing it. + const ValueDecl *Target = Dcl; + // VarDecls and FunctionDecls have different functions for checking + // inline-ness, so we have to do it manually. + bool TargetIsInline = Dcl->isInline(); + + // Update the Target and TargetIsInline property if necessary + if (Dcl->isStaticLocal()) { + const DeclContext *Ctx = Dcl->getDeclContext(); + if (!Ctx) + return false; + + const FunctionDecl *FunDcl = + dyn_cast_if_present(Ctx->getNonClosureAncestor()); + if (!FunDcl) + return false; + + Target = FunDcl; + // IsInlined() checks for the C++ inline property + TargetIsInline = FunDcl->isInlined(); + } + + // Non-inline variables can only legally appear in one TU + // FIXME: This also applies to templated variables, but that can rarely lead + // to false positives so templates are disabled for now. + if (!TargetIsInline) + return false; + + // If the object isn't hidden, the dynamic linker will prevent duplication. + clang::LinkageInfo Lnk = Target->getLinkageAndVisibility(); + if (Lnk.getVisibility() != HiddenVisibility) + return false; + + // If the obj doesn't have external linkage, it's supposed to be duplicated. + if (!isExternalFormalLinkage(Lnk.getLinkage())) + return false; + + return true; +} + void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // If there is no declaration, there was an error parsing it. Just ignore // the initializer. @@ -14780,6 +14842,51 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) { if (DC->getRedeclContext()->isFileContext() && VD->isExternallyVisible()) AddPushedVisibilityAttribute(VD); + // If this object has external linkage and hidden visibility, it might be + // duplicated when built into a shared library, which causes problems if it's + // mutable (since the copies won't be in sync) or its initialization has side + // effects (since it will run once per copy instead of once globally) + // FIXME: Windows uses dllexport/dllimport instead of visibility, and we don't + // handle that yet. Disable the warning on Windows for now. + // FIXME: Checking templates can cause false positives if the template in + // question is never instantiated (e.g. only specialized templates are used). + if (!Context.getTargetInfo().shouldDLLImportComdatSymbols() && + !VD->isTemplated() && + GloballyUniqueObjectMightBeAccidentallyDuplicated(VD)) { + // Check mutability. For pointers, ensure that both the pointer and the + // pointee are (recursively) const. + QualType Type = VD->getType().getNonReferenceType(); + if (!Type.isConstant(VD->getASTContext())) { + Diag(VD->getLocation(), diag::warn_possible_object_duplication_mutable) + << VD; + } else { + while (Type->isPointerType()) { + Type = Type->getPointeeType(); + if (Type->isFunctionType()) + break; + if (!Type.isConstant(VD->getASTContext())) { + Diag(VD->getLocation(), + diag::warn_possible_object_duplication_mutable) + << VD; + break; + } + } + } + + // To keep false positives low, only warn if we're certain that the + // initializer has side effects. Don't warn on operator new, since a mutable + // pointer will trigger the previous warning, and an immutable pointer + // getting duplicated just results in a little extra memory usage. + const Expr *Init = VD->getAnyInitializer(); + if (Init && + Init->HasSideEffects(VD->getASTContext(), + /*IncludePossibleEffects=*/false) && + !isa(Init->IgnoreParenImpCasts())) { + Diag(Init->getExprLoc(), diag::warn_possible_object_duplication_init) + << VD; + } + } + // FIXME: Warn on unused var template partial specializations. if (VD->isFileVarDecl() && !isa(VD)) MarkUnusedFileScopedDecl(VD); @@ -16016,7 +16123,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (!FD->isDeletedAsWritten()) FD->setBody(Body); FD->setWillHaveBody(false); - CheckImmediateEscalatingFunctionDefinition(FD, FSI); if (getLangOpts().CPlusPlus14) { if (!FD->isInvalidDecl() && Body && !FD->isDependentContext() && @@ -16394,6 +16500,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // the declaration context below. Otherwise, we're unable to transform // 'this' expressions when transforming immediate context functions. + if (FD) + CheckImmediateEscalatingFunctionDefinition(FD, getCurFunction()); + if (!IsInstantiation) PopDeclContext(); @@ -17700,9 +17809,11 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, return PrevTagDecl; QualType EnumUnderlyingTy; - if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast()) + if (TypeSourceInfo *TI = + dyn_cast_if_present(EnumUnderlying)) EnumUnderlyingTy = TI->getType().getUnqualifiedType(); - else if (const Type *T = EnumUnderlying.dyn_cast()) + else if (const Type *T = + dyn_cast_if_present(EnumUnderlying)) EnumUnderlyingTy = QualType(T, 0); // All conflicts with previous declarations are recovered by @@ -19522,23 +19633,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, ProcessAPINotes(Record); } -/// Determine whether the given integral value is representable within -/// the given type T. -static bool isRepresentableIntegerValue(ASTContext &Context, - llvm::APSInt &Value, - QualType T) { - assert((T->isIntegralType(Context) || T->isEnumeralType()) && - "Integral type required!"); - unsigned BitWidth = Context.getIntWidth(T); - - if (Value.isUnsigned() || Value.isNonNegative()) { - if (T->isSignedIntegerOrEnumerationType()) - --BitWidth; - return Value.getActiveBits() <= BitWidth; - } - return Value.getSignificantBits() <= BitWidth; -} - // Given an integral type, return the next larger integral type // (or a NULL type of no such type exists). static QualType getNextLargerIntegralType(ASTContext &Context, QualType T) { @@ -19612,7 +19706,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, // representable in the underlying type of the enumeration. In C++11, // we perform a non-narrowing conversion as part of converted constant // expression checking. - if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) { + if (!Context.isRepresentableIntegerValue(EnumVal, EltTy)) { if (Context.getTargetInfo() .getTriple() .isWindowsMSVCEnvironment()) { @@ -19641,7 +19735,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, // representable as an int. // Complain if the value is not representable in an int. - if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy)) { + if (!Context.isRepresentableIntegerValue(EnumVal, Context.IntTy)) { Diag(IdLoc, getLangOpts().C23 ? diag::warn_c17_compat_enum_value_not_int : diag::ext_c23_enum_value_not_int) @@ -19733,7 +19827,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, : diag::ext_c23_enum_value_not_int) << 1 << toString(EnumVal, 10) << 1; } else if (!getLangOpts().CPlusPlus && !EltTy->isDependentType() && - !isRepresentableIntegerValue(Context, EnumVal, EltTy)) { + !Context.isRepresentableIntegerValue(EnumVal, EltTy)) { // Enforce C99 6.7.2.2p2 even when we compute the next value. Diag(IdLoc, getLangOpts().C23 ? diag::warn_c17_compat_enum_value_not_int : diag::ext_c23_enum_value_not_int) @@ -19959,7 +20053,7 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef Elements, continue; DeclOrVector& Entry = Iter->second; - if (EnumConstantDecl *D = Entry.dyn_cast()) { + if (EnumConstantDecl *D = dyn_cast(Entry)) { // Ensure constants are different. if (D == ECD) continue; @@ -20060,35 +20154,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, // reverse the list. unsigned NumNegativeBits = 0; unsigned NumPositiveBits = 0; - bool MembersRepresentableByInt = true; - - for (unsigned i = 0, e = Elements.size(); i != e; ++i) { - EnumConstantDecl *ECD = - cast_or_null(Elements[i]); - if (!ECD) continue; // Already issued a diagnostic. - - llvm::APSInt InitVal = ECD->getInitVal(); - - // Keep track of the size of positive and negative values. - if (InitVal.isUnsigned() || InitVal.isNonNegative()) { - // If the enumerator is zero that should still be counted as a positive - // bit since we need a bit to store the value zero. - unsigned ActiveBits = InitVal.getActiveBits(); - NumPositiveBits = std::max({NumPositiveBits, ActiveBits, 1u}); - } else { - NumNegativeBits = - std::max(NumNegativeBits, (unsigned)InitVal.getSignificantBits()); - } - MembersRepresentableByInt &= - isRepresentableIntegerValue(Context, InitVal, Context.IntTy); - } - - // If we have an empty set of enumerators we still need one bit. - // From [dcl.enum]p8 - // If the enumerator-list is empty, the values of the enumeration are as if - // the enumeration had a single enumerator with value 0 - if (!NumPositiveBits && !NumNegativeBits) - NumPositiveBits = 1; + bool MembersRepresentableByInt = + Context.computeEnumBits(Elements, NumNegativeBits, NumPositiveBits); // Figure out the type that should be used for this enum. QualType BestType; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index c2d82b9aa9b32..527db176cf8dd 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -879,22 +879,38 @@ static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg)) return; - StringRef DiagTypeStr; - if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr)) + StringRef DefaultSevStr; + if (!S.checkStringLiteralArgumentAttr(AL, 2, DefaultSevStr)) return; - DiagnoseIfAttr::DiagnosticType DiagType; - if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) { + DiagnoseIfAttr::DefaultSeverity DefaultSev; + if (!DiagnoseIfAttr::ConvertStrToDefaultSeverity(DefaultSevStr, DefaultSev)) { S.Diag(AL.getArgAsExpr(2)->getBeginLoc(), diag::err_diagnose_if_invalid_diagnostic_type); return; } + StringRef WarningGroup; + SmallVector Options; + if (AL.getNumArgs() > 3) { + if (!S.checkStringLiteralArgumentAttr(AL, 3, WarningGroup)) + return; + if (WarningGroup.empty() || + !S.getDiagnostics().getDiagnosticIDs()->getGroupForWarningOption( + WarningGroup)) { + S.Diag(AL.getArgAsExpr(3)->getBeginLoc(), + diag::err_diagnose_if_unknown_warning) + << WarningGroup; + return; + } + } + bool ArgDependent = false; if (const auto *FD = dyn_cast(D)) ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond); D->addAttr(::new (S.Context) DiagnoseIfAttr( - S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast(D))); + S.Context, AL, Cond, Msg, DefaultSev, WarningGroup, ArgDependent, + cast(D))); } static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) { @@ -3057,7 +3073,8 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) { if (ParsedAttrs.BranchProtection.empty()) return false; if (!Context.getTargetInfo().validateBranchProtection( - ParsedAttrs.BranchProtection, ParsedAttrs.CPU, BPI, DiagMsg)) { + ParsedAttrs.BranchProtection, ParsedAttrs.CPU, BPI, + Context.getLangOpts(), DiagMsg)) { if (DiagMsg.empty()) return Diag(LiteralLoc, diag::warn_unsupported_target_attribute) << Unsupported << None << "branch-protection" << Target; @@ -7467,6 +7484,15 @@ void Sema::ProcessDeclAttributeList( } } + // Do not permit 'constructor' or 'destructor' attributes on __device__ code. + if (getLangOpts().CUDAIsDevice && D->hasAttr() && + (D->hasAttr() || D->hasAttr()) && + !getLangOpts().GPUAllowDeviceInit) { + Diag(D->getLocation(), diag::err_cuda_ctor_dtor_attrs) + << (D->hasAttr() ? "constructors" : "destructors"); + D->setInvalidDecl(); + } + // Do this check after processing D's attributes because the attribute // objc_method_family can change whether the given method is in the init // family, and it can be applied after objc_designated_initializer. This is a diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 839b3a1cccdcc..0cf02fe6407c2 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -888,7 +888,15 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, Previous.clear(); } - auto *BD = BindingDecl::Create(Context, DC, B.NameLoc, VarName); + QualType QT; + if (B.EllipsisLoc.isValid()) { + if (!cast(DC)->isTemplated()) + Diag(B.EllipsisLoc, diag::err_pack_outside_template); + QT = Context.getPackExpansionType(Context.DependentTy, std::nullopt, + /*ExpectsPackInType=*/false); + } + + auto *BD = BindingDecl::Create(Context, DC, B.NameLoc, B.Name, QT); ProcessDeclAttributeList(S, BD, *B.Attrs); @@ -951,20 +959,68 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, return New; } +// Check the arity of the structured bindings. +// Create the resolved pack expr if needed. +static bool CheckBindingsCount(Sema &S, DecompositionDecl *DD, + QualType DecompType, + ArrayRef Bindings, + unsigned MemberCount) { + auto BindingWithPackItr = + std::find_if(Bindings.begin(), Bindings.end(), + [](BindingDecl *D) -> bool { return D->isParameterPack(); }); + bool HasPack = BindingWithPackItr != Bindings.end(); + bool IsValid; + if (!HasPack) { + IsValid = Bindings.size() == MemberCount; + } else { + // There may not be more members than non-pack bindings. + IsValid = MemberCount >= Bindings.size() - 1; + } + + if (IsValid && HasPack) { + // Create the pack expr and assign it to the binding. + unsigned PackSize = MemberCount - Bindings.size() + 1; + QualType PackType = S.Context.getPackExpansionType( + S.Context.DependentTy, std::nullopt, /*ExpectsPackInType=*/false); + BindingDecl *BD = (*BindingWithPackItr); + auto *RP = ResolvedUnexpandedPackExpr::Create(S.Context, DD->getBeginLoc(), + DecompType, PackSize); + BD->setDecomposedDecl(DD); + BD->setBinding(PackType, RP); + + BindingDecl *BPack = *BindingWithPackItr; + // Create the nested BindingDecls. + for (Expr *&E : RP->getExprs()) { + auto *NestedBD = BindingDecl::Create(S.Context, BPack->getDeclContext(), + BPack->getLocation(), + BPack->getIdentifier(), QualType()); + NestedBD->setDecomposedDecl(DD); + E = S.BuildDeclRefExpr(NestedBD, S.Context.DependentTy, VK_LValue, + BPack->getLocation()); + } + } + + if (IsValid) + return false; + + S.Diag(DD->getLocation(), diag::err_decomp_decl_wrong_number_bindings) + << DecompType << (unsigned)Bindings.size() << MemberCount << MemberCount + << (MemberCount < Bindings.size()); + return true; +} + static bool checkSimpleDecomposition( Sema &S, ArrayRef Bindings, ValueDecl *Src, - QualType DecompType, const llvm::APSInt &NumElems, QualType ElemType, + QualType DecompType, const llvm::APSInt &NumElemsAPS, QualType ElemType, llvm::function_ref GetInit) { - if ((int64_t)Bindings.size() != NumElems) { - S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings) - << DecompType << (unsigned)Bindings.size() - << (unsigned)NumElems.getLimitedValue(UINT_MAX) - << toString(NumElems, 10) << (NumElems < Bindings.size()); + unsigned NumElems = (unsigned)NumElemsAPS.getLimitedValue(UINT_MAX); + auto *DD = cast(Src); + + if (CheckBindingsCount(S, DD, DecompType, Bindings, NumElems)) return true; - } unsigned I = 0; - for (auto *B : Bindings) { + for (auto *B : DD->flat_bindings()) { SourceLocation Loc = B->getLocation(); ExprResult E = S.BuildDeclRefExpr(Src, DecompType, VK_LValue, Loc); if (E.isInvalid()) @@ -1210,13 +1266,10 @@ static bool checkTupleLikeDecomposition(Sema &S, ArrayRef Bindings, VarDecl *Src, QualType DecompType, const llvm::APSInt &TupleSize) { - if ((int64_t)Bindings.size() != TupleSize) { - S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings) - << DecompType << (unsigned)Bindings.size() - << (unsigned)TupleSize.getLimitedValue(UINT_MAX) - << toString(TupleSize, 10) << (TupleSize < Bindings.size()); + auto *DD = cast(Src); + unsigned NumElems = (unsigned)TupleSize.getLimitedValue(UINT_MAX); + if (CheckBindingsCount(S, DD, DecompType, Bindings, NumElems)) return true; - } if (Bindings.empty()) return false; @@ -1250,7 +1303,7 @@ static bool checkTupleLikeDecomposition(Sema &S, } unsigned I = 0; - for (auto *B : Bindings) { + for (auto *B : DD->flat_bindings()) { InitializingBinding InitContext(S, B); SourceLocation Loc = B->getLocation(); @@ -1433,20 +1486,18 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef Bindings, QualType BaseType = S.Context.getQualifiedType(S.Context.getRecordType(RD), DecompType.getQualifiers()); - auto DiagnoseBadNumberOfBindings = [&]() -> bool { - unsigned NumFields = llvm::count_if( - RD->fields(), [](FieldDecl *FD) { return !FD->isUnnamedBitField(); }); - assert(Bindings.size() != NumFields); - S.Diag(Src->getLocation(), diag::err_decomp_decl_wrong_number_bindings) - << DecompType << (unsigned)Bindings.size() << NumFields << NumFields - << (NumFields < Bindings.size()); + auto *DD = cast(Src); + unsigned NumFields = llvm::count_if( + RD->fields(), [](FieldDecl *FD) { return !FD->isUnnamedBitField(); }); + if (CheckBindingsCount(S, DD, DecompType, Bindings, NumFields)) return true; - }; // all of E's non-static data members shall be [...] well-formed // when named as e.name in the context of the structured binding, // E shall not have an anonymous union member, ... - unsigned I = 0; + auto FlatBindings = DD->flat_bindings(); + assert(llvm::range_size(FlatBindings) == NumFields); + auto FlatBindingsItr = FlatBindings.begin(); for (auto *FD : RD->fields()) { if (FD->isUnnamedBitField()) continue; @@ -1471,9 +1522,8 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef Bindings, } // We have a real field to bind. - if (I >= Bindings.size()) - return DiagnoseBadNumberOfBindings(); - auto *B = Bindings[I++]; + assert(FlatBindingsItr != FlatBindings.end()); + BindingDecl *B = *(FlatBindingsItr++); SourceLocation Loc = B->getLocation(); // The field must be accessible in the context of the structured binding. @@ -1511,9 +1561,6 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef Bindings, B->setBinding(S.BuildQualifiedType(FD->getType(), Loc, Q), E.get()); } - if (I != Bindings.size()) - return DiagnoseBadNumberOfBindings(); - return false; } @@ -1523,8 +1570,12 @@ void Sema::CheckCompleteDecompositionDeclaration(DecompositionDecl *DD) { // If the type of the decomposition is dependent, then so is the type of // each binding. if (DecompType->isDependentType()) { - for (auto *B : DD->bindings()) - B->setType(Context.DependentTy); + // Note that all of the types are still Null or PackExpansionType. + for (auto *B : DD->bindings()) { + // Do not overwrite any pack type. + if (B->getType().isNull()) + B->setType(Context.DependentTy); + } return; } @@ -3316,6 +3367,29 @@ void Sema::CheckShadowInheritedFields(const SourceLocation &Loc, } } +template +inline static bool HasAttribute(const QualType &T) { + if (const TagDecl *TD = T->getAsTagDecl()) + return TD->hasAttr(); + if (const TypedefType *TDT = T->getAs()) + return TDT->getDecl()->hasAttr(); + return false; +} + +static bool IsUnusedPrivateField(const FieldDecl *FD) { + if (FD->getAccess() == AS_private && FD->getDeclName()) { + QualType FieldType = FD->getType(); + if (HasAttribute(FieldType)) + return true; + + return !FD->isImplicit() && !FD->hasAttr() && + !FD->getParent()->isDependentContext() && + !HasAttribute(FieldType) && + !InitializationHasSideEffects(*FD); + } + return false; +} + NamedDecl * Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, @@ -3598,25 +3672,11 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, FieldDecl *FD = cast(Member); FieldCollector->Add(FD); - if (!Diags.isIgnored(diag::warn_unused_private_field, FD->getLocation())) { + if (!Diags.isIgnored(diag::warn_unused_private_field, FD->getLocation()) && + IsUnusedPrivateField(FD)) { // Remember all explicit private FieldDecls that have a name, no side // effects and are not part of a dependent type declaration. - - auto DeclHasUnusedAttr = [](const QualType &T) { - if (const TagDecl *TD = T->getAsTagDecl()) - return TD->hasAttr(); - if (const TypedefType *TDT = T->getAs()) - return TDT->getDecl()->hasAttr(); - return false; - }; - - if (!FD->isImplicit() && FD->getDeclName() && - FD->getAccess() == AS_private && - !FD->hasAttr() && - !FD->getParent()->isDependentContext() && - !DeclHasUnusedAttr(FD->getType()) && - !InitializationHasSideEffects(*FD)) - UnusedPrivateFields.insert(FD); + UnusedPrivateFields.insert(FD); } } @@ -9235,7 +9295,7 @@ struct SpecialMemberVisitor { static SourceLocation getSubobjectLoc(Subobject Subobj) { // FIXME: For an indirect virtual base, the direct base leading to // the indirect virtual base would be a more useful choice. - if (auto *B = Subobj.dyn_cast()) + if (auto *B = dyn_cast(Subobj)) return B->getBaseTypeLoc(); else return cast(Subobj)->getLocation(); @@ -13406,8 +13466,6 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, UnqualifiedId &Name, const ParsedAttributesView &AttrList, TypeResult Type, Decl *DeclFromDeclSpec) { - // Get the innermost enclosing declaration scope. - S = S->getDeclParent(); if (Type.isInvalid()) return nullptr; @@ -13458,6 +13516,9 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS, CheckTypedefForVariablyModifiedType(S, NewTD); Invalid |= NewTD->isInvalidDecl(); + // Get the innermost enclosing declaration scope. + S = S->getDeclParent(); + bool Redeclaration = false; NamedDecl *NewND; @@ -13854,8 +13915,7 @@ void Sema::setupImplicitSpecialMemberType(CXXMethodDecl *SpecialMem, // During template instantiation of implicit special member functions we need // a reliable TypeSourceInfo for the function prototype in order to allow // functions to be substituted. - if (inTemplateInstantiation() && - cast(SpecialMem->getParent())->isLambda()) { + if (inTemplateInstantiation() && isLambdaMethod(SpecialMem)) { TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(SpecialMem->getType()); SpecialMem->setTypeSourceInfo(TSI); @@ -17524,7 +17584,7 @@ DeclResult Sema::ActOnTemplatedFriendTag( unsigned FriendDeclDepth = TempParamLists.front()->getDepth(); for (UnexpandedParameterPack &U : Unexpanded) { if (getDepthAndIndex(U).first >= FriendDeclDepth) { - auto *ND = U.first.dyn_cast(); + auto *ND = dyn_cast(U.first); if (!ND) ND = cast(U.first)->getDecl(); Diag(U.second, diag::friend_template_decl_malformed_pack_expansion) diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index f97f17e8c9658..e665d0293dc84 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1584,7 +1584,7 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers( const char* prevSpec; // unused unsigned diagID; // unused QualType type; - if (auto *actualTypeDecl = typeDecl.dyn_cast()) + if (auto *actualTypeDecl = dyn_cast(typeDecl)) type = Context.getTypeDeclType(actualTypeDecl); else type = Context.getObjCInterfaceType(cast(typeDecl)); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 470d0d753b558..77a1bbcc74e50 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1068,7 +1068,7 @@ static CanThrowResult canVarDeclThrow(Sema &Self, const VarDecl *VD) { // If this is a decomposition declaration, bindings might throw. if (auto *DD = dyn_cast(VD)) - for (auto *B : DD->bindings()) + for (auto *B : DD->flat_bindings()) if (auto *HD = B->getHoldingVar()) CT = mergeCanThrow(CT, canVarDeclThrow(Self, HD)); @@ -1286,6 +1286,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::ConvertVectorExprClass: case Expr::VAArgExprClass: case Expr::CXXParenListInitExprClass: + case Expr::ResolvedUnexpandedPackExprClass: return canSubStmtsThrow(*this, S); case Expr::CompoundLiteralExprClass: @@ -1424,6 +1425,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OpenACCCombinedConstructClass: case Stmt::OpenACCDataConstructClass: case Stmt::OpenACCHostDataConstructClass: + case Stmt::OpenACCAtomicConstructClass: case Stmt::AttributedStmtClass: case Stmt::BreakStmtClass: case Stmt::CapturedStmtClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d5273d463d7c0..3cd4010740d19 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -776,20 +776,11 @@ ExprResult Sema::CallExprUnaryConversions(Expr *E) { return Res.get(); } -/// UsualUnaryConversions - Performs various conversions that are common to most -/// operators (C99 6.3). The conversions of array and function types are -/// sometimes suppressed. For example, the array->pointer conversion doesn't -/// apply if the array is an argument to the sizeof or address (&) operators. -/// In these instances, this routine should *not* be called. -ExprResult Sema::UsualUnaryConversions(Expr *E) { - // First, convert to an r-value. - ExprResult Res = DefaultFunctionArrayLvalueConversion(E); - if (Res.isInvalid()) - return ExprError(); - E = Res.get(); - +/// UsualUnaryFPConversions - Promotes floating-point types according to the +/// current language semantics. +ExprResult Sema::UsualUnaryFPConversions(Expr *E) { QualType Ty = E->getType(); - assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); + assert(!Ty.isNull() && "UsualUnaryFPConversions - missing type"); LangOptions::FPEvalMethodKind EvalMethod = CurFPFeatures.getFPEvalMethod(); if (EvalMethod != LangOptions::FEM_Source && Ty->isFloatingType() && @@ -827,7 +818,30 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) { // Half FP have to be promoted to float unless it is natively supported if (Ty->isHalfType() && !getLangOpts().NativeHalfType) - return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast); + return ImpCastExprToType(E, Context.FloatTy, CK_FloatingCast); + + return E; +} + +/// UsualUnaryConversions - Performs various conversions that are common to most +/// operators (C99 6.3). The conversions of array and function types are +/// sometimes suppressed. For example, the array->pointer conversion doesn't +/// apply if the array is an argument to the sizeof or address (&) operators. +/// In these instances, this routine should *not* be called. +ExprResult Sema::UsualUnaryConversions(Expr *E) { + // First, convert to an r-value. + ExprResult Res = DefaultFunctionArrayLvalueConversion(E); + if (Res.isInvalid()) + return ExprError(); + + // Promote floating-point types. + Res = UsualUnaryFPConversions(Res.get()); + if (Res.isInvalid()) + return ExprError(); + E = Res.get(); + + QualType Ty = E->getType(); + assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); // Try to perform integral promotions if the object has a theoretically // promotable type. @@ -1489,9 +1503,9 @@ static QualType handleFixedPointConversion(Sema &S, QualType LHSTy, /// Check that the usual arithmetic conversions can be performed on this pair of /// expressions that might be of enumeration type. -static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS, - SourceLocation Loc, - Sema::ArithConvKind ACK) { +void Sema::checkEnumArithmeticConversions(Expr *LHS, Expr *RHS, + SourceLocation Loc, + Sema::ArithConvKind ACK) { // C++2a [expr.arith.conv]p1: // If one operand is of enumeration type and the other operand is of a // different enumeration type or a floating-point type, this behavior is @@ -1499,54 +1513,53 @@ static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS, // // Warn on this in all language modes. Produce a deprecation warning in C++20. // Eventually we will presumably reject these cases (in C++23 onwards?). - QualType L = LHS->getEnumCoercedType(S.Context), - R = RHS->getEnumCoercedType(S.Context); + QualType L = LHS->getEnumCoercedType(Context), + R = RHS->getEnumCoercedType(Context); bool LEnum = L->isUnscopedEnumerationType(), REnum = R->isUnscopedEnumerationType(); bool IsCompAssign = ACK == Sema::ACK_CompAssign; if ((!IsCompAssign && LEnum && R->isFloatingType()) || (REnum && L->isFloatingType())) { - S.Diag(Loc, S.getLangOpts().CPlusPlus26 - ? diag::err_arith_conv_enum_float_cxx26 - : S.getLangOpts().CPlusPlus20 - ? diag::warn_arith_conv_enum_float_cxx20 - : diag::warn_arith_conv_enum_float) + Diag(Loc, getLangOpts().CPlusPlus26 ? diag::err_arith_conv_enum_float_cxx26 + : getLangOpts().CPlusPlus20 + ? diag::warn_arith_conv_enum_float_cxx20 + : diag::warn_arith_conv_enum_float) << LHS->getSourceRange() << RHS->getSourceRange() << (int)ACK << LEnum << L << R; } else if (!IsCompAssign && LEnum && REnum && - !S.Context.hasSameUnqualifiedType(L, R)) { + !Context.hasSameUnqualifiedType(L, R)) { unsigned DiagID; // In C++ 26, usual arithmetic conversions between 2 different enum types // are ill-formed. - if (S.getLangOpts().CPlusPlus26) + if (getLangOpts().CPlusPlus26) DiagID = diag::err_conv_mixed_enum_types_cxx26; else if (!L->castAs()->getDecl()->hasNameForLinkage() || !R->castAs()->getDecl()->hasNameForLinkage()) { // If either enumeration type is unnamed, it's less likely that the // user cares about this, but this situation is still deprecated in // C++2a. Use a different warning group. - DiagID = S.getLangOpts().CPlusPlus20 - ? diag::warn_arith_conv_mixed_anon_enum_types_cxx20 - : diag::warn_arith_conv_mixed_anon_enum_types; + DiagID = getLangOpts().CPlusPlus20 + ? diag::warn_arith_conv_mixed_anon_enum_types_cxx20 + : diag::warn_arith_conv_mixed_anon_enum_types; } else if (ACK == Sema::ACK_Conditional) { // Conditional expressions are separated out because they have // historically had a different warning flag. - DiagID = S.getLangOpts().CPlusPlus20 + DiagID = getLangOpts().CPlusPlus20 ? diag::warn_conditional_mixed_enum_types_cxx20 : diag::warn_conditional_mixed_enum_types; } else if (ACK == Sema::ACK_Comparison) { // Comparison expressions are separated out because they have // historically had a different warning flag. - DiagID = S.getLangOpts().CPlusPlus20 + DiagID = getLangOpts().CPlusPlus20 ? diag::warn_comparison_mixed_enum_types_cxx20 : diag::warn_comparison_mixed_enum_types; } else { - DiagID = S.getLangOpts().CPlusPlus20 + DiagID = getLangOpts().CPlusPlus20 ? diag::warn_arith_conv_mixed_enum_types_cxx20 : diag::warn_arith_conv_mixed_enum_types; } - S.Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange() - << (int)ACK << L << R; + Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange() + << (int)ACK << L << R; } } @@ -1557,7 +1570,7 @@ static void checkEnumArithmeticConversions(Sema &S, Expr *LHS, Expr *RHS, QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK) { - checkEnumArithmeticConversions(*this, LHS.get(), RHS.get(), Loc, ACK); + checkEnumArithmeticConversions(LHS.get(), RHS.get(), Loc, ACK); if (ACK != ACK_CompAssign) { LHS = UsualUnaryConversions(LHS.get()); @@ -6682,7 +6695,7 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, Expr *Sema::BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, MultiExprArg CallArgs) { - StringRef Name = Context.BuiltinInfo.getName(Id); + std::string Name = Context.BuiltinInfo.getName(Id); LookupResult R(*this, &Context.Idents.get(Name), Loc, Sema::LookupOrdinaryName); LookupName(R, TUScope, /*AllowBuiltinCreation=*/true); @@ -7503,7 +7516,7 @@ static bool breakDownVectorType(QualType type, uint64_t &len, if (const VectorType *vecType = type->getAs()) { len = vecType->getNumElements(); eltType = vecType->getElementType(); - assert(eltType->isScalarType()); + assert(eltType->isScalarType() || eltType->isMFloat8Type()); return true; } @@ -10174,6 +10187,11 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, return HLSL().handleVectorBinOpConversion(LHS, RHS, LHSType, RHSType, IsCompAssign); + // Any operation with MFloat8 type is only possible with C intrinsics + if ((LHSVecType && LHSVecType->getElementType()->isMFloat8Type()) || + (RHSVecType && RHSVecType->getElementType()->isMFloat8Type())) + return InvalidOperands(Loc, LHS, RHS); + // AltiVec-style "vector bool op vector bool" combinations are allowed // for some operators but not others. if (!AllowBothBool && LHSVecType && @@ -11793,7 +11811,7 @@ static std::optional isTautologicalBoundsCheck(Sema &S, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opc) { if (!LHS->getType()->isPointerType() || - S.getLangOpts().isSignedOverflowDefined()) + S.getLangOpts().PointerOverflowDefined) return std::nullopt; // Canonicalize to >= or < predicate. diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 1e39d69e8b230..34219e0235a74 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -5032,7 +5032,6 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, case UTT_IsArray: case UTT_IsBoundedArray: case UTT_IsPointer: - case UTT_IsReferenceable: case UTT_IsLvalueReference: case UTT_IsRvalueReference: case UTT_IsMemberFunctionPointer: @@ -5679,8 +5678,6 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, return T.isTriviallyRelocatableType(C); case UTT_IsBitwiseCloneable: return T.isBitwiseCloneableType(C); - case UTT_IsReferenceable: - return T.isReferenceable(); case UTT_CanPassInRegs: if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers()) return RD->canPassInRegisters(); diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index f26469e6a2f1d..99eb5360ec356 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -25,6 +25,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/ParsedAttr.h" @@ -268,8 +269,11 @@ static bool isZeroSizedArray(const ConstantArrayType *CAT) { return CAT != nullptr; } -// Returns true if the record type is an HLSL resource class -static bool isResourceRecordType(const Type *Ty) { +// Returns true if the record type is an HLSL resource class or an array of +// resource classes +static bool isResourceRecordTypeOrArrayOf(const Type *Ty) { + while (const ConstantArrayType *CAT = dyn_cast(Ty)) + Ty = CAT->getArrayElementTypeNoTypeQual(); return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr; } @@ -278,15 +282,15 @@ static bool isResourceRecordType(const Type *Ty) { // array, or a builtin intangible type. Returns false it is a valid leaf element // type or if it is a record type that needs to be inspected further. static bool isInvalidConstantBufferLeafElementType(const Type *Ty) { - if (Ty->isRecordType()) { - if (isResourceRecordType(Ty) || Ty->getAsCXXRecordDecl()->isEmpty()) - return true; - return false; - } + Ty = Ty->getUnqualifiedDesugaredType(); + if (isResourceRecordTypeOrArrayOf(Ty)) + return true; + if (Ty->isRecordType()) + return Ty->getAsCXXRecordDecl()->isEmpty(); if (Ty->isConstantArrayType() && isZeroSizedArray(cast(Ty))) return true; - if (Ty->isHLSLBuiltinIntangibleType()) + if (Ty->isHLSLBuiltinIntangibleType() || Ty->isHLSLAttributedResourceType()) return true; return false; } @@ -338,7 +342,7 @@ static IdentifierInfo *getHostLayoutStructName(Sema &S, NamedDecl *BaseDecl, ASTContext &AST = S.getASTContext(); IdentifierInfo *NameBaseII = BaseDecl->getIdentifier(); - llvm::SmallString<64> Name("__layout_"); + llvm::SmallString<64> Name("__cblayout_"); if (NameBaseII) { Name.append(NameBaseII->getName()); } else { @@ -392,7 +396,7 @@ static FieldDecl *createFieldForHostLayoutStruct(Sema &S, const Type *Ty, auto *Field = FieldDecl::Create(AST, LayoutStruct, SourceLocation(), SourceLocation(), II, QT, TSI, nullptr, false, InClassInitStyle::ICIS_NoInit); - Field->setAccess(AccessSpecifier::AS_private); + Field->setAccess(AccessSpecifier::AS_public); return Field; } @@ -416,14 +420,17 @@ static CXXRecordDecl *createHostLayoutStruct(Sema &S, if (CXXRecordDecl *RD = findRecordDeclInContext(II, DC)) return RD; - CXXRecordDecl *LS = CXXRecordDecl::Create( - AST, TagDecl::TagKind::Class, DC, SourceLocation(), SourceLocation(), II); + CXXRecordDecl *LS = + CXXRecordDecl::Create(AST, TagDecl::TagKind::Struct, DC, SourceLocation(), + SourceLocation(), II); LS->setImplicit(true); + LS->addAttr(PackedAttr::CreateImplicit(AST)); LS->startDefinition(); // copy base struct, create HLSL Buffer compatible version if needed if (unsigned NumBases = StructDecl->getNumBases()) { assert(NumBases == 1 && "HLSL supports only one base type"); + (void)NumBases; CXXBaseSpecifier Base = *StructDecl->bases_begin(); CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); if (requiresImplicitBufferLayoutStructure(BaseDecl)) { @@ -459,30 +466,38 @@ static CXXRecordDecl *createHostLayoutStruct(Sema &S, // Creates host layout struct for HLSL Buffer. The struct will include only // fields of types that are allowed in HLSL buffer and it will filter out: -// - static variable declarations +// - static or groupshared variable declarations // - resource classes // - empty structs // - zero-sized arrays // - non-variable declarations -// The layour struct will be added to the HLSLBufferDecl declarations. +// The layout struct will be added to the HLSLBufferDecl declarations. void createHostLayoutStructForBuffer(Sema &S, HLSLBufferDecl *BufDecl) { ASTContext &AST = S.getASTContext(); IdentifierInfo *II = getHostLayoutStructName(S, BufDecl, true); CXXRecordDecl *LS = - CXXRecordDecl::Create(AST, TagDecl::TagKind::Class, BufDecl, + CXXRecordDecl::Create(AST, TagDecl::TagKind::Struct, BufDecl, SourceLocation(), SourceLocation(), II); + LS->addAttr(PackedAttr::CreateImplicit(AST)); LS->setImplicit(true); LS->startDefinition(); - for (const Decl *D : BufDecl->decls()) { - const VarDecl *VD = dyn_cast(D); - if (!VD || VD->getStorageClass() == SC_Static) + for (Decl *D : BufDecl->decls()) { + VarDecl *VD = dyn_cast(D); + if (!VD || VD->getStorageClass() == SC_Static || + VD->getType().getAddressSpace() == LangAS::hlsl_groupshared) continue; const Type *Ty = VD->getType()->getUnqualifiedDesugaredType(); if (FieldDecl *FD = - createFieldForHostLayoutStruct(S, Ty, VD->getIdentifier(), LS)) + createFieldForHostLayoutStruct(S, Ty, VD->getIdentifier(), LS)) { + // add the field decl to the layout struct LS->addDecl(FD); + // update address space of the original decl to hlsl_constant + QualType NewTy = + AST.getAddrSpaceQualType(VD->getType(), LangAS::hlsl_constant); + VD->setType(NewTy); + } } LS->completeDefinition(); BufDecl->addDecl(LS); @@ -1315,8 +1330,8 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) { // Walks though the global variable declaration, collects all resource binding // requirements and adds them to Bindings -void SemaHLSL::collectResourcesOnUserRecordDecl(const VarDecl *VD, - const RecordType *RT) { +void SemaHLSL::collectResourceBindingsOnUserRecordDecl(const VarDecl *VD, + const RecordType *RT) { const RecordDecl *RD = RT->getDecl(); for (FieldDecl *FD : RD->fields()) { const Type *Ty = FD->getType()->getUnqualifiedDesugaredType(); @@ -1346,15 +1361,15 @@ void SemaHLSL::collectResourcesOnUserRecordDecl(const VarDecl *VD, // binding, which is something we are probably going to need to do later // on. Hopefully nesting of structs in structs too many levels is // unlikely. - collectResourcesOnUserRecordDecl(VD, RT); + collectResourceBindingsOnUserRecordDecl(VD, RT); } } } -// Diagnore localized register binding errors for a single binding; does not +// Diagnose localized register binding errors for a single binding; does not // diagnose resource binding on user record types, that will be done later // in processResourceBindingOnDecl based on the information collected in -// collectResourcesOnVarDecl. +// collectResourceBindingsOnVarDecl. // Returns false if the register binding is not valid. static bool DiagnoseLocalRegisterBinding(Sema &S, SourceLocation &ArgLoc, Decl *D, RegisterType RegType, @@ -2023,6 +2038,18 @@ static bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { checkAllFloatTypes); } +static bool CheckUnsignedIntRepresentations(Sema *S, CallExpr *TheCall) { + auto checkUnsignedInteger = [](clang::QualType PassedType) -> bool { + clang::QualType BaseType = + PassedType->isVectorType() + ? PassedType->getAs()->getElementType() + : PassedType; + return !BaseType->isUnsignedIntegerType(); + }; + return CheckAllArgTypesAreCorrect(S, TheCall, S->Context.UnsignedIntTy, + checkUnsignedInteger); +} + static bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { auto checkFloatorHalf = [](clang::QualType PassedType) -> bool { clang::QualType BaseType = @@ -2214,6 +2241,41 @@ static bool CheckResourceHandle( // returning an ExprError bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { switch (BuiltinID) { + case Builtin::BI__builtin_hlsl_adduint64: { + if (SemaRef.checkArgCount(TheCall, 2)) + return true; + if (CheckVectorElementCallArgs(&SemaRef, TheCall)) + return true; + if (CheckUnsignedIntRepresentations(&SemaRef, TheCall)) + return true; + + // CheckVectorElementCallArgs(...) guarantees both args are the same type. + assert(TheCall->getArg(0)->getType() == TheCall->getArg(1)->getType() && + "Both args must be of the same type"); + + // ensure both args are vectors + auto *VTy = TheCall->getArg(0)->getType()->getAs(); + if (!VTy) { + SemaRef.Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_non_vector) + << "AddUint64" << /*all*/ 1; + return true; + } + + // ensure both args have 2 elements, or both args have 4 elements + int NumElementsArg = VTy->getNumElements(); + if (NumElementsArg != 2 && NumElementsArg != 4) { + SemaRef.Diag(TheCall->getBeginLoc(), + diag::err_invalid_even_odd_vector_element_count) + << NumElementsArg << 2 << 4 << /*even*/ 0 << /*operand*/ 1; + return true; + } + + ExprResult A = TheCall->getArg(0); + QualType ArgTyA = A.get()->getType(); + // return type is the same as the input type + TheCall->setType(ArgTyA); + break; + } case Builtin::BI__builtin_hlsl_resource_getpointer: { if (SemaRef.checkArgCount(TheCall, 2) || CheckResourceHandle(&SemaRef, TheCall, 0) || @@ -2422,6 +2484,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { TheCall->setType(ArgTyA); break; } + case Builtin::BI__builtin_hlsl_wave_active_max: case Builtin::BI__builtin_hlsl_wave_active_sum: { if (SemaRef.checkArgCount(TheCall, 1)) return true; @@ -2697,6 +2760,150 @@ bool SemaHLSL::CheckCompatibleParameterABI(FunctionDecl *New, return HadError; } +// Generally follows PerformScalarCast, with cases reordered for +// clarity of what types are supported +bool SemaHLSL::CanPerformScalarCast(QualType SrcTy, QualType DestTy) { + + if (SemaRef.getASTContext().hasSameUnqualifiedType(SrcTy, DestTy)) + return true; + + switch (SrcTy->getScalarTypeKind()) { + case Type::STK_Bool: // casting from bool is like casting from an integer + case Type::STK_Integral: + switch (DestTy->getScalarTypeKind()) { + case Type::STK_Bool: + case Type::STK_Integral: + case Type::STK_Floating: + return true; + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: + case Type::STK_MemberPointer: + llvm_unreachable("HLSL doesn't support pointers."); + case Type::STK_IntegralComplex: + case Type::STK_FloatingComplex: + llvm_unreachable("HLSL doesn't support complex types."); + case Type::STK_FixedPoint: + llvm_unreachable("HLSL doesn't support fixed point types."); + } + llvm_unreachable("Should have returned before this"); + + case Type::STK_Floating: + switch (DestTy->getScalarTypeKind()) { + case Type::STK_Floating: + case Type::STK_Bool: + case Type::STK_Integral: + return true; + case Type::STK_FloatingComplex: + case Type::STK_IntegralComplex: + llvm_unreachable("HLSL doesn't support complex types."); + case Type::STK_FixedPoint: + llvm_unreachable("HLSL doesn't support fixed point types."); + case Type::STK_CPointer: + case Type::STK_ObjCObjectPointer: + case Type::STK_BlockPointer: + case Type::STK_MemberPointer: + llvm_unreachable("HLSL doesn't support pointers."); + } + llvm_unreachable("Should have returned before this"); + + case Type::STK_MemberPointer: + case Type::STK_CPointer: + case Type::STK_BlockPointer: + case Type::STK_ObjCObjectPointer: + llvm_unreachable("HLSL doesn't support pointers."); + + case Type::STK_FixedPoint: + llvm_unreachable("HLSL doesn't support fixed point types."); + + case Type::STK_FloatingComplex: + case Type::STK_IntegralComplex: + llvm_unreachable("HLSL doesn't support complex types."); + } + + llvm_unreachable("Unhandled scalar cast"); +} + +// Detect if a type contains a bitfield. Will be removed when +// bitfield support is added to HLSLElementwiseCast +bool SemaHLSL::ContainsBitField(QualType BaseTy) { + llvm::SmallVector WorkList; + WorkList.push_back(BaseTy); + while (!WorkList.empty()) { + QualType T = WorkList.pop_back_val(); + T = T.getCanonicalType().getUnqualifiedType(); + // only check aggregate types + if (const auto *AT = dyn_cast(T)) { + WorkList.push_back(AT->getElementType()); + continue; + } + if (const auto *RT = dyn_cast(T)) { + const RecordDecl *RD = RT->getDecl(); + if (RD->isUnion()) + continue; + + const CXXRecordDecl *CXXD = dyn_cast(RD); + + if (CXXD && CXXD->isStandardLayout()) + RD = CXXD->getStandardLayoutBaseWithFields(); + + for (const auto *FD : RD->fields()) { + if (FD->isBitField()) + return true; + WorkList.push_back(FD->getType()); + } + continue; + } + } + return false; +} + +// Can we perform an HLSL Elementwise cast? +// TODO: update this code when matrices are added; see issue #88060 +bool SemaHLSL::CanPerformElementwiseCast(Expr *Src, QualType DestTy) { + + // Don't handle casts where LHS and RHS are any combination of scalar/vector + // There must be an aggregate somewhere + QualType SrcTy = Src->getType(); + if (SrcTy->isScalarType()) // always a splat and this cast doesn't handle that + return false; + + if (SrcTy->isVectorType() && + (DestTy->isScalarType() || DestTy->isVectorType())) + return false; + + if (ContainsBitField(DestTy) || ContainsBitField(SrcTy)) + return false; + + llvm::SmallVector DestTypes; + BuildFlattenedTypeList(DestTy, DestTypes); + llvm::SmallVector SrcTypes; + BuildFlattenedTypeList(SrcTy, SrcTypes); + + // Usually the size of SrcTypes must be greater than or equal to the size of + // DestTypes. + if (SrcTypes.size() < DestTypes.size()) + return false; + + unsigned SrcSize = SrcTypes.size(); + unsigned DstSize = DestTypes.size(); + unsigned I; + for (I = 0; I < DstSize && I < SrcSize; I++) { + if (SrcTypes[I]->isUnionType() || DestTypes[I]->isUnionType()) + return false; + if (!CanPerformScalarCast(SrcTypes[I], DestTypes[I])) { + return false; + } + } + + // check the rest of the source type for unions. + for (; I < SrcSize; I++) { + if (SrcTypes[I]->isUnionType()) + return false; + } + return true; +} + ExprResult SemaHLSL::ActOnOutParamExpr(ParmVarDecl *Param, Expr *Arg) { assert(Param->hasAttr() && "We should not get here without a parameter modifier expression"); @@ -2779,7 +2986,7 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { // find all resources on decl if (VD->getType()->isHLSLIntangibleType()) - collectResourcesOnVarDecl(VD); + collectResourceBindingsOnVarDecl(VD); // process explicit bindings processExplicitBindingsOnDecl(VD); @@ -2788,7 +2995,7 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) { // Walks though the global variable declaration, collects all resource binding // requirements and adds them to Bindings -void SemaHLSL::collectResourcesOnVarDecl(VarDecl *VD) { +void SemaHLSL::collectResourceBindingsOnVarDecl(VarDecl *VD) { assert(VD->hasGlobalStorage() && VD->getType()->isHLSLIntangibleType() && "expected global variable that contains HLSL resource"); @@ -2817,7 +3024,7 @@ void SemaHLSL::collectResourcesOnVarDecl(VarDecl *VD) { // User defined record type if (const RecordType *RT = dyn_cast(Ty)) - collectResourcesOnUserRecordDecl(VD, RT); + collectResourceBindingsOnUserRecordDecl(VD, RT); } // Walks though the explicit resource binding attributes on the declaration, diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index b95cbbf422205..18090eb1c9e9a 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4573,8 +4573,12 @@ static void TryConstructorInitialization(Sema &S, CXXConstructorDecl *CtorDecl = cast(Best->Function); if (Result != OR_Deleted) { - if (!IsListInit && Kind.getKind() == InitializationKind::IK_Default && - DestRecordDecl != nullptr && DestRecordDecl->isAggregate() && + if (!IsListInit && + (Kind.getKind() == InitializationKind::IK_Default || + Kind.getKind() == InitializationKind::IK_Direct) && + DestRecordDecl != nullptr && + !(CtorDecl->isCopyOrMoveConstructor() && CtorDecl->isImplicit()) && + DestRecordDecl->isAggregate() && DestRecordDecl->hasUninitializedExplicitInitFields()) { S.Diag(Kind.getLocation(), diag::warn_field_requires_explicit_init) << /* Var-in-Record */ 1 << DestRecordDecl; @@ -4860,9 +4864,13 @@ static void TryListInitialization(Sema &S, assert( S.Context.hasSameUnqualifiedType(SubInit[0]->getType(), DestType) && "Deduced to other type?"); + assert(Kind.getKind() == clang::InitializationKind::IK_DirectList && + "List-initialize structured bindings but not " + "direct-list-initialization?"); TryArrayCopy(S, - InitializationKind::CreateCopy(Kind.getLocation(), - InitList->getLBraceLoc()), + InitializationKind::CreateDirect(Kind.getLocation(), + InitList->getLBraceLoc(), + InitList->getRBraceLoc()), Entity, SubInit[0], DestType, Sequence, TreatUnavailableAsInvalid); if (Sequence) @@ -9146,6 +9154,17 @@ bool InitializationSequence::Diagnose(Sema &S, << (Msg ? Msg->getString() : StringRef()) << ArgsRange; } + // If it's a default constructed member, but it's not in the + // constructor's initializer list, explicitly note where the member is + // declared so the user can see which member is erroneously initialized + // with a deleted default constructor. + if (Kind.getKind() == InitializationKind::IK_Default && + (Entity.getKind() == InitializedEntity::EK_Member || + Entity.getKind() == InitializedEntity::EK_ParenAggInitMember)) { + S.Diag(Entity.getDecl()->getLocation(), + diag::note_default_constructed_field) + << Entity.getDecl(); + } S.NoteDeletedFunction(Best->Function); break; } diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 87b3ca53cefaf..ceb32ee15dfa3 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -2239,18 +2239,18 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, Cleanup.mergeFrom(LambdaCleanup); - LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, - CaptureDefault, CaptureDefaultLoc, - ExplicitParams, ExplicitResultType, - CaptureInits, EndLoc, - ContainsUnexpandedParameterPack); + LambdaExpr *Lambda = + LambdaExpr::Create(Context, Class, IntroducerRange, CaptureDefault, + CaptureDefaultLoc, ExplicitParams, ExplicitResultType, + CaptureInits, EndLoc, ContainsUnexpandedParameterPack); + // If the lambda expression's call operator is not explicitly marked constexpr - // and we are not in a dependent context, analyze the call operator to infer + // and is not dependent, analyze the call operator to infer // its constexpr-ness, suppressing diagnostics while doing so. if (getLangOpts().CPlusPlus17 && !CallOperator->isInvalidDecl() && !CallOperator->isConstexpr() && !isa(CallOperator->getBody()) && - !Class->getDeclContext()->isDependentContext()) { + !Class->isDependentContext()) { CallOperator->setConstexprKind( CheckConstexprFunctionDefinition(CallOperator, CheckConstexprKind::CheckValid) diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 5f8ffa71607bb..0f5b7426e743e 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3721,13 +3721,11 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, // is a well-formed template argument for the template parameter. if (StringLit) { SFINAETrap Trap(*this); - SmallVector SugaredChecked, CanonicalChecked; + CheckTemplateArgumentInfo CTAI; TemplateArgumentLoc Arg(TemplateArgument(StringLit), StringLit); if (CheckTemplateArgument( Params->getParam(0), Arg, FD, R.getNameLoc(), R.getNameLoc(), - 0, SugaredChecked, CanonicalChecked, CTAK_Specified, - /*PartialOrdering=*/false, - /*MatchedPackOnParmToNonPackOnArg=*/nullptr) || + /*ArgumentPackIndex=*/0, CTAI, CTAK_Specified) || Trap.hasErrorOccurred()) IsTemplate = false; } diff --git a/clang/lib/Sema/SemaMIPS.cpp b/clang/lib/Sema/SemaMIPS.cpp index 50d210e5b3814..ce6ad6d9cc3f3 100644 --- a/clang/lib/Sema/SemaMIPS.cpp +++ b/clang/lib/Sema/SemaMIPS.cpp @@ -271,14 +271,14 @@ void SemaMIPS::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { } if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { - Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) - << /*MIPS*/ 0 << 0; + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*MIPS*/ 0 << /*interrupt*/ 0 << 0; return; } if (!getFunctionOrMethodResultType(D)->isVoidType()) { - Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) - << /*MIPS*/ 0 << 1; + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*MIPS*/ 0 << /*interrupt*/ 0 << 1; return; } diff --git a/clang/lib/Sema/SemaMSP430.cpp b/clang/lib/Sema/SemaMSP430.cpp index 4038a1ff61d63..5bf931e388f03 100644 --- a/clang/lib/Sema/SemaMSP430.cpp +++ b/clang/lib/Sema/SemaMSP430.cpp @@ -32,14 +32,14 @@ void SemaMSP430::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { } if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { - Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) - << /*MSP430*/ 1 << 0; + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*MSP430*/ 1 << /*interrupt*/ 0 << 0; return; } if (!getFunctionOrMethodResultType(D)->isVoidType()) { - Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) - << /*MSP430*/ 1 << 1; + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*MSP430*/ 1 << /*interrupt*/ 0 << 1; return; } diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index f5edc0ed36a9a..2d2f8ddf4652b 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -30,18 +30,23 @@ bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K, // Nothing to do here, both invalid and unimplemented don't really need to // do anything. break; - case OpenACCDirectiveKind::ParallelLoop: - case OpenACCDirectiveKind::SerialLoop: - case OpenACCDirectiveKind::KernelsLoop: case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::ParallelLoop: case OpenACCDirectiveKind::Serial: + case OpenACCDirectiveKind::SerialLoop: case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::KernelsLoop: case OpenACCDirectiveKind::Loop: case OpenACCDirectiveKind::Data: case OpenACCDirectiveKind::EnterData: case OpenACCDirectiveKind::ExitData: case OpenACCDirectiveKind::HostData: case OpenACCDirectiveKind::Wait: + case OpenACCDirectiveKind::Update: + case OpenACCDirectiveKind::Init: + case OpenACCDirectiveKind::Shutdown: + case OpenACCDirectiveKind::Cache: + case OpenACCDirectiveKind::Atomic: if (!IsStmt) return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K; break; @@ -73,6 +78,7 @@ bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) { return false; case OpenACCDirectiveKind::Data: case OpenACCDirectiveKind::HostData: + case OpenACCDirectiveKind::Atomic: return true; case OpenACCDirectiveKind::EnterData: case OpenACCDirectiveKind::ExitData: @@ -327,6 +333,7 @@ void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K, case OpenACCDirectiveKind::Shutdown: case OpenACCDirectiveKind::Set: case OpenACCDirectiveKind::Update: + case OpenACCDirectiveKind::Atomic: // Nothing to do here, there is no real legalization that needs to happen // here as these constructs do not take any arguments. break; @@ -1518,8 +1525,9 @@ bool SemaOpenACC::ActOnStartStmtDirective( StmtResult SemaOpenACC::ActOnEndStmtDirective( OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef Exprs, - SourceLocation RParenLoc, SourceLocation EndLoc, - ArrayRef Clauses, StmtResult AssocStmt) { + OpenACCAtomicKind AtomicKind, SourceLocation RParenLoc, + SourceLocation EndLoc, ArrayRef Clauses, + StmtResult AssocStmt) { switch (K) { default: return StmtEmpty(); @@ -1583,13 +1591,20 @@ StmtResult SemaOpenACC::ActOnEndStmtDirective( return OpenACCUpdateConstruct::Create(getASTContext(), StartLoc, DirLoc, EndLoc, Clauses); } + case OpenACCDirectiveKind::Atomic: { + assert(Clauses.empty() && "Atomic doesn't allow clauses"); + return OpenACCAtomicConstruct::Create( + getASTContext(), StartLoc, DirLoc, AtomicKind, EndLoc, + AssocStmt.isUsable() ? AssocStmt.get() : nullptr); + } } llvm_unreachable("Unhandled case in directive handling?"); } StmtResult SemaOpenACC::ActOnAssociatedStmt( SourceLocation DirectiveLoc, OpenACCDirectiveKind K, - ArrayRef Clauses, StmtResult AssocStmt) { + OpenACCAtomicKind AtKind, ArrayRef Clauses, + StmtResult AssocStmt) { switch (K) { default: llvm_unreachable("Unimplemented associated statement application"); @@ -1601,6 +1616,8 @@ StmtResult SemaOpenACC::ActOnAssociatedStmt( case OpenACCDirectiveKind::Set: llvm_unreachable( "these don't have associated statements, so shouldn't get here"); + case OpenACCDirectiveKind::Atomic: + return CheckAtomicAssociatedStmt(DirectiveLoc, AtKind, AssocStmt); case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: case OpenACCDirectiveKind::Kernels: diff --git a/clang/lib/Sema/SemaOpenACCAtomic.cpp b/clang/lib/Sema/SemaOpenACCAtomic.cpp new file mode 100644 index 0000000000000..68cf338c07115 --- /dev/null +++ b/clang/lib/Sema/SemaOpenACCAtomic.cpp @@ -0,0 +1,736 @@ +//== SemaOpenACCAtomic.cpp - Semantic Analysis for OpenACC Atomic Construct===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// This file implements semantic analysis for the OpenACC atomic construct. +/// +//===----------------------------------------------------------------------===// + +#include "clang/AST/ExprCXX.h" +#include "clang/Basic/DiagnosticSema.h" +#include "clang/Sema/SemaOpenACC.h" + +#include +#include + +using namespace clang; + +namespace { + +class AtomicOperandChecker { + SemaOpenACC &SemaRef; + OpenACCAtomicKind AtKind; + SourceLocation AtomicDirLoc; + StmtResult AssocStmt; + + // Do a diagnostic, which sets the correct error, then displays passed note. + bool DiagnoseInvalidAtomic(SourceLocation Loc, PartialDiagnostic NoteDiag) { + SemaRef.Diag(AtomicDirLoc, diag::err_acc_invalid_atomic) + << (AtKind != OpenACCAtomicKind::None) << AtKind; + SemaRef.Diag(Loc, NoteDiag); + return true; + } + + // Create a replacement recovery expr in case we find an error here. This + // allows us to ignore this during template instantiation so we only get a + // single error. + StmtResult getRecoveryExpr() { + if (!AssocStmt.isUsable()) + return AssocStmt; + + if (!SemaRef.getASTContext().getLangOpts().RecoveryAST) + return StmtError(); + + Expr *E = dyn_cast(AssocStmt.get()); + QualType T = E ? E->getType() : SemaRef.getASTContext().DependentTy; + + return RecoveryExpr::Create(SemaRef.getASTContext(), T, + AssocStmt.get()->getBeginLoc(), + AssocStmt.get()->getEndLoc(), + E ? ArrayRef{E} : ArrayRef{}); + } + + // OpenACC 3.3 2.12: 'expr' is an expression with scalar type. + bool CheckOperandExpr(const Expr *E, PartialDiagnostic PD) { + QualType ExprTy = E->getType(); + + // Scalar allowed, plus we allow instantiation dependent to support + // templates. + if (ExprTy->isInstantiationDependentType() || ExprTy->isScalarType()) + return false; + + return DiagnoseInvalidAtomic(E->getExprLoc(), + PD << diag::OACCLValScalar::Scalar << ExprTy); + } + + // OpenACC 3.3 2.12: 'x' and 'v' (as applicable) are boht l-value expressoins + // with scalar type. + bool CheckOperandVariable(const Expr *E, PartialDiagnostic PD) { + if (CheckOperandExpr(E, PD)) + return true; + + if (E->isLValue()) + return false; + + return DiagnoseInvalidAtomic(E->getExprLoc(), + PD << diag::OACCLValScalar::LVal); + } + + Expr *RequireExpr(Stmt *Stmt, PartialDiagnostic ExpectedNote) { + if (Expr *E = dyn_cast(Stmt)) + return E->IgnoreImpCasts(); + + DiagnoseInvalidAtomic(Stmt->getBeginLoc(), ExpectedNote); + return nullptr; + } + + // A struct to hold the return the inner components of any operands, which + // allows for compound checking. + struct BinaryOpInfo { + const Expr *FoundExpr = nullptr; + const Expr *LHS = nullptr; + const Expr *RHS = nullptr; + BinaryOperatorKind Operator; + }; + + struct UnaryOpInfo { + const Expr *FoundExpr = nullptr; + const Expr *SubExpr = nullptr; + UnaryOperatorKind Operator; + + bool IsIncrementOp() { + return Operator == UO_PostInc || Operator == UO_PreInc; + } + }; + + std::optional GetUnaryOperatorInfo(const Expr *E) { + // If this is a simple unary operator, just return its details. + if (const auto *UO = dyn_cast(E)) + return UnaryOpInfo{UO, UO->getSubExpr()->IgnoreImpCasts(), + UO->getOpcode()}; + + // This might be an overloaded operator or a dependent context, so make sure + // we can get as many details out of this as we can. + if (const auto *OpCall = dyn_cast(E)) { + UnaryOpInfo Inf; + Inf.FoundExpr = OpCall; + + switch (OpCall->getOperator()) { + default: + return std::nullopt; + case OO_PlusPlus: + Inf.Operator = OpCall->getNumArgs() == 1 ? UO_PreInc : UO_PostInc; + break; + case OO_MinusMinus: + Inf.Operator = OpCall->getNumArgs() == 1 ? UO_PreDec : UO_PostDec; + break; + case OO_Amp: + Inf.Operator = UO_AddrOf; + break; + case OO_Star: + Inf.Operator = UO_Deref; + break; + case OO_Plus: + Inf.Operator = UO_Plus; + break; + case OO_Minus: + Inf.Operator = UO_Minus; + break; + case OO_Tilde: + Inf.Operator = UO_Not; + break; + case OO_Exclaim: + Inf.Operator = UO_LNot; + break; + case OO_Coawait: + Inf.Operator = UO_Coawait; + break; + } + + // Some of the above can be both binary and unary operations, so make sure + // we get the right one. + if (Inf.Operator != UO_PostInc && Inf.Operator != UO_PostDec && + OpCall->getNumArgs() != 1) + return std::nullopt; + + Inf.SubExpr = OpCall->getArg(0); + return Inf; + } + return std::nullopt; + } + + // Get a normalized version of a binary operator. + std::optional GetBinaryOperatorInfo(const Expr *E) { + if (const auto *BO = dyn_cast(E)) + return BinaryOpInfo{BO, BO->getLHS()->IgnoreImpCasts(), + BO->getRHS()->IgnoreImpCasts(), BO->getOpcode()}; + + // In case this is an operator-call, which allows us to support overloaded + // operators and dependent expression. + if (const auto *OpCall = dyn_cast(E)) { + BinaryOpInfo Inf; + Inf.FoundExpr = OpCall; + + switch (OpCall->getOperator()) { + default: + return std::nullopt; + case OO_Plus: + Inf.Operator = BO_Add; + break; + case OO_Minus: + Inf.Operator = BO_Sub; + break; + case OO_Star: + Inf.Operator = BO_Mul; + break; + case OO_Slash: + Inf.Operator = BO_Div; + break; + case OO_Percent: + Inf.Operator = BO_Rem; + break; + case OO_Caret: + Inf.Operator = BO_Xor; + break; + case OO_Amp: + Inf.Operator = BO_And; + break; + case OO_Pipe: + Inf.Operator = BO_Or; + break; + case OO_Equal: + Inf.Operator = BO_Assign; + break; + case OO_Spaceship: + Inf.Operator = BO_Cmp; + break; + case OO_Less: + Inf.Operator = BO_LT; + break; + case OO_Greater: + Inf.Operator = BO_GT; + break; + case OO_PlusEqual: + Inf.Operator = BO_AddAssign; + break; + case OO_MinusEqual: + Inf.Operator = BO_SubAssign; + break; + case OO_StarEqual: + Inf.Operator = BO_MulAssign; + break; + case OO_SlashEqual: + Inf.Operator = BO_DivAssign; + break; + case OO_PercentEqual: + Inf.Operator = BO_RemAssign; + break; + case OO_CaretEqual: + Inf.Operator = BO_XorAssign; + break; + case OO_AmpEqual: + Inf.Operator = BO_AndAssign; + break; + case OO_PipeEqual: + Inf.Operator = BO_OrAssign; + break; + case OO_LessLess: + Inf.Operator = BO_Shl; + break; + case OO_GreaterGreater: + Inf.Operator = BO_Shr; + break; + case OO_LessLessEqual: + Inf.Operator = BO_ShlAssign; + break; + case OO_GreaterGreaterEqual: + Inf.Operator = BO_ShrAssign; + break; + case OO_EqualEqual: + Inf.Operator = BO_EQ; + break; + case OO_ExclaimEqual: + Inf.Operator = BO_NE; + break; + case OO_LessEqual: + Inf.Operator = BO_LE; + break; + case OO_GreaterEqual: + Inf.Operator = BO_GE; + break; + case OO_AmpAmp: + Inf.Operator = BO_LAnd; + break; + case OO_PipePipe: + Inf.Operator = BO_LOr; + break; + case OO_Comma: + Inf.Operator = BO_Comma; + break; + case OO_ArrowStar: + Inf.Operator = BO_PtrMemI; + break; + } + + // This isn't a binary operator unless there are two arguments. + if (OpCall->getNumArgs() != 2) + return std::nullopt; + + // Callee is the call-operator, so we only need to extract the two + // arguments here. + Inf.LHS = OpCall->getArg(0)->IgnoreImpCasts(); + Inf.RHS = OpCall->getArg(1)->IgnoreImpCasts(); + return Inf; + } + + return std::nullopt; + } + + // Checks a required assignment operation, but don't check the LHS or RHS, + // callers have to do that here. + std::optional CheckAssignment(const Expr *E) { + std::optional Inf = GetBinaryOperatorInfo(E); + + if (!Inf) { + DiagnoseInvalidAtomic(E->getExprLoc(), + SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::Assign); + return std::nullopt; + } + + if (Inf->Operator != BO_Assign) { + DiagnoseInvalidAtomic(Inf->FoundExpr->getExprLoc(), + SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::Assign); + return std::nullopt; + } + + // Assignment always requires an lvalue/scalar on the LHS. + if (CheckOperandVariable( + Inf->LHS, SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*left=*/0 << diag::OACCAtomicOpKind::Assign)) + return std::nullopt; + + return Inf; + } + + struct IDACInfo { + bool Failed = false; + enum ExprKindTy { + Invalid, + // increment/decrement ops. + Unary, + // v = x + SimpleAssign, + // x = expr + ExprAssign, + // x binop= expr + CompoundAssign, + // x = x binop expr + // x = expr binop x + AssignBinOp + } ExprKind; + + // The variable referred to as 'x' in all of the grammar, such that it is + // needed in compound statement checking of capture to check between the two + // expressions. + const Expr *X_Var = nullptr; + + static IDACInfo Fail() { return IDACInfo{true, Invalid, nullptr}; }; + }; + + // Helper for CheckIncDecAssignCompoundAssign, does checks for inc/dec. + IDACInfo CheckIncDec(UnaryOpInfo Inf) { + + if (!UnaryOperator::isIncrementDecrementOp(Inf.Operator)) { + DiagnoseInvalidAtomic( + Inf.FoundExpr->getExprLoc(), + SemaRef.PDiag(diag::note_acc_atomic_unsupported_unary_operator)); + return IDACInfo::Fail(); + } + bool Failed = CheckOperandVariable( + Inf.SubExpr, + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*none=*/2 + << (Inf.IsIncrementOp() ? diag::OACCAtomicOpKind::Inc + : diag::OACCAtomicOpKind::Dec)); + // For increment/decrements, the subexpr is the 'x' (x++, ++x, etc). + return IDACInfo{Failed, IDACInfo::Unary, Inf.SubExpr}; + } + + enum class SimpleAssignKind { None, Var, Expr }; + + // Check an assignment, and ensure the RHS is either x binop expr or expr + // binop x. + // If AllowSimpleAssign, also allows v = x; + IDACInfo CheckAssignmentWithBinOpOnRHS(BinaryOpInfo AssignInf, + SimpleAssignKind SAK) { + PartialDiagnostic PD = + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*left=*/0 << diag::OACCAtomicOpKind::Assign; + if (CheckOperandVariable(AssignInf.LHS, PD)) + return IDACInfo::Fail(); + + std::optional BinInf = GetBinaryOperatorInfo(AssignInf.RHS); + + if (!BinInf) { + + // Capture in a compound statement allows v = x assignment. So make sure + // we permit that here. + if (SAK != SimpleAssignKind::None) { + PartialDiagnostic PD = + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*right=*/1 << diag::OACCAtomicOpKind::Assign; + if (SAK == SimpleAssignKind::Var) { + // In the var version, everywhere we allow v = x;, X is the RHS. + return IDACInfo{CheckOperandVariable(AssignInf.RHS, PD), + IDACInfo::SimpleAssign, AssignInf.RHS}; + } + assert(SAK == SimpleAssignKind::Expr); + // In the expression version, supported by v=x; x = expr;, we need to + // set to the LHS here. + return IDACInfo{CheckOperandExpr(AssignInf.RHS, PD), + IDACInfo::ExprAssign, AssignInf.LHS}; + } + + DiagnoseInvalidAtomic( + AssignInf.RHS->getExprLoc(), + SemaRef.PDiag(diag::note_acc_atomic_expected_binop)); + + return IDACInfo::Fail(); + } + switch (BinInf->Operator) { + default: + DiagnoseInvalidAtomic( + BinInf->FoundExpr->getExprLoc(), + SemaRef.PDiag(diag::note_acc_atomic_unsupported_binary_operator)); + return IDACInfo::Fail(); + // binop is one of +, *, -, /, &, ^, |, <<, or >> + case BO_Add: + case BO_Mul: + case BO_Sub: + case BO_Div: + case BO_And: + case BO_Xor: + case BO_Or: + case BO_Shl: + case BO_Shr: + // Handle these outside of the switch. + break; + } + + llvm::FoldingSetNodeID LHS_ID, InnerLHS_ID, InnerRHS_ID; + AssignInf.LHS->Profile(LHS_ID, SemaRef.getASTContext(), + /*Canonical=*/true); + BinInf->LHS->Profile(InnerLHS_ID, SemaRef.getASTContext(), + /*Canonical=*/true); + + // This is X = X binop expr; + // Check the RHS is an expression. + if (LHS_ID == InnerLHS_ID) + return IDACInfo{ + CheckOperandExpr( + BinInf->RHS, + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar + << /*right=*/1 + << diag::OACCAtomicOpKind::CompoundAssign)), + IDACInfo::AssignBinOp, AssignInf.LHS}; + + BinInf->RHS->Profile(InnerRHS_ID, SemaRef.getASTContext(), + /*Canonical=*/true); + // This is X = expr binop X; + // Check the LHS is an expression + if (LHS_ID == InnerRHS_ID) + return IDACInfo{ + CheckOperandExpr( + BinInf->LHS, + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*left=*/0 << diag::OACCAtomicOpKind::CompoundAssign), + IDACInfo::AssignBinOp, AssignInf.LHS}; + + // If nothing matches, error out. + DiagnoseInvalidAtomic(BinInf->FoundExpr->getExprLoc(), + SemaRef.PDiag(diag::note_acc_atomic_mismatch_operand) + << const_cast(AssignInf.LHS) + << const_cast(BinInf->LHS) + << const_cast(BinInf->RHS)); + return IDACInfo::Fail(); + } + + // Ensures that the expression is an increment/decrement, an assignment, or a + // compound assignment. If its an assignment, allows the x binop expr/x binop + // expr syntax. If it is a compound-assignment, allows any expr on the RHS. + IDACInfo CheckIncDecAssignCompoundAssign(const Expr *E, + SimpleAssignKind SAK) { + std::optional UInf = GetUnaryOperatorInfo(E); + + // If this is a unary operator, only increment/decrement are allowed, so get + // unary operator, then check everything we can. + if (UInf) + return CheckIncDec(*UInf); + + std::optional BinInf = GetBinaryOperatorInfo(E); + + // Unary or binary operator were the only choices, so error here. + if (!BinInf) { + DiagnoseInvalidAtomic(E->getExprLoc(), + SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::UnaryCompAssign); + return IDACInfo::Fail(); + } + + switch (BinInf->Operator) { + default: + DiagnoseInvalidAtomic( + BinInf->FoundExpr->getExprLoc(), + SemaRef.PDiag( + diag::note_acc_atomic_unsupported_compound_binary_operator)); + return IDACInfo::Fail(); + case BO_Assign: + return CheckAssignmentWithBinOpOnRHS(*BinInf, SAK); + case BO_AddAssign: + case BO_MulAssign: + case BO_SubAssign: + case BO_DivAssign: + case BO_AndAssign: + case BO_XorAssign: + case BO_OrAssign: + case BO_ShlAssign: + case BO_ShrAssign: { + PartialDiagnostic LPD = + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*left=*/0 << diag::OACCAtomicOpKind::CompoundAssign; + PartialDiagnostic RPD = + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*right=*/1 << diag::OACCAtomicOpKind::CompoundAssign; + // nothing to do other than check the variable expressions. + // success or failure + bool Failed = CheckOperandVariable(BinInf->LHS, LPD) || + CheckOperandExpr(BinInf->RHS, RPD); + + return IDACInfo{Failed, IDACInfo::CompoundAssign, BinInf->LHS}; + } + } + llvm_unreachable("all binary operator kinds should be checked above"); + } + + StmtResult CheckRead() { + Expr *AssocExpr = RequireExpr( + AssocStmt.get(), SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::Assign); + + if (!AssocExpr) + return getRecoveryExpr(); + + std::optional AssignRes = CheckAssignment(AssocExpr); + if (!AssignRes) + return getRecoveryExpr(); + + PartialDiagnostic PD = + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*right=*/1 << diag::OACCAtomicOpKind::Assign; + + // Finally, check the RHS. + if (CheckOperandVariable(AssignRes->RHS, PD)) + return getRecoveryExpr(); + + return AssocStmt; + } + + StmtResult CheckWrite() { + Expr *AssocExpr = RequireExpr( + AssocStmt.get(), SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::Assign); + + if (!AssocExpr) + return getRecoveryExpr(); + + std::optional AssignRes = CheckAssignment(AssocExpr); + if (!AssignRes) + return getRecoveryExpr(); + + PartialDiagnostic PD = + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*right=*/1 << diag::OACCAtomicOpKind::Assign; + + // Finally, check the RHS. + if (CheckOperandExpr(AssignRes->RHS, PD)) + return getRecoveryExpr(); + + return AssocStmt; + } + + StmtResult CheckUpdate() { + Expr *AssocExpr = RequireExpr( + AssocStmt.get(), SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::UnaryCompAssign); + + if (!AssocExpr || + CheckIncDecAssignCompoundAssign(AssocExpr, SimpleAssignKind::None) + .Failed) + return getRecoveryExpr(); + + return AssocStmt; + } + + bool CheckVarRefsSame(IDACInfo::ExprKindTy FirstKind, const Expr *FirstX, + IDACInfo::ExprKindTy SecondKind, const Expr *SecondX) { + llvm::FoldingSetNodeID First_ID, Second_ID; + FirstX->Profile(First_ID, SemaRef.getASTContext(), /*Canonical=*/true); + SecondX->Profile(Second_ID, SemaRef.getASTContext(), /*Canonical=*/true); + + if (First_ID == Second_ID) + return false; + + PartialDiagnostic PD = + SemaRef.PDiag(diag::note_acc_atomic_mismatch_compound_operand) + << FirstKind << const_cast(FirstX) << SecondKind + << const_cast(SecondX); + + return DiagnoseInvalidAtomic(SecondX->getExprLoc(), PD); + } + + StmtResult CheckCapture() { + if (const auto *CmpdStmt = dyn_cast(AssocStmt.get())) { + auto *const *BodyItr = CmpdStmt->body().begin(); + PartialDiagnostic PD = SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::UnaryCompAssign; + // If we don't have at least 1 statement, error. + if (BodyItr == CmpdStmt->body().end()) { + DiagnoseInvalidAtomic(CmpdStmt->getBeginLoc(), PD); + return getRecoveryExpr(); + } + + // First Expr can be inc/dec, assign, or compound assign. + Expr *FirstExpr = RequireExpr(*BodyItr, PD); + if (!FirstExpr) + return getRecoveryExpr(); + + IDACInfo FirstExprResults = + CheckIncDecAssignCompoundAssign(FirstExpr, SimpleAssignKind::Var); + if (FirstExprResults.Failed) + return getRecoveryExpr(); + + ++BodyItr; + + // If we don't have second statement, error. + if (BodyItr == CmpdStmt->body().end()) { + DiagnoseInvalidAtomic(CmpdStmt->getEndLoc(), PD); + return getRecoveryExpr(); + } + + Expr *SecondExpr = RequireExpr(*BodyItr, PD); + if (!SecondExpr) + return getRecoveryExpr(); + + assert(FirstExprResults.ExprKind != IDACInfo::Invalid); + + switch (FirstExprResults.ExprKind) { + case IDACInfo::Invalid: + case IDACInfo::ExprAssign: + llvm_unreachable("Should have error'ed out by now"); + case IDACInfo::Unary: + case IDACInfo::CompoundAssign: + case IDACInfo::AssignBinOp: { + // Everything but simple-assign can only be followed by a simple + // assignment. + std::optional AssignRes = CheckAssignment(SecondExpr); + if (!AssignRes) + return getRecoveryExpr(); + + PartialDiagnostic PD = + SemaRef.PDiag(diag::note_acc_atomic_operand_lvalue_scalar) + << /*right=*/1 << diag::OACCAtomicOpKind::Assign; + + if (CheckOperandVariable(AssignRes->RHS, PD)) + return getRecoveryExpr(); + + if (CheckVarRefsSame(FirstExprResults.ExprKind, FirstExprResults.X_Var, + IDACInfo::SimpleAssign, AssignRes->RHS)) + return getRecoveryExpr(); + break; + } + case IDACInfo::SimpleAssign: { + // If the first was v = x, anything but simple expression is allowed. + IDACInfo SecondExprResults = + CheckIncDecAssignCompoundAssign(SecondExpr, SimpleAssignKind::Expr); + if (SecondExprResults.Failed) + return getRecoveryExpr(); + + if (CheckVarRefsSame(FirstExprResults.ExprKind, FirstExprResults.X_Var, + SecondExprResults.ExprKind, + SecondExprResults.X_Var)) + return getRecoveryExpr(); + break; + } + } + ++BodyItr; + if (BodyItr != CmpdStmt->body().end()) { + DiagnoseInvalidAtomic( + (*BodyItr)->getBeginLoc(), + SemaRef.PDiag(diag::note_acc_atomic_too_many_stmts)); + return getRecoveryExpr(); + } + } else { + // This check doesn't need to happen if it is a compound stmt. + Expr *AssocExpr = RequireExpr( + AssocStmt.get(), SemaRef.PDiag(diag::note_acc_atomic_expr_must_be) + << diag::OACCAtomicExpr::Assign); + if (!AssocExpr) + return getRecoveryExpr(); + + // First, we require an assignment. + std::optional AssignRes = CheckAssignment(AssocExpr); + + if (!AssignRes) + return getRecoveryExpr(); + + if (CheckIncDecAssignCompoundAssign(AssignRes->RHS, + SimpleAssignKind::None) + .Failed) + return getRecoveryExpr(); + } + + return AssocStmt; + } + +public: + AtomicOperandChecker(SemaOpenACC &S, OpenACCAtomicKind AtKind, + SourceLocation DirLoc, StmtResult AssocStmt) + : SemaRef(S), AtKind(AtKind), AtomicDirLoc(DirLoc), AssocStmt(AssocStmt) { + } + + StmtResult Check() { + + switch (AtKind) { + case OpenACCAtomicKind::Read: + return CheckRead(); + case OpenACCAtomicKind::Write: + return CheckWrite(); + case OpenACCAtomicKind::None: + case OpenACCAtomicKind::Update: + return CheckUpdate(); + case OpenACCAtomicKind::Capture: + return CheckCapture(); + } + llvm_unreachable("Unhandled atomic kind?"); + } +}; +} // namespace + +StmtResult SemaOpenACC::CheckAtomicAssociatedStmt(SourceLocation AtomicDirLoc, + OpenACCAtomicKind AtKind, + StmtResult AssocStmt) { + if (!AssocStmt.isUsable()) + return AssocStmt; + + if (isa(AssocStmt.get())) + return AssocStmt; + + AtomicOperandChecker Checker{*this, AtKind, AtomicDirLoc, AssocStmt}; + return Checker.Check(); +} diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index 000934225402a..1e74f126c31ce 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -589,7 +589,6 @@ bool checkValidAfterDeviceType( // construct has been implemented. bool isDirectiveKindImplemented(OpenACCDirectiveKind DK) { return DK != OpenACCDirectiveKind::Declare && - DK != OpenACCDirectiveKind::Atomic && DK != OpenACCDirectiveKind::Routine; } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index b83b2b12f4a23..39ce65381a98c 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4788,13 +4788,26 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite); OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back(); - if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() && - CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop && - CurrentRegion != OMPD_parallel && - !isOpenMPCombinedParallelADirective(CurrentRegion)) { - SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order) - << getOpenMPDirectiveName(CurrentRegion); - return true; + if (Stack->isParentOrderConcurrent()) { + bool InvalidOrderNesting = false; + if ((SemaRef.LangOpts.OpenMP == 51 || SemaRef.LangOpts.OpenMP == 52) && + CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop && + CurrentRegion != OMPD_parallel && + !isOpenMPCombinedParallelADirective(CurrentRegion)) { + InvalidOrderNesting = true; + } else if (SemaRef.LangOpts.OpenMP >= 60 && + !isOpenMPOrderConcurrentNestableDirective(CurrentRegion)) { + // OpenMP 6.0 [12.3 order Clause, Restrictions] + // Only regions that correspond to order-concurrent-nestable constructs + // or order-concurrent-nestable routines may be strictly nested regions + // of regions that correspond to constructs on which the order clause is + // specified with concurrent as the ordering argument. + InvalidOrderNesting = true; + } + if (InvalidOrderNesting) { + SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order) + << getOpenMPDirectiveName(CurrentRegion); + } } if (isOpenMPSimdDirective(ParentRegion) && ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || @@ -5065,7 +5078,8 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, // At most one if clause without a directive-name-modifier can appear on // the directive. OpenMPDirectiveKind CurNM = IC->getNameModifier(); - if (FoundNameModifiers[CurNM]) { + auto &FNM = FoundNameModifiers[CurNM]; + if (FNM) { S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); @@ -5074,7 +5088,7 @@ static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, NameModifierLoc.push_back(IC->getNameModifierLoc()); ++NamedModifiersNumber; } - FoundNameModifiers[CurNM] = IC; + FNM = IC; if (CurNM == OMPD_unknown) continue; // Check if the specified name modifier is allowed for the current @@ -6746,16 +6760,15 @@ SemaOpenMP::DeclGroupPtrTy SemaOpenMP::ActOnOpenMPDeclareSimdDirective( ->getCanonicalDecl() == CanonPVD) { // OpenMP [2.8.1, simd construct, Restrictions] // A list-item cannot appear in more than one aligned clause. - if (AlignedArgs.count(CanonPVD) > 0) { + auto [It, Inserted] = AlignedArgs.try_emplace(CanonPVD, E); + if (!Inserted) { Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) << 1 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); - Diag(AlignedArgs[CanonPVD]->getExprLoc(), - diag::note_omp_explicit_dsa) + Diag(It->second->getExprLoc(), diag::note_omp_explicit_dsa) << getOpenMPClauseName(OMPC_aligned); continue; } - AlignedArgs[CanonPVD] = E; QualType QTy = PVD->getType() .getNonReferenceType() .getUnqualifiedType() @@ -7114,7 +7127,8 @@ ExprResult SemaOpenMP::ActOnOpenMPCall(ExprResult Call, Scope *Scope, if (!CalleeFnDecl) return Call; - if (getLangOpts().OpenMP >= 51 && CalleeFnDecl->getIdentifier() && + if (getLangOpts().OpenMP >= 51 && getLangOpts().OpenMP < 60 && + CalleeFnDecl->getIdentifier() && CalleeFnDecl->getName().starts_with_insensitive("omp_")) { // checking for any calls inside an Order region if (Scope && Scope->isOpenMPOrderClauseScope()) @@ -7134,7 +7148,7 @@ ExprResult SemaOpenMP::ActOnOpenMPCall(ExprResult Call, Scope *Scope, }; TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), SemaRef.getCurFunctionDecl(), - DSAStack->getConstructTraits()); + DSAStack->getConstructTraits(), getOpenMPDeviceNum()); QualType CalleeFnType = CalleeFnDecl->getType(); @@ -15631,6 +15645,38 @@ ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause( return ICE; } +void SemaOpenMP::setOpenMPDeviceNum(int Num) { DeviceNum = Num; } + +void SemaOpenMP::setOpenMPDeviceNumID(StringRef ID) { DeviceNumID = ID; } + +int SemaOpenMP::getOpenMPDeviceNum() const { return DeviceNum; } + +void SemaOpenMP::ActOnOpenMPDeviceNum(Expr *DeviceNumExpr) { + llvm::APSInt Result; + Expr::EvalResult EvalResult; + // Evaluate the expression to an integer value + if (!DeviceNumExpr->isValueDependent() && + DeviceNumExpr->EvaluateAsInt(EvalResult, SemaRef.Context)) { + // The device expression must evaluate to a non-negative integer value. + Result = EvalResult.Val.getInt(); + if (Result.isNonNegative()) { + setOpenMPDeviceNum(Result.getZExtValue()); + } else { + Diag(DeviceNumExpr->getExprLoc(), + diag::err_omp_negative_expression_in_clause) + << "device_num" << 0 << DeviceNumExpr->getSourceRange(); + } + } else if (auto *DeclRef = dyn_cast(DeviceNumExpr)) { + // Check if the expression is an identifier + IdentifierInfo *IdInfo = DeclRef->getDecl()->getIdentifier(); + if (IdInfo) { + setOpenMPDeviceNumID(IdInfo->getName()); + } + } else { + Diag(DeviceNumExpr->getExprLoc(), diag::err_expected_expression); + } +} + OMPClause *SemaOpenMP::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -22773,8 +22819,12 @@ class GlobalDeclRefChecker final : public StmtVisitor { void declareTargetInitializer(Decl *TD) { A = TD->getAttr(); DeclVector.push_back(cast(TD)); + llvm::SmallDenseSet Visited; while (!DeclVector.empty()) { VarDecl *TargetVarDecl = DeclVector.pop_back_val(); + if (!Visited.insert(TargetVarDecl).second) + continue; + if (TargetVarDecl->hasAttr() && TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) { if (Expr *Ex = TargetVarDecl->getInit()) @@ -23717,6 +23767,8 @@ OMPClause *SemaOpenMP::ActOnOpenMPNullaryAssumptionClause(OpenMPClauseKind CK, return new (getASTContext()) OMPNoOpenMPRoutinesClause(Loc, RLoc); case OMPC_no_parallelism: return new (getASTContext()) OMPNoParallelismClause(Loc, RLoc); + case OMPC_no_openmp_constructs: + return new (getASTContext()) OMPNoOpenMPConstructsClause(Loc, RLoc); default: llvm_unreachable("Unexpected OpenMP clause"); } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 6ae9c51c06b31..8d5b5ac190b5b 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -6151,8 +6151,8 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From, Sema::CCEKind CCE, NamedDecl *Dest, APValue &PreNarrowingValue) { - assert(S.getLangOpts().CPlusPlus11 && - "converted constant expression outside C++11"); + assert((S.getLangOpts().CPlusPlus11 || CCE == Sema::CCEK_InjectedTTP) && + "converted constant expression outside C++11 or TTP matching"); if (checkPlaceholderForOverload(S, From)) return ExprError(); @@ -6221,8 +6221,10 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From, // earlier, but that's not guaranteed to work when initializing an object of // class type. ExprResult Result; + bool IsTemplateArgument = + CCE == Sema::CCEK_TemplateArg || CCE == Sema::CCEK_InjectedTTP; if (T->isRecordType()) { - assert(CCE == Sema::CCEK_TemplateArg && + assert(IsTemplateArgument && "unexpected class type converted constant expr"); Result = S.PerformCopyInitialization( InitializedEntity::InitializeTemplateParameter( @@ -6239,7 +6241,7 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From, // A full-expression is [...] a constant-expression [...] Result = S.ActOnFinishFullExpr(Result.get(), From->getExprLoc(), /*DiscardedValue=*/false, /*IsConstexpr=*/true, - CCE == Sema::CCEKind::CCEK_TemplateArg); + IsTemplateArgument); if (Result.isInvalid()) return Result; @@ -6248,9 +6250,6 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From, QualType PreNarrowingType; switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue, PreNarrowingType)) { - case NK_Dependent_Narrowing: - // Implicit conversion to a narrower type, but the expression is - // value-dependent so we can't tell whether it's actually narrowing. case NK_Variable_Narrowing: // Implicit conversion to a narrower type, and the value is not a constant // expression. We'll diagnose this in a moment. @@ -6271,6 +6270,14 @@ static ExprResult BuildConvertedConstantExpression(Sema &S, Expr *From, << PreNarrowingValue.getAsString(S.Context, PreNarrowingType) << T; break; + case NK_Dependent_Narrowing: + // Implicit conversion to a narrower type, but the expression is + // value-dependent so we can't tell whether it's actually narrowing. + // For matching the parameters of a TTP, the conversion is ill-formed + // if it may narrow. + if (CCE != Sema::CCEK_InjectedTTP) + break; + [[fallthrough]]; case NK_Type_Narrowing: // FIXME: It would be better to diagnose that the expression is not a // constant expression. @@ -6343,6 +6350,8 @@ Sema::EvaluateConvertedConstantExpression(Expr *E, QualType T, APValue &Value, Expr::EvalResult Eval; Eval.Diag = &Notes; + assert(CCE != Sema::CCEK_InjectedTTP && "unnexpected CCE Kind"); + ConstantExprKind Kind; if (CCE == Sema::CCEK_TemplateArg && T->isRecordType()) Kind = ConstantExprKind::ClassTemplateArgument; @@ -6918,7 +6927,7 @@ void Sema::AddOverloadCandidate( bool PartialOverloading, bool AllowExplicit, bool AllowExplicitConversions, ADLCallKind IsADLCandidate, ConversionSequenceList EarlyConversions, OverloadCandidateParamOrder PO, bool AggregateCandidateDeduction, - bool HasMatchedPackOnParmToNonPackOnArg) { + bool StrictPackMatch) { const FunctionProtoType *Proto = dyn_cast(Function->getType()->getAs()); assert(Proto && "Functions without a prototype cannot be overloaded"); @@ -6938,7 +6947,7 @@ void Sema::AddOverloadCandidate( Expr::Classification::makeSimpleLValue(), Args, CandidateSet, SuppressUserConversions, PartialOverloading, EarlyConversions, PO, - HasMatchedPackOnParmToNonPackOnArg); + StrictPackMatch); return; } // We treat a constructor like a non-member function, since its object @@ -6981,8 +6990,7 @@ void Sema::AddOverloadCandidate( CandidateSet.getRewriteInfo().getRewriteKind(Function, PO); Candidate.IsADLCandidate = llvm::to_underlying(IsADLCandidate); Candidate.ExplicitCallArguments = Args.size(); - Candidate.HasMatchedPackOnParmToNonPackOnArg = - HasMatchedPackOnParmToNonPackOnArg; + Candidate.StrictPackMatch = StrictPackMatch; // Explicit functions are not actually candidates at all if we're not // allowing them in this context, but keep them around so we can point @@ -7377,8 +7385,10 @@ static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND, return false; auto WarningBegin = std::stable_partition( - Attrs.begin(), Attrs.end(), - [](const DiagnoseIfAttr *DIA) { return DIA->isError(); }); + Attrs.begin(), Attrs.end(), [](const DiagnoseIfAttr *DIA) { + return DIA->getDefaultSeverity() == DiagnoseIfAttr::DS_error && + DIA->getWarningGroup().empty(); + }); // Note that diagnose_if attributes are late-parsed, so they appear in the // correct order (unlike enable_if attributes). @@ -7392,11 +7402,32 @@ static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND, return true; } + auto ToSeverity = [](DiagnoseIfAttr::DefaultSeverity Sev) { + switch (Sev) { + case DiagnoseIfAttr::DS_warning: + return diag::Severity::Warning; + case DiagnoseIfAttr::DS_error: + return diag::Severity::Error; + } + llvm_unreachable("Fully covered switch above!"); + }; + for (const auto *DIA : llvm::make_range(WarningBegin, Attrs.end())) if (IsSuccessful(DIA)) { - S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage(); - S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) - << DIA->getParent() << DIA->getCond()->getSourceRange(); + if (DIA->getWarningGroup().empty() && + DIA->getDefaultSeverity() == DiagnoseIfAttr::DS_warning) { + S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage(); + S.Diag(DIA->getLocation(), diag::note_from_diagnose_if) + << DIA->getParent() << DIA->getCond()->getSourceRange(); + } else { + auto DiagGroup = S.Diags.getDiagnosticIDs()->getGroupForWarningOption( + DIA->getWarningGroup()); + assert(DiagGroup); + auto DiagID = S.Diags.getDiagnosticIDs()->getCustomDiagID( + {ToSeverity(DIA->getDefaultSeverity()), "%0", + DiagnosticIDs::CLASS_WARNING, false, false, *DiagGroup}); + S.Diag(Loc, DiagID) << DIA->getMessage(); + } } return false; @@ -7531,7 +7562,7 @@ void Sema::AddMethodCandidate( Expr::Classification ObjectClassification, ArrayRef Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, ConversionSequenceList EarlyConversions, - OverloadCandidateParamOrder PO, bool HasMatchedPackOnParmToNonPackOnArg) { + OverloadCandidateParamOrder PO, bool StrictPackMatch) { const FunctionProtoType *Proto = dyn_cast(Method->getType()->getAs()); assert(Proto && "Methods without a prototype cannot be overloaded"); @@ -7562,8 +7593,7 @@ void Sema::AddMethodCandidate( Candidate.TookAddressOfOverload = CandidateSet.getKind() == OverloadCandidateSet::CSK_AddressOfOverloadSet; Candidate.ExplicitCallArguments = Args.size(); - Candidate.HasMatchedPackOnParmToNonPackOnArg = - HasMatchedPackOnParmToNonPackOnArg; + Candidate.StrictPackMatch = StrictPackMatch; bool IgnoreExplicitObject = (Method->isExplicitObjectMemberFunction() && @@ -7773,8 +7803,7 @@ void Sema::AddMethodTemplateCandidate( AddMethodCandidate(cast(Specialization), FoundDecl, ActingContext, ObjectType, ObjectClassification, Args, CandidateSet, SuppressUserConversions, PartialOverloading, - Conversions, PO, - Info.hasMatchedPackOnParmToNonPackOnArg()); + Conversions, PO, Info.hasStrictPackMatch()); } /// Determine whether a given function template has a simple explicit specifier @@ -7862,7 +7891,7 @@ void Sema::AddTemplateOverloadCandidate( PartialOverloading, AllowExplicit, /*AllowExplicitConversions=*/false, IsADLCandidate, Conversions, PO, Info.AggregateDeductionCandidateHasMismatchedArity, - Info.hasMatchedPackOnParmToNonPackOnArg()); + Info.hasStrictPackMatch()); } bool Sema::CheckNonDependentConversions( @@ -7984,8 +8013,7 @@ void Sema::AddConversionCandidate( CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit, - bool AllowExplicit, bool AllowResultConversion, - bool HasMatchedPackOnParmToNonPackOnArg) { + bool AllowExplicit, bool AllowResultConversion, bool StrictPackMatch) { assert(!Conversion->getDescribedFunctionTemplate() && "Conversion function templates use AddTemplateConversionCandidate"); QualType ConvType = Conversion->getConversionType().getNonReferenceType(); @@ -8030,8 +8058,7 @@ void Sema::AddConversionCandidate( Candidate.FinalConversion.setAllToTypes(ToType); Candidate.Viable = true; Candidate.ExplicitCallArguments = 1; - Candidate.HasMatchedPackOnParmToNonPackOnArg = - HasMatchedPackOnParmToNonPackOnArg; + Candidate.StrictPackMatch = StrictPackMatch; // Explicit functions are not actually candidates at all if we're not // allowing them in this context, but keep them around so we can point @@ -8234,7 +8261,7 @@ void Sema::AddTemplateConversionCandidate( AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType, CandidateSet, AllowObjCConversionOnExplicit, AllowExplicit, AllowResultConversion, - Info.hasMatchedPackOnParmToNonPackOnArg()); + Info.hasStrictPackMatch()); } void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, @@ -10586,9 +10613,8 @@ bool clang::isBetterOverloadCandidate( isa(Cand2.Function)) return isa(Cand1.Function); - if (Cand1.HasMatchedPackOnParmToNonPackOnArg != - Cand2.HasMatchedPackOnParmToNonPackOnArg) - return Cand2.HasMatchedPackOnParmToNonPackOnArg; + if (Cand1.StrictPackMatch != Cand2.StrictPackMatch) + return Cand2.StrictPackMatch; // -- F1 is a non-template function and F2 is a function template // specialization, or, if not that, diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index 163f7129a7b42..8a5037d045125 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -1457,14 +1457,14 @@ void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { } if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { - Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) - << /*RISC-V*/ 2 << 0; + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*RISC-V*/ 2 << /*interrupt*/ 0 << 0; return; } if (!getFunctionOrMethodResultType(D)->isVoidType()) { - Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) - << /*RISC-V*/ 2 << 1; + Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) + << /*RISC-V*/ 2 << /*interrupt*/ 0 << 1; return; } diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 25a07d0315eac..ec38674a2c3e7 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2716,8 +2716,10 @@ StmtResult Sema::BuildCXXForRangeStmt( // them in properly when we instantiate the loop. if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check) { if (auto *DD = dyn_cast(LoopVar)) - for (auto *Binding : DD->bindings()) - Binding->setType(Context.DependentTy); + for (auto *Binding : DD->bindings()) { + if (!Binding->isParameterPack()) + Binding->setType(Context.DependentTy); + } LoopVar->setType(SubstAutoTypeDependent(LoopVar->getType())); } } else if (!BeginDeclStmt.get()) { @@ -4568,9 +4570,27 @@ buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI, return false; } +static std::optional +isOpenMPCapturedRegionInArmSMEFunction(Sema const &S, CapturedRegionKind Kind) { + if (!S.getLangOpts().OpenMP || Kind != CR_OpenMP) + return {}; + if (const FunctionDecl *FD = S.getCurFunctionDecl(/*AllowLambda=*/true)) { + if (IsArmStreamingFunction(FD, /*IncludeLocallyStreaming=*/true)) + return /* in streaming functions */ 0; + if (hasArmZAState(FD)) + return /* in functions with ZA state */ 1; + if (hasArmZT0State(FD)) + return /* in fuctions with ZT0 state */ 2; + } + return {}; +} + void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams) { + if (auto ErrorIndex = isOpenMPCapturedRegionInArmSMEFunction(*this, Kind)) + Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex; + CapturedDecl *CD = nullptr; RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams); @@ -4602,6 +4622,9 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, ArrayRef Params, unsigned OpenMPCaptureLevel) { + if (auto ErrorIndex = isOpenMPCapturedRegionInArmSMEFunction(*this, Kind)) + Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex; + CapturedDecl *CD = nullptr; RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, Params.size()); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 38196c5c2bc12..9e68972b33f0a 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -38,6 +38,7 @@ #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/SaveAndRestore.h" #include using namespace clang; @@ -3497,10 +3498,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // Check that the template argument list is well-formed for this // template. - SmallVector SugaredConverted, CanonicalConverted; + CheckTemplateArgumentInfo CTAI; if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs, - DefaultArgs, false, SugaredConverted, - CanonicalConverted, + DefaultArgs, /*PartialTemplateArgs=*/false, + CTAI, /*UpdateArgsWithConversions=*/true)) return QualType(); @@ -3522,7 +3523,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // template type alias specializations apart. MultiLevelTemplateArgumentList TemplateArgLists; TemplateArgLists.addOuterTemplateArguments( - Template, SugaredConverted, + Template, CTAI.SugaredConverted, /*Final=*/!getLangOpts().RetainSubstTemplateTypeParmTypeAstNodes); TemplateArgLists.addOuterRetainedLevels( AliasTemplate->getTemplateParameters()->getDepth()); @@ -3582,11 +3583,11 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, return QualType(); } } else if (auto *BTD = dyn_cast(Template)) { - CanonType = checkBuiltinTemplateIdType(*this, BTD, SugaredConverted, + CanonType = checkBuiltinTemplateIdType(*this, BTD, CTAI.SugaredConverted, TemplateLoc, TemplateArgs); } else if (Name.isDependent() || TemplateSpecializationType::anyDependentTemplateArguments( - TemplateArgs, CanonicalConverted)) { + TemplateArgs, CTAI.CanonicalConverted)) { // This class template specialization is a dependent // type. Therefore, its canonical type is another class template // specialization type that contains all of the converted @@ -3595,7 +3596,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // // template struct A; CanonType = Context.getCanonicalTemplateSpecializationType( - Name, CanonicalConverted); + Name, CTAI.CanonicalConverted); // This might work out to be a current instantiation, in which // case the canonical type needs to be the InjectedClassNameType. @@ -3640,7 +3641,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // corresponds to these arguments. void *InsertPos = nullptr; ClassTemplateSpecializationDecl *Decl = - ClassTemplate->findSpecialization(CanonicalConverted, InsertPos); + ClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos); if (!Decl) { // This is the first time we have referenced this class template // specialization. Create the canonical declaration and add it to @@ -3649,8 +3650,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, Context, ClassTemplate->getTemplatedDecl()->getTagKind(), ClassTemplate->getDeclContext(), ClassTemplate->getTemplatedDecl()->getBeginLoc(), - ClassTemplate->getLocation(), ClassTemplate, CanonicalConverted, - nullptr); + ClassTemplate->getLocation(), ClassTemplate, CTAI.CanonicalConverted, + CTAI.StrictPackMatch, nullptr); ClassTemplate->AddSpecialization(Decl, InsertPos); if (ClassTemplate->isOutOfLine()) Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext()); @@ -3661,7 +3662,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, InstantiatingTemplate Inst(*this, TemplateLoc, Decl); if (!Inst.isInvalid()) { MultiLevelTemplateArgumentList TemplateArgLists(Template, - CanonicalConverted, + CTAI.CanonicalConverted, /*Final=*/false); InstantiateAttrsForDecl(TemplateArgLists, ClassTemplate->getTemplatedDecl(), Decl); @@ -4183,10 +4184,10 @@ DeclResult Sema::ActOnVarTemplateSpecialization( // Check that the template argument list is well-formed for this // template. - SmallVector SugaredConverted, CanonicalConverted; + CheckTemplateArgumentInfo CTAI; if (CheckTemplateArgumentList(VarTemplate, TemplateNameLoc, TemplateArgs, - /*DefaultArgs=*/{}, false, SugaredConverted, - CanonicalConverted, + /*DefaultArgs=*/{}, + /*PartialTemplateArgs=*/false, CTAI, /*UpdateArgsWithConversions=*/true)) return true; @@ -4195,21 +4196,21 @@ DeclResult Sema::ActOnVarTemplateSpecialization( if (IsPartialSpecialization) { if (CheckTemplatePartialSpecializationArgs(TemplateNameLoc, VarTemplate, TemplateArgs.size(), - CanonicalConverted)) + CTAI.CanonicalConverted)) return true; - // FIXME: Move these checks to CheckTemplatePartialSpecializationArgs so we - // also do them during instantiation. + // FIXME: Move these checks to CheckTemplatePartialSpecializationArgs so + // we also do them during instantiation. if (!Name.isDependent() && !TemplateSpecializationType::anyDependentTemplateArguments( - TemplateArgs, CanonicalConverted)) { + TemplateArgs, CTAI.CanonicalConverted)) { Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized) << VarTemplate->getDeclName(); IsPartialSpecialization = false; } if (isSameAsPrimaryTemplate(VarTemplate->getTemplateParameters(), - CanonicalConverted) && + CTAI.CanonicalConverted) && (!Context.getLangOpts().CPlusPlus20 || !TemplateParams->hasAssociatedConstraints())) { // C++ [temp.class.spec]p9b3: @@ -4217,11 +4218,11 @@ DeclResult Sema::ActOnVarTemplateSpecialization( // -- The argument list of the specialization shall not be identical // to the implicit argument list of the primary template. Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template) - << /*variable template*/ 1 - << /*is definition*/(SC != SC_Extern && !CurContext->isRecord()) - << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc)); - // FIXME: Recover from this by treating the declaration as a redeclaration - // of the primary template. + << /*variable template*/ 1 + << /*is definition*/ (SC != SC_Extern && !CurContext->isRecord()) + << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc)); + // FIXME: Recover from this by treating the declaration as a + // redeclaration of the primary template. return true; } } @@ -4231,9 +4232,10 @@ DeclResult Sema::ActOnVarTemplateSpecialization( if (IsPartialSpecialization) PrevDecl = VarTemplate->findPartialSpecialization( - CanonicalConverted, TemplateParams, InsertPos); + CTAI.CanonicalConverted, TemplateParams, InsertPos); else - PrevDecl = VarTemplate->findSpecialization(CanonicalConverted, InsertPos); + PrevDecl = + VarTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos); VarTemplateSpecializationDecl *Specialization = nullptr; @@ -4260,7 +4262,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( VarTemplatePartialSpecializationDecl::Create( Context, VarTemplate->getDeclContext(), TemplateKWLoc, TemplateNameLoc, TemplateParams, VarTemplate, DI->getType(), DI, SC, - CanonicalConverted); + CTAI.CanonicalConverted); Partial->setTemplateArgsAsWritten(TemplateArgs); if (!PrevPartial) @@ -4278,7 +4280,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( // this explicit specialization or friend declaration. Specialization = VarTemplateSpecializationDecl::Create( Context, VarTemplate->getDeclContext(), TemplateKWLoc, TemplateNameLoc, - VarTemplate, DI->getType(), DI, SC, CanonicalConverted); + VarTemplate, DI->getType(), DI, SC, CTAI.CanonicalConverted); Specialization->setTemplateArgsAsWritten(TemplateArgs); if (!PrevDecl) @@ -4350,25 +4352,25 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, assert(Template && "A variable template id without template?"); // Check that the template argument list is well-formed for this template. - SmallVector SugaredConverted, CanonicalConverted; + CheckTemplateArgumentInfo CTAI; if (CheckTemplateArgumentList( Template, TemplateNameLoc, const_cast(TemplateArgs), - /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted, + /*DefaultArgs=*/{}, /*PartialTemplateArgs=*/false, CTAI, /*UpdateArgsWithConversions=*/true)) return true; // Produce a placeholder value if the specialization is dependent. if (Template->getDeclContext()->isDependentContext() || TemplateSpecializationType::anyDependentTemplateArguments( - TemplateArgs, CanonicalConverted)) + TemplateArgs, CTAI.CanonicalConverted)) return DeclResult(); // Find the variable template specialization declaration that // corresponds to these arguments. void *InsertPos = nullptr; if (VarTemplateSpecializationDecl *Spec = - Template->findSpecialization(CanonicalConverted, InsertPos)) { + Template->findSpecialization(CTAI.CanonicalConverted, InsertPos)) { checkSpecializationReachability(TemplateNameLoc, Spec); // If we already have a variable template specialization, return it. return Spec; @@ -4412,7 +4414,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, TemplateDeductionInfo Info(FailedCandidates.getLocation()); if (TemplateDeductionResult Result = - DeduceTemplateArguments(Partial, SugaredConverted, Info); + DeduceTemplateArguments(Partial, CTAI.SugaredConverted, Info); Result != TemplateDeductionResult::Success) { // Store the failed-deduction information for use in diagnostics, later. // TODO: Actually use the failed-deduction info? @@ -4479,7 +4481,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc, // FIXME: LateAttrs et al.? VarTemplateSpecializationDecl *Decl = BuildVarTemplateInstantiation( Template, InstantiationPattern, PartialSpecArgs, TemplateArgs, - CanonicalConverted, TemplateNameLoc /*, LateAttrs, StartingScope*/); + CTAI.CanonicalConverted, TemplateNameLoc /*, LateAttrs, StartingScope*/); if (!Decl) return true; @@ -4559,12 +4561,12 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, if (NamedConcept->isInvalidDecl()) return ExprError(); - llvm::SmallVector SugaredConverted, CanonicalConverted; + CheckTemplateArgumentInfo CTAI; if (CheckTemplateArgumentList( NamedConcept, ConceptNameInfo.getLoc(), const_cast(*TemplateArgs), /*DefaultArgs=*/{}, - /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted, + /*PartialTemplateArgs=*/false, CTAI, /*UpdateArgsWithConversions=*/false)) return ExprError(); @@ -4572,12 +4574,12 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, auto *CSD = ImplicitConceptSpecializationDecl::Create( Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(), - CanonicalConverted); + CTAI.CanonicalConverted); ConstraintSatisfaction Satisfaction; bool AreArgsDependent = TemplateSpecializationType::anyDependentTemplateArguments( - *TemplateArgs, CanonicalConverted); - MultiLevelTemplateArgumentList MLTAL(NamedConcept, CanonicalConverted, + *TemplateArgs, CTAI.CanonicalConverted); + MultiLevelTemplateArgumentList MLTAL(NamedConcept, CTAI.CanonicalConverted, /*Final=*/false); LocalInstantiationScope Scope(*this); @@ -5198,19 +5200,19 @@ convertTypeTemplateArgumentToTemplate(ASTContext &Context, TypeLoc TLoc) { return TemplateArgumentLoc(); } -bool Sema::CheckTemplateArgument( - NamedDecl *Param, TemplateArgumentLoc &Arg, NamedDecl *Template, - SourceLocation TemplateLoc, SourceLocation RAngleLoc, - unsigned ArgumentPackIndex, - SmallVectorImpl &SugaredConverted, - SmallVectorImpl &CanonicalConverted, - CheckTemplateArgumentKind CTAK, bool PartialOrdering, - bool *MatchedPackOnParmToNonPackOnArg) { +bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, + NamedDecl *Template, + SourceLocation TemplateLoc, + SourceLocation RAngleLoc, + unsigned ArgumentPackIndex, + CheckTemplateArgumentInfo &CTAI, + CheckTemplateArgumentKind CTAK) { // Check template type parameters. if (TemplateTypeParmDecl *TTP = dyn_cast(Param)) - return CheckTemplateTypeArgument(TTP, Arg, SugaredConverted, - CanonicalConverted); + return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted, + CTAI.CanonicalConverted); + const TemplateArgument &Arg = ArgLoc.getArgument(); // Check non-type template parameters. if (NonTypeTemplateParmDecl *NTTP =dyn_cast(Param)) { // Do substitution on the type of the non-type template parameter @@ -5225,12 +5227,12 @@ bool Sema::CheckTemplateArgument( !Template->getDeclContext()->isDependentContext()) { // Do substitution on the type of the non-type template parameter. InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP, - SugaredConverted, + CTAI.SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return true; - MultiLevelTemplateArgumentList MLTAL(Template, SugaredConverted, + MultiLevelTemplateArgumentList MLTAL(Template, CTAI.SugaredConverted, /*Final=*/true); // If the parameter is a pack expansion, expand this slice of the pack. if (auto *PET = NTTPType->getAs()) { @@ -5252,62 +5254,73 @@ bool Sema::CheckTemplateArgument( return true; } - switch (Arg.getArgument().getKind()) { + auto checkExpr = [&](Expr *E) -> Expr * { + TemplateArgument SugaredResult, CanonicalResult; + unsigned CurSFINAEErrors = NumSFINAEErrors; + ExprResult Res = + CheckTemplateArgument(NTTP, NTTPType, E, SugaredResult, + CanonicalResult, CTAI.MatchingTTP, CTAK); + // If the current template argument causes an error, give up now. + if (Res.isInvalid() || CurSFINAEErrors < NumSFINAEErrors) + return nullptr; + CTAI.SugaredConverted.push_back(SugaredResult); + CTAI.CanonicalConverted.push_back(CanonicalResult); + return Res.get(); + }; + + switch (Arg.getKind()) { case TemplateArgument::Null: llvm_unreachable("Should never see a NULL template argument here"); case TemplateArgument::Expression: { - Expr *E = Arg.getArgument().getAsExpr(); - TemplateArgument SugaredResult, CanonicalResult; - unsigned CurSFINAEErrors = NumSFINAEErrors; - ExprResult Res = CheckTemplateArgument(NTTP, NTTPType, E, SugaredResult, - CanonicalResult, CTAK); - if (Res.isInvalid()) + Expr *E = Arg.getAsExpr(); + Expr *R = checkExpr(E); + if (!R) return true; - // If the current template argument causes an error, give up now. - if (CurSFINAEErrors < NumSFINAEErrors) - return true; - // If the resulting expression is new, then use it in place of the // old expression in the template argument. - if (Res.get() != E) { - TemplateArgument TA(Res.get()); - Arg = TemplateArgumentLoc(TA, Res.get()); + if (R != E) { + TemplateArgument TA(R); + ArgLoc = TemplateArgumentLoc(TA, R); } - - SugaredConverted.push_back(SugaredResult); - CanonicalConverted.push_back(CanonicalResult); break; } - case TemplateArgument::Declaration: + // As for the converted NTTP kinds, they still might need another + // conversion, as the new corresponding parameter might be different. + // Ideally, we would always perform substitution starting with sugared types + // and never need these, as we would still have expressions. Since these are + // needed so rarely, it's probably a better tradeoff to just convert them + // back to expressions. case TemplateArgument::Integral: - case TemplateArgument::StructuralValue: + case TemplateArgument::Declaration: case TemplateArgument::NullPtr: - // We've already checked this template argument, so just copy - // it to the list of converted arguments. - SugaredConverted.push_back(Arg.getArgument()); - CanonicalConverted.push_back( - Context.getCanonicalTemplateArgument(Arg.getArgument())); + case TemplateArgument::StructuralValue: { + // FIXME: StructuralValue is untested here. + ExprResult R = + BuildExpressionFromNonTypeTemplateArgument(Arg, SourceLocation()); + assert(R.isUsable()); + if (!checkExpr(R.get())) + return true; break; + } case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: // We were given a template template argument. It may not be ill-formed; // see below. - if (DependentTemplateName *DTN - = Arg.getArgument().getAsTemplateOrTemplatePattern() - .getAsDependentTemplateName()) { + if (DependentTemplateName *DTN = Arg.getAsTemplateOrTemplatePattern() + .getAsDependentTemplateName()) { // We have a template argument such as \c T::template X, which we // parsed as a template template argument. However, since we now // know that we need a non-type template argument, convert this // template name into an expression. DeclarationNameInfo NameInfo(DTN->getIdentifier(), - Arg.getTemplateNameLoc()); + ArgLoc.getTemplateNameLoc()); CXXScopeSpec SS; - SS.Adopt(Arg.getTemplateQualifierLoc()); + SS.Adopt(ArgLoc.getTemplateQualifierLoc()); // FIXME: the template-template arg was a DependentTemplateName, // so it was provided with a template keyword. However, its source // location is not stored in the template argument structure. @@ -5318,28 +5331,29 @@ bool Sema::CheckTemplateArgument( // If we parsed the template argument as a pack expansion, create a // pack expansion expression. - if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){ - E = ActOnPackExpansion(E.get(), Arg.getTemplateEllipsisLoc()); + if (Arg.getKind() == TemplateArgument::TemplateExpansion) { + E = ActOnPackExpansion(E.get(), ArgLoc.getTemplateEllipsisLoc()); if (E.isInvalid()) return true; } TemplateArgument SugaredResult, CanonicalResult; E = CheckTemplateArgument(NTTP, NTTPType, E.get(), SugaredResult, - CanonicalResult, CTAK_Specified); + CanonicalResult, /*PartialOrderingTTP=*/false, + CTAK_Specified); if (E.isInvalid()) return true; - SugaredConverted.push_back(SugaredResult); - CanonicalConverted.push_back(CanonicalResult); + CTAI.SugaredConverted.push_back(SugaredResult); + CTAI.CanonicalConverted.push_back(CanonicalResult); break; } // We have a template argument that actually does refer to a class // template, alias template, or template template parameter, and // therefore cannot be a non-type template argument. - Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr) - << Arg.getSourceRange(); + Diag(ArgLoc.getLocation(), diag::err_template_arg_must_be_expr) + << ArgLoc.getSourceRange(); NoteTemplateParameterLocation(*Param); return true; @@ -5355,8 +5369,8 @@ bool Sema::CheckTemplateArgument( // // We warn specifically about this case, since it can be rather // confusing for users. - QualType T = Arg.getArgument().getAsType(); - SourceRange SR = Arg.getSourceRange(); + QualType T = Arg.getAsType(); + SourceRange SR = ArgLoc.getSourceRange(); if (T->isFunctionType()) Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) << SR << T; else @@ -5389,16 +5403,16 @@ bool Sema::CheckTemplateArgument( // Set up a template instantiation context. LocalInstantiationScope Scope(*this); InstantiatingTemplate Inst(*this, TemplateLoc, Template, TempParm, - SugaredConverted, + CTAI.SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return true; - Params = - SubstTemplateParams(Params, CurContext, - MultiLevelTemplateArgumentList( - Template, SugaredConverted, /*Final=*/true), - /*EvaluateConstraints=*/false); + Params = SubstTemplateParams( + Params, CurContext, + MultiLevelTemplateArgumentList(Template, CTAI.SugaredConverted, + /*Final=*/true), + /*EvaluateConstraints=*/false); if (!Params) return true; } @@ -5407,34 +5421,35 @@ bool Sema::CheckTemplateArgument( // When [the injected-class-name] is used [...] as a template-argument for // a template template-parameter [...] it refers to the class template // itself. - if (Arg.getArgument().getKind() == TemplateArgument::Type) { + if (Arg.getKind() == TemplateArgument::Type) { TemplateArgumentLoc ConvertedArg = convertTypeTemplateArgumentToTemplate( - Context, Arg.getTypeSourceInfo()->getTypeLoc()); + Context, ArgLoc.getTypeSourceInfo()->getTypeLoc()); if (!ConvertedArg.getArgument().isNull()) - Arg = ConvertedArg; + ArgLoc = ConvertedArg; } - switch (Arg.getArgument().getKind()) { + switch (Arg.getKind()) { case TemplateArgument::Null: llvm_unreachable("Should never see a NULL template argument here"); case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: - if (CheckTemplateTemplateArgument(TempParm, Params, Arg, PartialOrdering, - MatchedPackOnParmToNonPackOnArg)) + if (CheckTemplateTemplateArgument(TempParm, Params, ArgLoc, + CTAI.PartialOrdering, + &CTAI.StrictPackMatch)) return true; - SugaredConverted.push_back(Arg.getArgument()); - CanonicalConverted.push_back( - Context.getCanonicalTemplateArgument(Arg.getArgument())); + CTAI.SugaredConverted.push_back(Arg); + CTAI.CanonicalConverted.push_back( + Context.getCanonicalTemplateArgument(Arg)); break; case TemplateArgument::Expression: case TemplateArgument::Type: // We have a template template parameter but the template // argument does not refer to a template. - Diag(Arg.getLocation(), diag::err_template_arg_must_be_template) - << getLangOpts().CPlusPlus11; + Diag(ArgLoc.getLocation(), diag::err_template_arg_must_be_template) + << getLangOpts().CPlusPlus11; return true; case TemplateArgument::Declaration: @@ -5491,11 +5506,8 @@ static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc, bool Sema::CheckTemplateArgumentList( TemplateDecl *Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs, - bool PartialTemplateArgs, - SmallVectorImpl &SugaredConverted, - SmallVectorImpl &CanonicalConverted, - bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied, - bool PartialOrderingTTP, bool *MatchedPackOnParmToNonPackOnArg) { + bool PartialTemplateArgs, CheckTemplateArgumentInfo &CTAI, + bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied) { if (ConstraintsNotSatisfied) *ConstraintsNotSatisfied = false; @@ -5532,8 +5544,8 @@ bool Sema::CheckTemplateArgumentList( assert(Param + DefaultArgs.Args.size() <= ParamEnd); // Default arguments from a DeducedTemplateName are already converted. for (const TemplateArgument &DefArg : DefaultArgs.Args) { - SugaredConverted.push_back(DefArg); - CanonicalConverted.push_back( + CTAI.SugaredConverted.push_back(DefArg); + CTAI.CanonicalConverted.push_back( Context.getCanonicalTemplateArgument(DefArg)); ++Param; } @@ -5547,11 +5559,11 @@ bool Sema::CheckTemplateArgumentList( if (*Expansions == SugaredArgumentPack.size()) { // We're done with this parameter pack. Pack up its arguments and add // them to the list. - SugaredConverted.push_back( + CTAI.SugaredConverted.push_back( TemplateArgument::CreatePackCopy(Context, SugaredArgumentPack)); SugaredArgumentPack.clear(); - CanonicalConverted.push_back( + CTAI.CanonicalConverted.push_back( TemplateArgument::CreatePackCopy(Context, CanonicalArgumentPack)); CanonicalArgumentPack.clear(); @@ -5575,7 +5587,7 @@ bool Sema::CheckTemplateArgumentList( !(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param); bool ArgIsExpansion = ArgLoc.getArgument().isPackExpansion(); - if (ArgIsExpansion && PartialOrderingTTP) { + if (ArgIsExpansion && CTAI.MatchingTTP) { SmallVector Args(ParamEnd - Param); for (TemplateParameterList::iterator First = Param; Param != ParamEnd; ++Param) { @@ -5585,31 +5597,30 @@ bool Sema::CheckTemplateArgumentList( getExpandedPackSize(*Param)) Arg = Arg.getPackExpansionPattern(); TemplateArgumentLoc NewArgLoc(Arg, ArgLoc.getLocInfo()); + SaveAndRestore _1(CTAI.PartialOrdering, false); + SaveAndRestore _2(CTAI.MatchingTTP, true); if (CheckTemplateArgument(*Param, NewArgLoc, Template, TemplateLoc, - RAngleLoc, SugaredArgumentPack.size(), - SugaredConverted, CanonicalConverted, - CTAK_Specified, /*PartialOrdering=*/false, - MatchedPackOnParmToNonPackOnArg)) + RAngleLoc, SugaredArgumentPack.size(), CTAI, + CTAK_Specified)) return true; Arg = NewArgLoc.getArgument(); - CanonicalConverted.back().setIsDefaulted( + CTAI.CanonicalConverted.back().setIsDefaulted( clang::isSubstitutedDefaultArgument(Context, Arg, *Param, - CanonicalConverted, + CTAI.CanonicalConverted, Params->getDepth())); } ArgLoc = TemplateArgumentLoc(TemplateArgument::CreatePackCopy(Context, Args), ArgLoc.getLocInfo()); } else { + SaveAndRestore _1(CTAI.PartialOrdering, false); if (CheckTemplateArgument(*Param, ArgLoc, Template, TemplateLoc, - RAngleLoc, SugaredArgumentPack.size(), - SugaredConverted, CanonicalConverted, - CTAK_Specified, /*PartialOrdering=*/false, - MatchedPackOnParmToNonPackOnArg)) + RAngleLoc, SugaredArgumentPack.size(), CTAI, + CTAK_Specified)) return true; - CanonicalConverted.back().setIsDefaulted( + CTAI.CanonicalConverted.back().setIsDefaulted( clang::isSubstitutedDefaultArgument(Context, ArgLoc.getArgument(), - *Param, CanonicalConverted, + *Param, CTAI.CanonicalConverted, Params->getDepth())); if (ArgIsExpansion && NonPackParameter) { // CWG1430/CWG2686: we have a pack expansion as an argument to an @@ -5629,28 +5640,28 @@ bool Sema::CheckTemplateArgumentList( // We're now done with this argument. ++ArgIdx; - if (ArgIsExpansion && (PartialOrderingTTP || NonPackParameter)) { + if (ArgIsExpansion && (CTAI.MatchingTTP || NonPackParameter)) { // Directly convert the remaining arguments, because we don't know what // parameters they'll match up with. if (!SugaredArgumentPack.empty()) { // If we were part way through filling in an expanded parameter pack, // fall back to just producing individual arguments. - SugaredConverted.insert(SugaredConverted.end(), - SugaredArgumentPack.begin(), - SugaredArgumentPack.end()); + CTAI.SugaredConverted.insert(CTAI.SugaredConverted.end(), + SugaredArgumentPack.begin(), + SugaredArgumentPack.end()); SugaredArgumentPack.clear(); - CanonicalConverted.insert(CanonicalConverted.end(), - CanonicalArgumentPack.begin(), - CanonicalArgumentPack.end()); + CTAI.CanonicalConverted.insert(CTAI.CanonicalConverted.end(), + CanonicalArgumentPack.begin(), + CanonicalArgumentPack.end()); CanonicalArgumentPack.clear(); } while (ArgIdx < NumArgs) { const TemplateArgument &Arg = NewArgs[ArgIdx].getArgument(); - SugaredConverted.push_back(Arg); - CanonicalConverted.push_back( + CTAI.SugaredConverted.push_back(Arg); + CTAI.CanonicalConverted.push_back( Context.getCanonicalTemplateArgument(Arg)); ++ArgIdx; } @@ -5663,8 +5674,8 @@ bool Sema::CheckTemplateArgumentList( // deduced argument and place it on the argument pack. Note that we // stay on the same template parameter so that we can deduce more // arguments. - SugaredArgumentPack.push_back(SugaredConverted.pop_back_val()); - CanonicalArgumentPack.push_back(CanonicalConverted.pop_back_val()); + SugaredArgumentPack.push_back(CTAI.SugaredConverted.pop_back_val()); + CanonicalArgumentPack.push_back(CTAI.CanonicalConverted.pop_back_val()); } else { // Move to the next template parameter. ++Param; @@ -5675,9 +5686,9 @@ bool Sema::CheckTemplateArgumentList( // If we're checking a partial template argument list, we're done. if (PartialTemplateArgs) { if ((*Param)->isTemplateParameterPack() && !SugaredArgumentPack.empty()) { - SugaredConverted.push_back( + CTAI.SugaredConverted.push_back( TemplateArgument::CreatePackCopy(Context, SugaredArgumentPack)); - CanonicalConverted.push_back( + CTAI.CanonicalConverted.push_back( TemplateArgument::CreatePackCopy(Context, CanonicalArgumentPack)); } return false; @@ -5699,11 +5710,11 @@ bool Sema::CheckTemplateArgumentList( return true; } - SugaredConverted.push_back( + CTAI.SugaredConverted.push_back( TemplateArgument::CreatePackCopy(Context, SugaredArgumentPack)); SugaredArgumentPack.clear(); - CanonicalConverted.push_back( + CTAI.CanonicalConverted.push_back( TemplateArgument::CreatePackCopy(Context, CanonicalArgumentPack)); CanonicalArgumentPack.clear(); @@ -5720,8 +5731,8 @@ bool Sema::CheckTemplateArgumentList( // (when the template parameter was part of a nested template) into // the default argument. TemplateArgumentLoc Arg = SubstDefaultTemplateArgumentIfAvailable( - Template, TemplateLoc, RAngleLoc, *Param, SugaredConverted, - CanonicalConverted, HasDefaultArg); + Template, TemplateLoc, RAngleLoc, *Param, CTAI.SugaredConverted, + CTAI.CanonicalConverted, HasDefaultArg); if (Arg.getArgument().isNull()) { if (!HasDefaultArg) { @@ -5744,20 +5755,21 @@ bool Sema::CheckTemplateArgumentList( // template here, we just create this object to put a note into the // context stack. InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param, - SugaredConverted, + CTAI.SugaredConverted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return true; + SaveAndRestore _1(CTAI.PartialOrdering, false); + SaveAndRestore _2(CTAI.MatchingTTP, false); + SaveAndRestore _3(CTAI.StrictPackMatch, {}); // Check the default template argument. if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc, RAngleLoc, 0, - SugaredConverted, CanonicalConverted, - CTAK_Specified, /*PartialOrdering=*/false, - /*MatchedPackOnParmToNonPackOnArg=*/nullptr)) + CTAI, CTAK_Specified)) return true; - SugaredConverted.back().setIsDefaulted(true); - CanonicalConverted.back().setIsDefaulted(true); + CTAI.SugaredConverted.back().setIsDefaulted(true); + CTAI.CanonicalConverted.back().setIsDefaulted(true); // Core issue 150 (assumed resolution): if this is a template template // parameter, keep track of the default template arguments from the @@ -5774,14 +5786,15 @@ bool Sema::CheckTemplateArgumentList( // pack expansions; they might be empty. This can happen even if // PartialTemplateArgs is false (the list of arguments is complete but // still dependent). - if (PartialOrderingTTP || + if (CTAI.MatchingTTP || (CurrentInstantiationScope && CurrentInstantiationScope->getPartiallySubstitutedPack())) { while (ArgIdx < NumArgs && NewArgs[ArgIdx].getArgument().isPackExpansion()) { const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument(); - SugaredConverted.push_back(Arg); - CanonicalConverted.push_back(Context.getCanonicalTemplateArgument(Arg)); + CTAI.SugaredConverted.push_back(Arg); + CTAI.CanonicalConverted.push_back( + Context.getCanonicalTemplateArgument(Arg)); } } @@ -5822,7 +5835,7 @@ bool Sema::CheckTemplateArgumentList( CXXThisScopeRAII(*this, RD, ThisQuals, RD != nullptr); MultiLevelTemplateArgumentList MLTAL = getTemplateInstantiationArgs( - Template, NewContext, /*Final=*/false, CanonicalConverted, + Template, NewContext, /*Final=*/false, CTAI.CanonicalConverted, /*RelativeToPrimary=*/true, /*Pattern=*/nullptr, /*ForConceptInstantiation=*/true); @@ -6740,6 +6753,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, QualType ParamType, Expr *Arg, TemplateArgument &SugaredConverted, TemplateArgument &CanonicalConverted, + bool PartialOrderingTTP, CheckTemplateArgumentKind CTAK) { SourceLocation StartLoc = Arg->getBeginLoc(); @@ -6930,17 +6944,21 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, IsConvertedConstantExpression = false; } - if (getLangOpts().CPlusPlus17) { + if (getLangOpts().CPlusPlus17 || PartialOrderingTTP) { // C++17 [temp.arg.nontype]p1: // A template-argument for a non-type template parameter shall be // a converted constant expression of the type of the template-parameter. APValue Value; ExprResult ArgResult; if (IsConvertedConstantExpression) { - ArgResult = BuildConvertedConstantExpression(Arg, ParamType, - CCEK_TemplateArg, Param); - if (ArgResult.isInvalid()) + ArgResult = BuildConvertedConstantExpression( + Arg, ParamType, + PartialOrderingTTP ? CCEK_InjectedTTP : CCEK_TemplateArg, Param); + assert(!ArgResult.isUnset()); + if (ArgResult.isInvalid()) { + NoteTemplateParameterLocation(*Param); return ExprError(); + } } else { ArgResult = Arg; } @@ -7343,10 +7361,11 @@ static void DiagnoseTemplateParameterListArityMismatch( Sema &S, TemplateParameterList *New, TemplateParameterList *Old, Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc); -bool Sema::CheckTemplateTemplateArgument( - TemplateTemplateParmDecl *Param, TemplateParameterList *Params, - TemplateArgumentLoc &Arg, bool PartialOrdering, - bool *MatchedPackOnParmToNonPackOnArg) { +bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, + TemplateParameterList *Params, + TemplateArgumentLoc &Arg, + bool PartialOrdering, + bool *StrictPackMatch) { TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern(); auto [Template, DefaultArgs] = Name.getTemplateDeclAndDefaultArgs(); if (!Template) { @@ -7381,17 +7400,12 @@ bool Sema::CheckTemplateTemplateArgument( << Template; } - if (!getLangOpts().RelaxedTemplateTemplateArgs) - return !TemplateParameterListsAreEqual( - Template->getTemplateParameters(), Params, /*Complain=*/true, - TPL_TemplateTemplateArgumentMatch, Arg.getLocation()); - // C++1z [temp.arg.template]p3: (DR 150) // A template-argument matches a template template-parameter P when P // is at least as specialized as the template-argument A. if (!isTemplateTemplateParameterAtLeastAsSpecializedAs( Params, Param, Template, DefaultArgs, Arg.getLocation(), - PartialOrdering, MatchedPackOnParmToNonPackOnArg)) + PartialOrdering, StrictPackMatch)) return true; // P2113 // C++20[temp.func.order]p2 @@ -7757,9 +7771,7 @@ static bool MatchTemplateParameterKind( // However, if we are matching a template template argument to a // template template parameter, the template template parameter can have // a parameter pack where the template template argument does not. - if (Old->isTemplateParameterPack() != New->isTemplateParameterPack() && - !(Kind == Sema::TPL_TemplateTemplateArgumentMatch && - Old->isTemplateParameterPack())) { + if (Old->isTemplateParameterPack() != New->isTemplateParameterPack()) { if (Complain) { unsigned NextDiag = diag::err_template_parameter_pack_non_pack; if (TemplateArgLoc.isValid()) { @@ -7785,37 +7797,28 @@ static bool MatchTemplateParameterKind( = dyn_cast(Old)) { NonTypeTemplateParmDecl *NewNTTP = cast(New); - // If we are matching a template template argument to a template - // template parameter and one of the non-type template parameter types - // is dependent, then we must wait until template instantiation time - // to actually compare the arguments. - if (Kind != Sema::TPL_TemplateTemplateArgumentMatch || - (!OldNTTP->getType()->isDependentType() && - !NewNTTP->getType()->isDependentType())) { - // C++20 [temp.over.link]p6: - // Two [non-type] template-parameters are equivalent [if] they have - // equivalent types ignoring the use of type-constraints for - // placeholder types - QualType OldType = S.Context.getUnconstrainedType(OldNTTP->getType()); - QualType NewType = S.Context.getUnconstrainedType(NewNTTP->getType()); - if (!S.Context.hasSameType(OldType, NewType)) { - if (Complain) { - unsigned NextDiag = diag::err_template_nontype_parm_different_type; - if (TemplateArgLoc.isValid()) { - S.Diag(TemplateArgLoc, - diag::err_template_arg_template_params_mismatch); - NextDiag = diag::note_template_nontype_parm_different_type; - } - S.Diag(NewNTTP->getLocation(), NextDiag) - << NewNTTP->getType() - << (Kind != Sema::TPL_TemplateMatch); - S.Diag(OldNTTP->getLocation(), - diag::note_template_nontype_parm_prev_declaration) - << OldNTTP->getType(); + // C++20 [temp.over.link]p6: + // Two [non-type] template-parameters are equivalent [if] they have + // equivalent types ignoring the use of type-constraints for + // placeholder types + QualType OldType = S.Context.getUnconstrainedType(OldNTTP->getType()); + QualType NewType = S.Context.getUnconstrainedType(NewNTTP->getType()); + if (!S.Context.hasSameType(OldType, NewType)) { + if (Complain) { + unsigned NextDiag = diag::err_template_nontype_parm_different_type; + if (TemplateArgLoc.isValid()) { + S.Diag(TemplateArgLoc, + diag::err_template_arg_template_params_mismatch); + NextDiag = diag::note_template_nontype_parm_different_type; } - - return false; + S.Diag(NewNTTP->getLocation(), NextDiag) + << NewNTTP->getType() << (Kind != Sema::TPL_TemplateMatch); + S.Diag(OldNTTP->getLocation(), + diag::note_template_nontype_parm_prev_declaration) + << OldNTTP->getType(); } + + return false; } } // For template template parameters, check the template parameter types. @@ -7835,7 +7838,6 @@ static bool MatchTemplateParameterKind( } if (Kind != Sema::TPL_TemplateParamsEquivalent && - Kind != Sema::TPL_TemplateTemplateArgumentMatch && !isa(Old)) { const Expr *NewC = nullptr, *OldC = nullptr; @@ -7906,7 +7908,7 @@ bool Sema::TemplateParameterListsAreEqual( const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) { - if (Old->size() != New->size() && Kind != TPL_TemplateTemplateArgumentMatch) { + if (Old->size() != New->size()) { if (Complain) DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, TemplateArgLoc); @@ -7923,40 +7925,18 @@ bool Sema::TemplateParameterListsAreEqual( TemplateParameterList::iterator NewParm = New->begin(); TemplateParameterList::iterator NewParmEnd = New->end(); for (TemplateParameterList::iterator OldParm = Old->begin(), - OldParmEnd = Old->end(); - OldParm != OldParmEnd; ++OldParm) { - if (Kind != TPL_TemplateTemplateArgumentMatch || - !(*OldParm)->isTemplateParameterPack()) { - if (NewParm == NewParmEnd) { - if (Complain) - DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, - TemplateArgLoc); - - return false; - } - - if (!MatchTemplateParameterKind(*this, *NewParm, NewInstFrom, *OldParm, - OldInstFrom, Complain, Kind, - TemplateArgLoc)) - return false; - - ++NewParm; - continue; - } - - // C++0x [temp.arg.template]p3: - // [...] When P's template- parameter-list contains a template parameter - // pack (14.5.3), the template parameter pack will match zero or more - // template parameters or template parameter packs in the - // template-parameter-list of A with the same type and form as the - // template parameter pack in P (ignoring whether those template - // parameters are template parameter packs). - for (; NewParm != NewParmEnd; ++NewParm) { - if (!MatchTemplateParameterKind(*this, *NewParm, NewInstFrom, *OldParm, - OldInstFrom, Complain, Kind, - TemplateArgLoc)) - return false; + OldParmEnd = Old->end(); + OldParm != OldParmEnd; ++OldParm, ++NewParm) { + if (NewParm == NewParmEnd) { + if (Complain) + DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, + TemplateArgLoc); + return false; } + if (!MatchTemplateParameterKind(*this, *NewParm, NewInstFrom, *OldParm, + OldInstFrom, Complain, Kind, + TemplateArgLoc)) + return false; } // Make sure we exhausted all of the arguments. @@ -7968,8 +7948,7 @@ bool Sema::TemplateParameterListsAreEqual( return false; } - if (Kind != TPL_TemplateTemplateArgumentMatch && - Kind != TPL_TemplateParamsEquivalent) { + if (Kind != TPL_TemplateParamsEquivalent) { const Expr *NewRC = New->getRequiresClause(); const Expr *OldRC = Old->getRequiresClause(); @@ -8441,11 +8420,10 @@ DeclResult Sema::ActOnClassTemplateSpecialization( // Check that the template argument list is well-formed for this // template. - SmallVector SugaredConverted, CanonicalConverted; + CheckTemplateArgumentInfo CTAI; if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs, /*DefaultArgs=*/{}, - /*PartialTemplateArgs=*/false, SugaredConverted, - CanonicalConverted, + /*PartialTemplateArgs=*/false, CTAI, /*UpdateArgsWithConversions=*/true)) return true; @@ -8454,14 +8432,14 @@ DeclResult Sema::ActOnClassTemplateSpecialization( if (isPartialSpecialization) { if (CheckTemplatePartialSpecializationArgs(TemplateNameLoc, ClassTemplate, TemplateArgs.size(), - CanonicalConverted)) + CTAI.CanonicalConverted)) return true; // FIXME: Move this to CheckTemplatePartialSpecializationArgs so we // also do it during instantiation. if (!Name.isDependent() && !TemplateSpecializationType::anyDependentTemplateArguments( - TemplateArgs, CanonicalConverted)) { + TemplateArgs, CTAI.CanonicalConverted)) { Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized) << ClassTemplate->getDeclName(); isPartialSpecialization = false; @@ -8474,9 +8452,10 @@ DeclResult Sema::ActOnClassTemplateSpecialization( if (isPartialSpecialization) PrevDecl = ClassTemplate->findPartialSpecialization( - CanonicalConverted, TemplateParams, InsertPos); + CTAI.CanonicalConverted, TemplateParams, InsertPos); else - PrevDecl = ClassTemplate->findSpecialization(CanonicalConverted, InsertPos); + PrevDecl = + ClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos); ClassTemplateSpecializationDecl *Specialization = nullptr; @@ -8495,7 +8474,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( // arguments of the class template partial specialization. TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name); CanonType = Context.getTemplateSpecializationType(CanonTemplate, - CanonicalConverted); + CTAI.CanonicalConverted); if (Context.hasSameType(CanonType, ClassTemplate->getInjectedClassNameSpecialization()) && @@ -8525,7 +8504,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( ClassTemplatePartialSpecializationDecl *Partial = ClassTemplatePartialSpecializationDecl::Create( Context, Kind, DC, KWLoc, TemplateNameLoc, TemplateParams, - ClassTemplate, CanonicalConverted, CanonType, PrevPartial); + ClassTemplate, CTAI.CanonicalConverted, CanonType, PrevPartial); Partial->setTemplateArgsAsWritten(TemplateArgs); SetNestedNameSpecifier(*this, Partial, SS); if (TemplateParameterLists.size() > 1 && SS.isSet()) { @@ -8548,7 +8527,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( // this explicit specialization or friend declaration. Specialization = ClassTemplateSpecializationDecl::Create( Context, Kind, DC, KWLoc, TemplateNameLoc, ClassTemplate, - CanonicalConverted, PrevDecl); + CTAI.CanonicalConverted, CTAI.StrictPackMatch, PrevDecl); Specialization->setTemplateArgsAsWritten(TemplateArgs); SetNestedNameSpecifier(*this, Specialization, SS); if (TemplateParameterLists.size() > 0) { @@ -8561,8 +8540,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization( if (CurContext->isDependentContext()) { TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name); - CanonType = Context.getTemplateSpecializationType(CanonTemplate, - CanonicalConverted); + CanonType = Context.getTemplateSpecializationType( + CanonTemplate, CTAI.CanonicalConverted); } else { CanonType = Context.getTypeDeclType(Specialization); } @@ -9821,21 +9800,18 @@ DeclResult Sema::ActOnExplicitInstantiation( // Check that the template argument list is well-formed for this // template. - bool PrimaryHasMatchedPackOnParmToNonPackOnArg = false; - SmallVector SugaredConverted, CanonicalConverted; - if (CheckTemplateArgumentList( - ClassTemplate, TemplateNameLoc, TemplateArgs, - /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted, - /*UpdateArgsWithConversions=*/true, - /*ConstraintsNotSatisfied=*/nullptr, /*PartialOrderingTTP=*/false, - &PrimaryHasMatchedPackOnParmToNonPackOnArg)) + CheckTemplateArgumentInfo CTAI; + if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs, + /*DefaultArgs=*/{}, false, CTAI, + /*UpdateArgsWithConversions=*/true, + /*ConstraintsNotSatisfied=*/nullptr)) return true; // Find the class template specialization declaration that // corresponds to these arguments. void *InsertPos = nullptr; ClassTemplateSpecializationDecl *PrevDecl = - ClassTemplate->findSpecialization(CanonicalConverted, InsertPos); + ClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos); TemplateSpecializationKind PrevDecl_TSK = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared; @@ -9894,7 +9870,7 @@ DeclResult Sema::ActOnExplicitInstantiation( // this explicit specialization. Specialization = ClassTemplateSpecializationDecl::Create( Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc, - ClassTemplate, CanonicalConverted, PrevDecl); + ClassTemplate, CTAI.CanonicalConverted, CTAI.StrictPackMatch, PrevDecl); SetNestedNameSpecifier(*this, Specialization, SS); // A MSInheritanceAttr attached to the previous declaration must be @@ -9949,9 +9925,9 @@ DeclResult Sema::ActOnExplicitInstantiation( = cast_or_null( Specialization->getDefinition()); if (!Def) - InstantiateClassTemplateSpecialization( - TemplateNameLoc, Specialization, TSK, - /*Complain=*/true, PrimaryHasMatchedPackOnParmToNonPackOnArg); + InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK, + /*Complain=*/true, + CTAI.StrictPackMatch); else if (TSK == TSK_ExplicitInstantiationDefinition) { MarkVTableUsed(TemplateNameLoc, Specialization, true); Specialization->setPointOfInstantiation(Def->getPointOfInstantiation()); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 7882d7a755d34..eb70dd743c8be 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -53,6 +53,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SaveAndRestore.h" #include #include #include @@ -2541,10 +2542,9 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::NullPtr: - if (A.getKind() == TemplateArgument::NullPtr && - S.Context.hasSameType(P.getNullPtrType(), A.getNullPtrType())) + // 'nullptr' has only one possible value, so it always matches. + if (A.getKind() == TemplateArgument::NullPtr) return TemplateDeductionResult::Success; - Info.FirstArg = P; Info.SecondArg = A; return TemplateDeductionResult::NonDeducedMismatch; @@ -2559,6 +2559,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, return TemplateDeductionResult::NonDeducedMismatch; case TemplateArgument::StructuralValue: + // FIXME: structural equality will also compare types, + // but they should match iff they have the same value. if (A.getKind() == TemplateArgument::StructuralValue && A.structurallyEquals(P)) return TemplateDeductionResult::Success; @@ -2774,7 +2776,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, if (!FoldPackParameter) return TemplateDeductionResult::MiscellaneousDeductionFailure; if (FoldPackArgument) - Info.setMatchedPackOnParmToNonPackOnArg(); + Info.setStrictPackMatch(); } // Deduce template arguments from the pattern. if (auto Result = DeduceTemplateArguments( @@ -2956,11 +2958,11 @@ Sema::getIdentityTemplateArgumentLoc(NamedDecl *TemplateParm, /// Convert the given deduced template argument and add it to the set of /// fully-converted template arguments. -static bool ConvertDeducedTemplateArgument( - Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template, - TemplateDeductionInfo &Info, bool IsDeduced, bool PartialOrdering, - SmallVectorImpl &SugaredOutput, - SmallVectorImpl &CanonicalOutput) { +static bool +ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, + DeducedTemplateArgument Arg, NamedDecl *Template, + TemplateDeductionInfo &Info, bool IsDeduced, + Sema::CheckTemplateArgumentInfo &CTAI) { auto ConvertArg = [&](DeducedTemplateArgument Arg, unsigned ArgumentPackIndex) { // Convert the deduced template argument into a template @@ -2969,19 +2971,18 @@ static bool ConvertDeducedTemplateArgument( TemplateArgumentLoc ArgLoc = S.getTrivialTemplateArgumentLoc( Arg, QualType(), Info.getLocation(), Param); - bool MatchedPackOnParmToNonPackOnArg = false; + SaveAndRestore _1(CTAI.MatchingTTP, false); + SaveAndRestore _2(CTAI.StrictPackMatch, false); // Check the template argument, converting it as necessary. auto Res = S.CheckTemplateArgument( Param, ArgLoc, Template, Template->getLocation(), - Template->getSourceRange().getEnd(), ArgumentPackIndex, SugaredOutput, - CanonicalOutput, + Template->getSourceRange().getEnd(), ArgumentPackIndex, CTAI, IsDeduced ? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound : Sema::CTAK_Deduced) - : Sema::CTAK_Specified, - PartialOrdering, &MatchedPackOnParmToNonPackOnArg); - if (MatchedPackOnParmToNonPackOnArg) - Info.setMatchedPackOnParmToNonPackOnArg(); + : Sema::CTAK_Specified); + if (CTAI.StrictPackMatch) + Info.setStrictPackMatch(); return Res; }; @@ -3012,20 +3013,21 @@ static bool ConvertDeducedTemplateArgument( return true; // Move the converted template argument into our argument pack. - SugaredPackedArgsBuilder.push_back(SugaredOutput.pop_back_val()); - CanonicalPackedArgsBuilder.push_back(CanonicalOutput.pop_back_val()); + SugaredPackedArgsBuilder.push_back(CTAI.SugaredConverted.pop_back_val()); + CanonicalPackedArgsBuilder.push_back( + CTAI.CanonicalConverted.pop_back_val()); } // If the pack is empty, we still need to substitute into the parameter // itself, in case that substitution fails. if (SugaredPackedArgsBuilder.empty()) { LocalInstantiationScope Scope(S); - MultiLevelTemplateArgumentList Args(Template, SugaredOutput, + MultiLevelTemplateArgumentList Args(Template, CTAI.SugaredConverted, /*Final=*/true); if (auto *NTTP = dyn_cast(Param)) { Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, - NTTP, SugaredOutput, + NTTP, CTAI.SugaredConverted, Template->getSourceRange()); if (Inst.isInvalid() || S.SubstType(NTTP->getType(), Args, NTTP->getLocation(), @@ -3033,7 +3035,7 @@ static bool ConvertDeducedTemplateArgument( return true; } else if (auto *TTP = dyn_cast(Param)) { Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, - TTP, SugaredOutput, + TTP, CTAI.SugaredConverted, Template->getSourceRange()); if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args)) return true; @@ -3042,9 +3044,9 @@ static bool ConvertDeducedTemplateArgument( } // Create the resulting argument pack. - SugaredOutput.push_back( + CTAI.SugaredConverted.push_back( TemplateArgument::CreatePackCopy(S.Context, SugaredPackedArgsBuilder)); - CanonicalOutput.push_back(TemplateArgument::CreatePackCopy( + CTAI.CanonicalConverted.push_back(TemplateArgument::CreatePackCopy( S.Context, CanonicalPackedArgsBuilder)); return false; } @@ -3063,9 +3065,7 @@ template static TemplateDeductionResult ConvertDeducedTemplateArguments( Sema &S, TemplateDeclT *Template, bool IsDeduced, SmallVectorImpl &Deduced, - TemplateDeductionInfo &Info, - SmallVectorImpl &SugaredBuilder, - SmallVectorImpl &CanonicalBuilder, bool PartialOrdering, + TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI, LocalInstantiationScope *CurrentInstantiationScope, unsigned NumAlreadyConverted, bool *IsIncomplete) { TemplateParameterList *TemplateParams = Template->getTemplateParameters(); @@ -3100,8 +3100,8 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments( // We have already fully type-checked and converted this // argument, because it was explicitly-specified. Just record the // presence of this argument. - SugaredBuilder.push_back(Deduced[I]); - CanonicalBuilder.push_back( + CTAI.SugaredConverted.push_back(Deduced[I]); + CTAI.CanonicalConverted.push_back( S.Context.getCanonicalTemplateArgument(Deduced[I])); continue; } @@ -3110,13 +3110,13 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments( // We may have deduced this argument, so it still needs to be // checked and converted. if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Template, Info, - IsDeduced, PartialOrdering, - SugaredBuilder, CanonicalBuilder)) { + IsDeduced, CTAI)) { Info.Param = makeTemplateParameter(Param); // FIXME: These template arguments are temporary. Free them! Info.reset( - TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder), - TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder)); + TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted), + TemplateArgumentList::CreateCopy(S.Context, + CTAI.CanonicalConverted)); return TemplateDeductionResult::SubstitutionFailure; } @@ -3130,8 +3130,8 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments( // arguments. if (IsIncomplete) { *IsIncomplete = true; - SugaredBuilder.push_back({}); - CanonicalBuilder.push_back({}); + CTAI.SugaredConverted.push_back({}); + CTAI.CanonicalConverted.push_back({}); continue; } @@ -3160,31 +3160,34 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments( DefArg = S.SubstDefaultTemplateArgumentIfAvailable( TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, - SugaredBuilder, CanonicalBuilder, HasDefaultArg); + CTAI.SugaredConverted, CTAI.CanonicalConverted, HasDefaultArg); } // If there was no default argument, deduction is incomplete. if (DefArg.getArgument().isNull()) { Info.Param = makeTemplateParameter( const_cast(TemplateParams->getParam(I))); - Info.reset(TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder), - TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder)); + Info.reset( + TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted), + TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted)); return HasDefaultArg ? TemplateDeductionResult::SubstitutionFailure : TemplateDeductionResult::Incomplete; } + SaveAndRestore _1(CTAI.PartialOrdering, false); + SaveAndRestore _2(CTAI.MatchingTTP, false); + SaveAndRestore _3(CTAI.StrictPackMatch, false); // Check whether we can actually use the default argument. if (S.CheckTemplateArgument( Param, DefArg, TD, TD->getLocation(), TD->getSourceRange().getEnd(), - /*ArgumentPackIndex=*/0, SugaredBuilder, CanonicalBuilder, - Sema::CTAK_Specified, /*PartialOrdering=*/false, - /*MatchedPackOnParmToNonPackOnArg=*/nullptr)) { + /*ArgumentPackIndex=*/0, CTAI, Sema::CTAK_Specified)) { Info.Param = makeTemplateParameter( const_cast(TemplateParams->getParam(I))); // FIXME: These template arguments are temporary. Free them! - Info.reset(TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder), - TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder)); + Info.reset( + TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted), + TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted)); return TemplateDeductionResult::SubstitutionFailure; } @@ -3284,10 +3287,9 @@ FinishTemplateArgumentDeduction( // C++ [temp.deduct.type]p2: // [...] or if any template argument remains neither deduced nor // explicitly specified, template argument deduction fails. - SmallVector SugaredBuilder, CanonicalBuilder; + Sema::CheckTemplateArgumentInfo CTAI(IsPartialOrdering); if (auto Result = ConvertDeducedTemplateArguments( - S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder, - CanonicalBuilder, IsPartialOrdering, + S, Partial, IsPartialOrdering, Deduced, Info, CTAI, /*CurrentInstantiationScope=*/nullptr, /*NumAlreadyConverted=*/0, /*IsIncomplete=*/nullptr); Result != TemplateDeductionResult::Success) @@ -3295,9 +3297,9 @@ FinishTemplateArgumentDeduction( // Form the template argument list from the deduced template arguments. TemplateArgumentList *SugaredDeducedArgumentList = - TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder); + TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted); TemplateArgumentList *CanonicalDeducedArgumentList = - TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder); + TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted); Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList); @@ -3314,11 +3316,11 @@ FinishTemplateArgumentDeduction( TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc, PartialTemplArgInfo->RAngleLoc); - if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(), - MultiLevelTemplateArgumentList(Partial, - SugaredBuilder, - /*Final=*/true), - InstArgs)) { + if (S.SubstTemplateArguments( + PartialTemplArgInfo->arguments(), + MultiLevelTemplateArgumentList(Partial, CTAI.SugaredConverted, + /*Final=*/true), + InstArgs)) { unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx; if (ParamIdx >= Partial->getTemplateParameters()->size()) ParamIdx = Partial->getTemplateParameters()->size() - 1; @@ -3330,24 +3332,19 @@ FinishTemplateArgumentDeduction( return TemplateDeductionResult::SubstitutionFailure; } - bool MatchedPackOnParmToNonPackOnArg = false; bool ConstraintsNotSatisfied; - SmallVector SugaredConvertedInstArgs, - CanonicalConvertedInstArgs; - if (S.CheckTemplateArgumentList( - Template, Partial->getLocation(), InstArgs, /*DefaultArgs=*/{}, false, - SugaredConvertedInstArgs, CanonicalConvertedInstArgs, - /*UpdateArgsWithConversions=*/true, &ConstraintsNotSatisfied, - /*PartialOrderingTTP=*/false, &MatchedPackOnParmToNonPackOnArg)) + Sema::CheckTemplateArgumentInfo InstCTAI; + if (S.CheckTemplateArgumentList(Template, Partial->getLocation(), InstArgs, + /*DefaultArgs=*/{}, false, InstCTAI, + /*UpdateArgsWithConversions=*/true, + &ConstraintsNotSatisfied)) return ConstraintsNotSatisfied ? TemplateDeductionResult::ConstraintsNotSatisfied : TemplateDeductionResult::SubstitutionFailure; - if (MatchedPackOnParmToNonPackOnArg) - Info.setMatchedPackOnParmToNonPackOnArg(); TemplateParameterList *TemplateParams = Template->getTemplateParameters(); for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) { - TemplateArgument InstArg = SugaredConvertedInstArgs.data()[I]; + TemplateArgument InstArg = InstCTAI.SugaredConverted.data()[I]; if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg, IsPartialOrdering)) { Info.Param = makeTemplateParameter(TemplateParams->getParam(I)); @@ -3362,7 +3359,7 @@ FinishTemplateArgumentDeduction( if (!IsPartialOrdering) { if (auto Result = CheckDeducedArgumentConstraints( - S, Partial, SugaredBuilder, CanonicalBuilder, Info); + S, Partial, CTAI.SugaredConverted, CTAI.CanonicalConverted, Info); Result != TemplateDeductionResult::Success) return Result; } @@ -3387,10 +3384,9 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // C++ [temp.deduct.type]p2: // [...] or if any template argument remains neither deduced nor // explicitly specified, template argument deduction fails. - SmallVector SugaredBuilder, CanonicalBuilder; + Sema::CheckTemplateArgumentInfo CTAI(PartialOrdering); if (auto Result = ConvertDeducedTemplateArguments( - S, Template, /*IsDeduced=*/PartialOrdering, Deduced, Info, - SugaredBuilder, CanonicalBuilder, PartialOrdering, + S, Template, /*IsDeduced=*/PartialOrdering, Deduced, Info, CTAI, /*CurrentInstantiationScope=*/nullptr, /*NumAlreadyConverted=*/0U, /*IsIncomplete=*/nullptr); Result != TemplateDeductionResult::Success) @@ -3398,7 +3394,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // Check that we produced the correct argument list. SmallVector, 4> PsStack{TemplateArgs}, - AsStack{CanonicalBuilder}; + AsStack{CTAI.CanonicalConverted}; for (;;) { auto take = [](SmallVectorImpl> &Stack) -> std::tuple &, TemplateArgument> { @@ -3455,7 +3451,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( if (!PartialOrdering) { if (auto Result = CheckDeducedArgumentConstraints( - S, Template, SugaredBuilder, CanonicalBuilder, Info); + S, Template, CTAI.SugaredConverted, CTAI.CanonicalConverted, Info); Result != TemplateDeductionResult::Success) return Result; } @@ -3479,17 +3475,16 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // C++ [temp.deduct.type]p2: // [...] or if any template argument remains neither deduced nor // explicitly specified, template argument deduction fails. - SmallVector SugaredBuilder, CanonicalBuilder; + Sema::CheckTemplateArgumentInfo CTAI; if (auto Result = ConvertDeducedTemplateArguments( - S, TD, /*IsDeduced=*/false, Deduced, Info, SugaredBuilder, - CanonicalBuilder, /*PartialOrdering=*/false, + S, TD, /*IsDeduced=*/false, Deduced, Info, CTAI, /*CurrentInstantiationScope=*/nullptr, /*NumAlreadyConverted=*/0, /*IsIncomplete=*/nullptr); Result != TemplateDeductionResult::Success) return Result; - return ::CheckDeducedArgumentConstraints(S, TD, SugaredBuilder, - CanonicalBuilder, Info); + return ::CheckDeducedArgumentConstraints(S, TD, CTAI.SugaredConverted, + CTAI.CanonicalConverted, Info); } /// Perform template argument deduction to determine whether the given template @@ -3670,7 +3665,6 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( // declaration order of their corresponding template-parameters. The // template argument list shall not specify more template-arguments than // there are corresponding template-parameters. - SmallVector SugaredBuilder, CanonicalBuilder; // Enter a new template instantiation context where we check the // explicitly-specified template arguments against this function template, @@ -3682,12 +3676,13 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( if (Inst.isInvalid()) return TemplateDeductionResult::InstantiationDepth; + CheckTemplateArgumentInfo CTAI; if (CheckTemplateArgumentList(FunctionTemplate, SourceLocation(), - ExplicitTemplateArgs, /*DefaultArgs=*/{}, true, - SugaredBuilder, CanonicalBuilder, + ExplicitTemplateArgs, /*DefaultArgs=*/{}, + /*PartialTemplateArgs=*/true, CTAI, /*UpdateArgsWithConversions=*/false) || Trap.hasErrorOccurred()) { - unsigned Index = SugaredBuilder.size(); + unsigned Index = CTAI.SugaredConverted.size(); if (Index >= TemplateParams->size()) return TemplateDeductionResult::SubstitutionFailure; Info.Param = makeTemplateParameter(TemplateParams->getParam(Index)); @@ -3697,9 +3692,9 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( // Form the template argument list from the explicitly-specified // template arguments. TemplateArgumentList *SugaredExplicitArgumentList = - TemplateArgumentList::CreateCopy(Context, SugaredBuilder); + TemplateArgumentList::CreateCopy(Context, CTAI.SugaredConverted); TemplateArgumentList *CanonicalExplicitArgumentList = - TemplateArgumentList::CreateCopy(Context, CanonicalBuilder); + TemplateArgumentList::CreateCopy(Context, CTAI.CanonicalConverted); Info.setExplicitArgs(SugaredExplicitArgumentList, CanonicalExplicitArgumentList); @@ -3714,15 +3709,15 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments( // the explicit template arguments. They'll be used as part of deduction // for this template parameter pack. unsigned PartiallySubstitutedPackIndex = -1u; - if (!SugaredBuilder.empty()) { - const TemplateArgument &Arg = SugaredBuilder.back(); + if (!CTAI.SugaredConverted.empty()) { + const TemplateArgument &Arg = CTAI.SugaredConverted.back(); if (Arg.getKind() == TemplateArgument::Pack) { - auto *Param = TemplateParams->getParam(SugaredBuilder.size() - 1); + auto *Param = TemplateParams->getParam(CTAI.SugaredConverted.size() - 1); // If this is a fully-saturated fixed-size pack, it should be // fully-substituted, not partially-substituted. std::optional Expansions = getExpandedPackSize(Param); if (!Expansions || Arg.pack_size() < *Expansions) { - PartiallySubstitutedPackIndex = SugaredBuilder.size() - 1; + PartiallySubstitutedPackIndex = CTAI.SugaredConverted.size() - 1; CurrentInstantiationScope->SetPartiallySubstitutedPack( Param, Arg.pack_begin(), Arg.pack_size()); } @@ -4044,10 +4039,9 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( // [...] or if any template argument remains neither deduced nor // explicitly specified, template argument deduction fails. bool IsIncomplete = false; - SmallVector SugaredBuilder, CanonicalBuilder; + CheckTemplateArgumentInfo CTAI(PartialOrdering); if (auto Result = ConvertDeducedTemplateArguments( - *this, FunctionTemplate, /*IsDeduced=*/true, Deduced, Info, - SugaredBuilder, CanonicalBuilder, PartialOrdering, + *this, FunctionTemplate, /*IsDeduced=*/true, Deduced, Info, CTAI, CurrentInstantiationScope, NumExplicitlySpecified, PartialOverloading ? &IsIncomplete : nullptr); Result != TemplateDeductionResult::Success) @@ -4067,9 +4061,9 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( // Form the template argument list from the deduced template arguments. TemplateArgumentList *SugaredDeducedArgumentList = - TemplateArgumentList::CreateCopy(Context, SugaredBuilder); + TemplateArgumentList::CreateCopy(Context, CTAI.SugaredConverted); TemplateArgumentList *CanonicalDeducedArgumentList = - TemplateArgumentList::CreateCopy(Context, CanonicalBuilder); + TemplateArgumentList::CreateCopy(Context, CTAI.CanonicalConverted); Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList); // Substitute the deduced template arguments into the function template @@ -4078,22 +4072,7 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( if (FunctionTemplate->getFriendObjectKind()) Owner = FunctionTemplate->getLexicalDeclContext(); FunctionDecl *FD = FunctionTemplate->getTemplatedDecl(); - // additional check for inline friend, - // ``` - // template int foo(F1 X); - // template struct A { - // template friend int foo(F1 X) { return A1; } - // }; - // template struct A<1>; - // int a = foo(1.0); - // ``` - const FunctionDecl *FDFriend; - if (FD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None && - FD->isDefined(FDFriend, /*CheckForPendingFriendDefinition*/ true) && - FDFriend->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None) { - FD = const_cast(FDFriend); - Owner = FD->getLexicalDeclContext(); - } + MultiLevelTemplateArgumentList SubstArgs( FunctionTemplate, CanonicalDeducedArgumentList->asArray(), /*Final=*/false); @@ -4130,13 +4109,13 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( // deduction fails. if (!IsIncomplete) { if (CheckInstantiatedFunctionTemplateConstraints( - Info.getLocation(), Specialization, CanonicalBuilder, + Info.getLocation(), Specialization, CTAI.CanonicalConverted, Info.AssociatedConstraintsSatisfaction)) return TemplateDeductionResult::MiscellaneousDeductionFailure; if (!Info.AssociatedConstraintsSatisfaction.IsSatisfied) { - Info.reset(Info.takeSugared(), - TemplateArgumentList::CreateCopy(Context, CanonicalBuilder)); + Info.reset(Info.takeSugared(), TemplateArgumentList::CreateCopy( + Context, CTAI.CanonicalConverted)); return TemplateDeductionResult::ConstraintsNotSatisfied; } } @@ -5219,12 +5198,12 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, for (unsigned I = 0, C = TypeLoc.getNumArgs(); I != C; ++I) TemplateArgs.addArgument(TypeLoc.getArgLoc(I)); - llvm::SmallVector SugaredConverted, CanonicalConverted; - if (S.CheckTemplateArgumentList( - Concept, SourceLocation(), TemplateArgs, /*DefaultArgs=*/{}, - /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted)) + Sema::CheckTemplateArgumentInfo CTAI; + if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs, + /*DefaultArgs=*/{}, + /*PartialTemplateArgs=*/false, CTAI)) return true; - MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted, + MultiLevelTemplateArgumentList MLTAL(Concept, CTAI.CanonicalConverted, /*Final=*/false); // Build up an EvaluationContext with an ImplicitConceptSpecializationDecl so // that the template arguments of the constraint can be preserved. For @@ -5239,7 +5218,7 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, S, Sema::ExpressionEvaluationContext::Unevaluated, ImplicitConceptSpecializationDecl::Create( S.getASTContext(), Concept->getDeclContext(), Concept->getLocation(), - CanonicalConverted)); + CTAI.CanonicalConverted)); if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, MLTAL, TypeLoc.getLocalSourceRange(), Satisfaction)) @@ -5669,10 +5648,9 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // [...] or if any template argument remains neither deduced nor // explicitly specified, template argument deduction fails. bool IsIncomplete = false; - SmallVector SugaredBuilder, CanonicalBuilder; + Sema::CheckTemplateArgumentInfo CTAI(/*PartialOrdering=*/true); if (auto Result = ConvertDeducedTemplateArguments( - S, FTD, /*IsDeduced=*/true, Deduced, Info, SugaredBuilder, - CanonicalBuilder, /*PartialOrdering=*/true, + S, FTD, /*IsDeduced=*/true, Deduced, Info, CTAI, /*CurrentInstantiationScope=*/nullptr, /*NumAlreadyConverted=*/0, &IsIncomplete); Result != TemplateDeductionResult::Success) @@ -5680,9 +5658,9 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // Form the template argument list from the deduced template arguments. TemplateArgumentList *SugaredDeducedArgumentList = - TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder); + TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted); TemplateArgumentList *CanonicalDeducedArgumentList = - TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder); + TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted); Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList); @@ -5691,7 +5669,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // and equivalent to the parameter. LocalInstantiationScope InstScope(S); - if (auto TDR = CheckDeductionConsistency(S, FTD, SugaredBuilder); + if (auto TDR = CheckDeductionConsistency(S, FTD, CTAI.SugaredConverted); TDR != TemplateDeductionResult::Success) return TDR; @@ -6519,7 +6497,7 @@ bool Sema::isMoreSpecializedThanPrimary( bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( TemplateParameterList *P, TemplateDecl *PArg, TemplateDecl *AArg, const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, - bool PartialOrdering, bool *MatchedPackOnParmToNonPackOnArg) { + bool PartialOrdering, bool *StrictPackMatch) { // C++1z [temp.arg.template]p4: (DR 150) // A template template-parameter P is at least as specialized as a // template template-argument A if, given the following rewrite to two @@ -6568,13 +6546,17 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( // C++1z [temp.arg.template]p3: // If the rewrite produces an invalid type, then P is not at least as // specialized as A. - SmallVector CanonicalPArgs; - if (CheckTemplateArgumentList( - AArg, ArgLoc, PArgList, DefaultArgs, false, PArgs, CanonicalPArgs, - /*UpdateArgsWithConversions=*/true, - /*ConstraintsNotSatisfied=*/nullptr, - /*PartialOrderingTTP=*/true, MatchedPackOnParmToNonPackOnArg)) + CheckTemplateArgumentInfo CTAI( + /*PartialOrdering=*/false, /*MatchingTTP=*/true); + CTAI.SugaredConverted = std::move(PArgs); + if (CheckTemplateArgumentList(AArg, ArgLoc, PArgList, DefaultArgs, + /*PartialTemplateArgs=*/false, CTAI, + /*UpdateArgsWithConversions=*/true, + /*ConstraintsNotSatisfied=*/nullptr)) return false; + PArgs = std::move(CTAI.SugaredConverted); + if (StrictPackMatch) + *StrictPackMatch |= CTAI.StrictPackMatch; } // Determine whether P1 is at least as specialized as P2. @@ -6599,9 +6581,8 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( PartialOrdering ? PackFold::ArgumentToParameter : PackFold::Both, /*HasDeducedAnyParam=*/nullptr)) { case clang::TemplateDeductionResult::Success: - if (MatchedPackOnParmToNonPackOnArg && - Info.hasMatchedPackOnParmToNonPackOnArg()) - *MatchedPackOnParmToNonPackOnArg = true; + if (StrictPackMatch && Info.hasStrictPackMatch()) + *StrictPackMatch = true; break; case TemplateDeductionResult::MiscellaneousDeductionFailure: diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp index 950783303efb3..e5931f4684a57 100644 --- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp +++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp @@ -740,6 +740,28 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) { return false; } +// Returns all source deduction guides associated with the declared +// deduction guides that have the specified deduction guide name. +llvm::DenseSet getSourceDeductionGuides(DeclarationName Name, + DeclContext *DC) { + assert(Name.getNameKind() == + DeclarationName::NameKind::CXXDeductionGuideName && + "name must be a deduction guide name"); + llvm::DenseSet Result; + for (auto *D : DC->lookup(Name)) { + if (const auto *FTD = dyn_cast(D)) + D = FTD->getTemplatedDecl(); + + if (const auto *GD = dyn_cast(D)) { + assert(GD->getSourceDeductionGuide() && + "deduction guide for alias template must have a source deduction " + "guide"); + Result.insert(GD->getSourceDeductionGuide()); + } + } + return Result; +} + // Build the associated constraints for the alias deduction guides. // C++ [over.match.class.deduct]p3.3: // The associated constraints ([temp.constr.decl]) are the conjunction of the @@ -1175,8 +1197,12 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef, GG->getTypeSourceInfo(), AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(), AliasTemplate->getEndLoc(), F->isImplicit())); - cast(Result->getTemplatedDecl()) - ->setDeductionCandidateKind(GG->getDeductionCandidateKind()); + auto *DGuide = cast(Result->getTemplatedDecl()); + DGuide->setDeductionCandidateKind(GG->getDeductionCandidateKind()); + DGuide->setSourceDeductionGuide( + cast(F->getTemplatedDecl())); + DGuide->setSourceDeductionGuideKind( + CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias); return Result; } return nullptr; @@ -1187,17 +1213,14 @@ void DeclareImplicitDeductionGuidesForTypeAlias( if (AliasTemplate->isInvalidDecl()) return; auto &Context = SemaRef.Context; - // FIXME: if there is an explicit deduction guide after the first use of the - // type alias usage, we will not cover this explicit deduction guide. fix this - // case. - if (hasDeclaredDeductionGuides( - Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), - AliasTemplate->getDeclContext())) - return; auto [Template, AliasRhsTemplateArgs] = getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate); if (!Template) return; + auto SourceDeductionGuides = getSourceDeductionGuides( + Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate), + AliasTemplate->getDeclContext()); + DeclarationNameInfo NameInfo( Context.DeclarationNames.getCXXDeductionGuideName(Template), Loc); LookupResult Guides(SemaRef, NameInfo, clang::Sema::LookupOrdinaryName); @@ -1206,6 +1229,8 @@ void DeclareImplicitDeductionGuidesForTypeAlias( for (auto *G : Guides) { if (auto *DG = dyn_cast(G)) { + if (SourceDeductionGuides.contains(DG)) + continue; // The deduction guide is a non-template function decl, we just clone it. auto *FunctionType = SemaRef.Context.getTrivialTypeSourceInfo(DG->getType()); @@ -1223,11 +1248,14 @@ void DeclareImplicitDeductionGuidesForTypeAlias( NewParam->setScopeInfo(0, I); FPTL.setParam(I, NewParam); } - auto *Transformed = cast(buildDeductionGuide( + auto *Transformed = cast(buildDeductionGuide( SemaRef, AliasTemplate, /*TemplateParams=*/nullptr, /*Constructor=*/nullptr, DG->getExplicitSpecifier(), FunctionType, AliasTemplate->getBeginLoc(), AliasTemplate->getLocation(), AliasTemplate->getEndLoc(), DG->isImplicit())); + Transformed->setSourceDeductionGuide(DG); + Transformed->setSourceDeductionGuideKind( + CXXDeductionGuideDecl::SourceDeductionGuideKind::Alias); // FIXME: Here the synthesized deduction guide is not a templated // function. Per [dcl.decl]p4, the requires-clause shall be present only @@ -1242,9 +1270,10 @@ void DeclareImplicitDeductionGuidesForTypeAlias( Constraint = Conjunction.getAs(); } Transformed->setTrailingRequiresClause(Constraint); + continue; } FunctionTemplateDecl *F = dyn_cast(G); - if (!F) + if (!F || SourceDeductionGuides.contains(F->getTemplatedDecl())) continue; // The **aggregate** deduction guides are handled in a different code path // (DeclareAggregateDeductionGuideFromInitList), which involves the tricky diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 3dc5696bd3821..d9a47ca3daa20 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -190,7 +190,7 @@ HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec, llvm::PointerUnion Specialized = VarTemplSpec->getSpecializedTemplateOrPartial(); if (VarTemplatePartialSpecializationDecl *Partial = - Specialized.dyn_cast()) { + dyn_cast(Specialized)) { if (!SkipForSpecialization) Result.addOuterTemplateArguments( Partial, VarTemplSpec->getTemplateInstantiationArgs().asArray(), @@ -479,9 +479,6 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs( using namespace TemplateInstArgsHelpers; const Decl *CurDecl = ND; - if (!CurDecl) - CurDecl = Decl::castFromDeclContext(DC); - if (Innermost) { Result.addOuterTemplateArguments(const_cast(ND), *Innermost, Final); @@ -495,8 +492,10 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs( // has a depth of 0. if (const auto *TTP = dyn_cast(CurDecl)) HandleDefaultTempArgIntoTempTempParam(TTP, Result); - CurDecl = Response::UseNextDecl(CurDecl).NextDecl; - } + CurDecl = DC ? Decl::castFromDeclContext(DC) + : Response::UseNextDecl(CurDecl).NextDecl; + } else if (!CurDecl) + CurDecl = Decl::castFromDeclContext(DC); while (!CurDecl->isFileContextDecl()) { Response R; @@ -1584,6 +1583,10 @@ namespace { /// pack. ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E); + // Transform a ResolvedUnexpandedPackExpr + ExprResult + TransformResolvedUnexpandedPackExpr(ResolvedUnexpandedPackExpr *E); + QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL) { // Call the base version; it will forward to our overridden version below. @@ -1762,23 +1765,6 @@ namespace { return inherited::TransformLambdaBody(E, Body); } - ExprResult TransformSizeOfPackExpr(SizeOfPackExpr *E) { - ExprResult Transformed = inherited::TransformSizeOfPackExpr(E); - if (!Transformed.isUsable()) - return Transformed; - auto *TransformedExpr = cast(Transformed.get()); - if (SemaRef.CodeSynthesisContexts.back().Kind == - Sema::CodeSynthesisContext::ConstraintNormalization && - TransformedExpr->getPack() == E->getPack()) { - Decl *NewPack = - TransformDecl(E->getPackLoc(), TransformedExpr->getPack()); - if (!NewPack) - return ExprError(); - TransformedExpr->setPack(cast(NewPack)); - } - return TransformedExpr; - } - ExprResult TransformRequiresExpr(RequiresExpr *E) { LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true); ExprResult TransReq = inherited::TransformRequiresExpr(E); @@ -1866,7 +1852,8 @@ bool TemplateInstantiator::AlreadyTransformed(QualType T) { if (T.isNull()) return true; - if (T->isInstantiationDependentType() || T->isVariablyModifiedType()) + if (T->isInstantiationDependentType() || T->isVariablyModifiedType() || + T->containsUnexpandedParameterPack()) return false; getSema().MarkDeclarationsReferencedInType(Loc, T); @@ -1902,15 +1889,6 @@ Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) { TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition()); if (TTP->isParameterPack()) { - // We might not have an index for pack expansion when normalizing - // constraint expressions. In that case, resort to instantiation scopes - // for the transformed declarations. - if (SemaRef.ArgumentPackSubstitutionIndex == -1 && - SemaRef.CodeSynthesisContexts.back().Kind == - Sema::CodeSynthesisContext::ConstraintNormalization) { - return SemaRef.FindInstantiatedDecl(Loc, cast(D), - TemplateArgs); - } assert(Arg.getKind() == TemplateArgument::Pack && "Missing argument pack"); Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); @@ -2399,9 +2377,10 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr( // The call to CheckTemplateArgument here produces the ImpCast. TemplateArgument SugaredConverted, CanonicalConverted; if (SemaRef - .CheckTemplateArgument(E->getParameter(), SubstType, - SubstReplacement.get(), SugaredConverted, - CanonicalConverted, Sema::CTAK_Specified) + .CheckTemplateArgument( + E->getParameter(), SubstType, SubstReplacement.get(), + SugaredConverted, CanonicalConverted, + /*PartialOrderingTTP=*/false, Sema::CTAK_Specified) .isInvalid()) return true; return transformNonTypeTemplateParmRef(E->getAssociatedDecl(), @@ -2458,7 +2437,7 @@ TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E, assert(Found && "no instantiation for parameter pack"); Decl *TransformedDecl; - if (DeclArgumentPack *Pack = Found->dyn_cast()) { + if (DeclArgumentPack *Pack = dyn_cast(*Found)) { // If this is a reference to a function parameter pack which we can // substitute but can't yet expand, build a FunctionParmPackExpr for it. if (getSema().ArgumentPackSubstitutionIndex == -1) { @@ -2499,6 +2478,15 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) { if (PD->isParameterPack()) return TransformFunctionParmPackRefExpr(E, PD); + if (BindingDecl *BD = dyn_cast(D); BD && BD->isParameterPack()) { + BD = cast_or_null(TransformDecl(BD->getLocation(), BD)); + if (!BD) + return ExprError(); + if (auto *RP = + dyn_cast_if_present(BD->getBinding())) + return TransformResolvedUnexpandedPackExpr(RP); + } + return inherited::TransformDeclRefExpr(E); } @@ -2663,6 +2651,19 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, return Result; } +ExprResult TemplateInstantiator::TransformResolvedUnexpandedPackExpr( + ResolvedUnexpandedPackExpr *E) { + if (getSema().ArgumentPackSubstitutionIndex != -1) { + assert(static_cast(getSema().ArgumentPackSubstitutionIndex) < + E->getNumExprs() && + "ArgumentPackSubstitutionIndex is out of range"); + return TransformExpr( + E->getExpansion(getSema().ArgumentPackSubstitutionIndex)); + } + + return inherited::TransformResolvedUnexpandedPackExpr(E); +} + QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType( TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool SuppressObjCLifetime) { @@ -4057,8 +4058,7 @@ bool Sema::usesPartialOrExplicitSpecialization( static ActionResult getPatternForClassTemplateSpecialization( Sema &S, SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, - bool PrimaryHasMatchedPackOnParmToNonPackOnArg) { + TemplateSpecializationKind TSK, bool PrimaryStrictPackMatch) { Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec); if (Inst.isInvalid()) return {/*Invalid=*/true}; @@ -4111,12 +4111,11 @@ static ActionResult getPatternForClassTemplateSpecialization( MakeDeductionFailureInfo(S.Context, Result, Info)); (void)Result; } else { - auto &List = - Info.hasMatchedPackOnParmToNonPackOnArg() ? ExtraMatched : Matched; + auto &List = Info.hasStrictPackMatch() ? ExtraMatched : Matched; List.push_back(MatchResult{Partial, Info.takeCanonical()}); } } - if (Matched.empty() && PrimaryHasMatchedPackOnParmToNonPackOnArg) + if (Matched.empty() && PrimaryStrictPackMatch) Matched = std::move(ExtraMatched); // If we're dealing with a member template where the template parameters @@ -4221,7 +4220,7 @@ bool Sema::InstantiateClassTemplateSpecialization( SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, TemplateSpecializationKind TSK, bool Complain, - bool PrimaryHasMatchedPackOnParmToNonPackOnArg) { + bool PrimaryStrictPackMatch) { // Perform the actual instantiation on the canonical declaration. ClassTemplateSpec = cast( ClassTemplateSpec->getCanonicalDecl()); @@ -4229,9 +4228,9 @@ bool Sema::InstantiateClassTemplateSpecialization( return true; ActionResult Pattern = - getPatternForClassTemplateSpecialization( - *this, PointOfInstantiation, ClassTemplateSpec, TSK, - PrimaryHasMatchedPackOnParmToNonPackOnArg); + getPatternForClassTemplateSpecialization(*this, PointOfInstantiation, + ClassTemplateSpec, TSK, + PrimaryStrictPackMatch); if (!Pattern.isUsable()) return Pattern.isInvalid(); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 6a2331e59477a..1f42f9500959e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -12,6 +12,7 @@ #include "TreeTransform.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DependentDiagnostic.h" @@ -284,7 +285,8 @@ static void instantiateDependentDiagnoseIfAttr( if (Cond) New->addAttr(new (S.getASTContext()) DiagnoseIfAttr( S.getASTContext(), *DIA, Cond, DIA->getMessage(), - DIA->getDiagnosticType(), DIA->getArgDependent(), New)); + DIA->getDefaultSeverity(), DIA->getWarningGroup(), + DIA->getArgDependent(), New)); } // Constructs and adds to New a new instance of CUDALaunchBoundsAttr using @@ -1166,26 +1168,57 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { Decl *TemplateDeclInstantiator::VisitBindingDecl(BindingDecl *D) { auto *NewBD = BindingDecl::Create(SemaRef.Context, Owner, D->getLocation(), - D->getIdentifier()); + D->getIdentifier(), D->getType()); NewBD->setReferenced(D->isReferenced()); SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewBD); + return NewBD; } Decl *TemplateDeclInstantiator::VisitDecompositionDecl(DecompositionDecl *D) { // Transform the bindings first. + // The transformed DD will have all of the concrete BindingDecls. SmallVector NewBindings; - for (auto *OldBD : D->bindings()) + ResolvedUnexpandedPackExpr *OldResolvedPack = nullptr; + for (auto *OldBD : D->bindings()) { + Expr *BindingExpr = OldBD->getBinding(); + if (auto *RP = + dyn_cast_if_present(BindingExpr)) { + assert(!OldResolvedPack && "no more than one pack is allowed"); + OldResolvedPack = RP; + } NewBindings.push_back(cast(VisitBindingDecl(OldBD))); + } ArrayRef NewBindingArray = NewBindings; - auto *NewDD = cast_or_null( + auto *NewDD = cast_if_present( VisitVarDecl(D, /*InstantiatingVarTemplate=*/false, &NewBindingArray)); if (!NewDD || NewDD->isInvalidDecl()) for (auto *NewBD : NewBindings) NewBD->setInvalidDecl(); + if (OldResolvedPack) { + // Mark the holding vars (if any) in the pack as instantiated since + // they are created implicitly. + auto Bindings = NewDD->bindings(); + auto BPack = llvm::find_if( + Bindings, [](BindingDecl *D) -> bool { return D->isParameterPack(); }); + auto *NewResolvedPack = + cast((*BPack)->getBinding()); + auto OldExprs = OldResolvedPack->getExprs(); + auto NewExprs = NewResolvedPack->getExprs(); + assert(OldExprs.size() == NewExprs.size()); + for (unsigned I = 0; I < OldResolvedPack->getNumExprs(); I++) { + DeclRefExpr *OldDRE = cast(OldExprs[I]); + BindingDecl *OldNestedBD = cast(OldDRE->getDecl()); + DeclRefExpr *NewDRE = cast(NewExprs[I]); + BindingDecl *NewNestedBD = cast(NewDRE->getDecl()); + SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldNestedBD, + NewNestedBD); + } + } + return NewDD; } @@ -1627,12 +1660,17 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { // specialization causes the implicit instantiation of the declarations, but // not the definitions of scoped member enumerations. // - // DR1484 clarifies that enumeration definitions inside of a template + // DR1484 clarifies that enumeration definitions inside a template // declaration aren't considered entities that can be separately instantiated - // from the rest of the entity they are declared inside of. + // from the rest of the entity they are declared inside. if (isDeclWithinFunction(D) ? D == Def : Def && !Enum->isScoped()) { - SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum); - InstantiateEnumDefinition(Enum, Def); + // Prevent redundant instantiation of the enumerator-definition if the + // definition has already been instantiated due to a prior + // opaque-enum-declaration. + if (PrevDecl == nullptr) { + SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum); + InstantiateEnumDefinition(Enum, Def); + } } return Enum; @@ -2264,7 +2302,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( SemaRef.Context, DC, D->getInnerLocStart(), InstantiatedExplicitSpecifier, NameInfo, T, TInfo, D->getSourceRange().getEnd(), DGuide->getCorrespondingConstructor(), - DGuide->getDeductionCandidateKind(), TrailingRequiresClause); + DGuide->getDeductionCandidateKind(), TrailingRequiresClause, + DGuide->getSourceDeductionGuide(), + DGuide->getSourceDeductionGuideKind()); Function->setAccess(D->getAccess()); } else { Function = FunctionDecl::Create( @@ -2606,8 +2646,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl( // conditionally populate the TSI without breaking non-template related use // cases. Populate TSIs prior to calling SubstFunctionType to make sure we get // a proper transformation. - if (cast(D->getParent())->isLambda() && - !D->getTypeSourceInfo() && + if (isLambdaMethod(D) && !D->getTypeSourceInfo() && isa(D)) { TypeSourceInfo *TSI = SemaRef.Context.getTrivialTypeSourceInfo(D->getType()); @@ -3950,10 +3989,10 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( // Check that the template argument list is well-formed for this // class template. - SmallVector SugaredConverted, CanonicalConverted; + Sema::CheckTemplateArgumentInfo CTAI; if (SemaRef.CheckTemplateArgumentList( InstClassTemplate, D->getLocation(), InstTemplateArgs, - /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted, + /*DefaultArgs=*/{}, /*PartialTemplateArgs=*/false, CTAI, /*UpdateArgsWithConversions=*/true)) return nullptr; @@ -3961,7 +4000,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( // in the member template's set of class template explicit specializations. void *InsertPos = nullptr; ClassTemplateSpecializationDecl *PrevDecl = - InstClassTemplate->findSpecialization(CanonicalConverted, InsertPos); + InstClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos); // Check whether we've already seen a conflicting instantiation of this // declaration (for instance, if there was a prior implicit instantiation). @@ -3999,7 +4038,8 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( ClassTemplateSpecializationDecl *InstD = ClassTemplateSpecializationDecl::Create( SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(), - D->getLocation(), InstClassTemplate, CanonicalConverted, PrevDecl); + D->getLocation(), InstClassTemplate, CTAI.CanonicalConverted, + CTAI.StrictPackMatch, PrevDecl); InstD->setTemplateArgsAsWritten(InstTemplateArgs); // Add this partial specialization to the set of class template partial @@ -4058,17 +4098,17 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( } // Check that the template argument list is well-formed for this template. - SmallVector SugaredConverted, CanonicalConverted; + Sema::CheckTemplateArgumentInfo CTAI; if (SemaRef.CheckTemplateArgumentList( InstVarTemplate, D->getLocation(), VarTemplateArgsInfo, - /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted, + /*DefaultArgs=*/{}, /*PartialTemplateArgs=*/false, CTAI, /*UpdateArgsWithConversions=*/true)) return nullptr; // Check whether we've already seen a declaration of this specialization. void *InsertPos = nullptr; VarTemplateSpecializationDecl *PrevDecl = - InstVarTemplate->findSpecialization(CanonicalConverted, InsertPos); + InstVarTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos); // Check whether we've already seen a conflicting instantiation of this // declaration (for instance, if there was a prior implicit instantiation). @@ -4079,8 +4119,9 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( PrevDecl->getPointOfInstantiation(), Ignored)) return nullptr; - return VisitVarTemplateSpecializationDecl( - InstVarTemplate, D, VarTemplateArgsInfo, CanonicalConverted, PrevDecl); + return VisitVarTemplateSpecializationDecl(InstVarTemplate, D, + VarTemplateArgsInfo, + CTAI.CanonicalConverted, PrevDecl); } Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( @@ -4324,37 +4365,37 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // Check that the template argument list is well-formed for this // class template. - SmallVector SugaredConverted, CanonicalConverted; + Sema::CheckTemplateArgumentInfo CTAI; if (SemaRef.CheckTemplateArgumentList( ClassTemplate, PartialSpec->getLocation(), InstTemplateArgs, /*DefaultArgs=*/{}, - /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted)) + /*PartialTemplateArgs=*/false, CTAI)) return nullptr; // Check these arguments are valid for a template partial specialization. if (SemaRef.CheckTemplatePartialSpecializationArgs( PartialSpec->getLocation(), ClassTemplate, InstTemplateArgs.size(), - CanonicalConverted)) + CTAI.CanonicalConverted)) return nullptr; // Figure out where to insert this class template partial specialization // in the member template's set of class template partial specializations. void *InsertPos = nullptr; ClassTemplateSpecializationDecl *PrevDecl = - ClassTemplate->findPartialSpecialization(CanonicalConverted, InstParams, - InsertPos); + ClassTemplate->findPartialSpecialization(CTAI.CanonicalConverted, + InstParams, InsertPos); // Build the canonical type that describes the converted template // arguments of the class template partial specialization. QualType CanonType = SemaRef.Context.getTemplateSpecializationType( - TemplateName(ClassTemplate), CanonicalConverted); + TemplateName(ClassTemplate), CTAI.CanonicalConverted); // Create the class template partial specialization declaration. ClassTemplatePartialSpecializationDecl *InstPartialSpec = ClassTemplatePartialSpecializationDecl::Create( SemaRef.Context, PartialSpec->getTagKind(), Owner, PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams, - ClassTemplate, CanonicalConverted, CanonType, + ClassTemplate, CTAI.CanonicalConverted, CanonType, /*PrevDecl=*/nullptr); InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs); @@ -4438,25 +4479,24 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( // Check that the template argument list is well-formed for this // class template. - SmallVector SugaredConverted, CanonicalConverted; + Sema::CheckTemplateArgumentInfo CTAI; if (SemaRef.CheckTemplateArgumentList(VarTemplate, PartialSpec->getLocation(), InstTemplateArgs, /*DefaultArgs=*/{}, - /*PartialTemplateArgs=*/false, - SugaredConverted, CanonicalConverted)) + /*PartialTemplateArgs=*/false, CTAI)) return nullptr; // Check these arguments are valid for a template partial specialization. if (SemaRef.CheckTemplatePartialSpecializationArgs( PartialSpec->getLocation(), VarTemplate, InstTemplateArgs.size(), - CanonicalConverted)) + CTAI.CanonicalConverted)) return nullptr; // Figure out where to insert this variable template partial specialization // in the member template's set of variable template partial specializations. void *InsertPos = nullptr; VarTemplateSpecializationDecl *PrevDecl = - VarTemplate->findPartialSpecialization(CanonicalConverted, InstParams, - InsertPos); + VarTemplate->findPartialSpecialization(CTAI.CanonicalConverted, + InstParams, InsertPos); // Do substitution on the type of the declaration TypeSourceInfo *DI = SemaRef.SubstType( @@ -4477,7 +4517,7 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( VarTemplatePartialSpecializationDecl::Create( SemaRef.Context, Owner, PartialSpec->getInnerLocStart(), PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(), - DI, PartialSpec->getStorageClass(), CanonicalConverted); + DI, PartialSpec->getStorageClass(), CTAI.CanonicalConverted); InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs); @@ -5237,9 +5277,31 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, RebuildTypeSourceInfoForDefaultSpecialMembers(); SetDeclDefaulted(Function, PatternDecl->getLocation()); } else { + NamedDecl *ND = Function; + DeclContext *DC = ND->getLexicalDeclContext(); + std::optional> Innermost; + if (auto *Primary = Function->getPrimaryTemplate(); + Primary && + !isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function) && + Function->getTemplateSpecializationKind() != + TSK_ExplicitSpecialization) { + auto It = llvm::find_if(Primary->redecls(), + [](const RedeclarableTemplateDecl *RTD) { + return cast(RTD) + ->isCompatibleWithDefinition(); + }); + assert(It != Primary->redecls().end() && + "Should't get here without a definition"); + if (FunctionDecl *Def = cast(*It) + ->getTemplatedDecl() + ->getDefinition()) + DC = Def->getLexicalDeclContext(); + else + DC = (*It)->getLexicalDeclContext(); + Innermost.emplace(Function->getTemplateSpecializationArgs()->asArray()); + } MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs( - Function, Function->getLexicalDeclContext(), /*Final=*/false, - /*Innermost=*/std::nullopt, false, PatternDecl); + Function, DC, /*Final=*/false, Innermost, false, PatternDecl); // Substitute into the qualifier; we can get a substitution failure here // through evil use of alias templates. @@ -6214,8 +6276,16 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, // declarations to their instantiations. if (CurrentInstantiationScope) { if (auto Found = CurrentInstantiationScope->findInstantiationOf(D)) { - if (Decl *FD = Found->dyn_cast()) + if (Decl *FD = Found->dyn_cast()) { + if (auto *BD = dyn_cast(FD); + BD && BD->isParameterPack() && + ArgumentPackSubstitutionIndex != -1) { + auto *DRE = cast( + BD->getBindingPackExprs()[ArgumentPackSubstitutionIndex]); + return cast(DRE->getDecl()); + } return cast(FD); + } int PackIdx = ArgumentPackSubstitutionIndex; assert(PackIdx != -1 && diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index c8452db6bc901..3c56794722dcc 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -50,17 +50,29 @@ class CollectUnexpandedParameterPacksVisitor auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr; if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit) return; - } else if (getDepthAndIndex(ND).first >= DepthLimit) + } else if (auto *BD = dyn_cast(ND)) { + Expr *E = BD->getBinding(); + if (auto *RP = cast_if_present(E)) { + addUnexpanded(RP); + return; + } + } else if (getDepthAndIndex(ND).first >= DepthLimit) { return; + } Unexpanded.push_back({ND, Loc}); } + void addUnexpanded(const TemplateTypeParmType *T, SourceLocation Loc = SourceLocation()) { if (T->getDepth() < DepthLimit) Unexpanded.push_back({T, Loc}); } + void addUnexpanded(ResolvedUnexpandedPackExpr *E) { + Unexpanded.push_back({E, E->getBeginLoc()}); + } + public: explicit CollectUnexpandedParameterPacksVisitor( SmallVectorImpl &Unexpanded) @@ -103,6 +115,12 @@ class CollectUnexpandedParameterPacksVisitor return true; } + bool + VisitResolvedUnexpandedPackExpr(ResolvedUnexpandedPackExpr *E) override { + addUnexpanded(E); + return true; + } + /// Record occurrences of template template parameter packs. bool TraverseTemplateName(TemplateName Template) override { if (auto *TTP = dyn_cast_or_null( @@ -422,8 +440,8 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc, if (const TemplateTypeParmType *TTP = Unexpanded[I].first.dyn_cast()) Name = TTP->getIdentifier(); - else - Name = cast(Unexpanded[I].first)->getIdentifier(); + else if (NamedDecl *ND = Unexpanded[I].first.dyn_cast()) + Name = ND->getIdentifier(); if (Name && NamesKnown.insert(Name).second) Names.push_back(Name); @@ -757,23 +775,39 @@ bool Sema::CheckParameterPacksForExpansion( bool HaveFirstPack = false; std::optional NumPartialExpansions; SourceLocation PartiallySubstitutedPackLoc; + typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; for (UnexpandedParameterPack ParmPack : Unexpanded) { // Compute the depth and index for this parameter pack. unsigned Depth = 0, Index = 0; IdentifierInfo *Name; bool IsVarDeclPack = false; + ResolvedUnexpandedPackExpr *ResolvedPack = nullptr; if (const TemplateTypeParmType *TTP = ParmPack.first.dyn_cast()) { Depth = TTP->getDepth(); Index = TTP->getIndex(); Name = TTP->getIdentifier(); + } else if (auto *RP = + ParmPack.first.dyn_cast()) { + ResolvedPack = RP; } else { NamedDecl *ND = cast(ParmPack.first); if (isa(ND)) IsVarDeclPack = true; - else + else if (isa(ND)) { + // Find the instantiated BindingDecl and check it for a resolved pack. + llvm::PointerUnion *Instantiation = + CurrentInstantiationScope->findInstantiationOf(ND); + Decl *B = cast(*Instantiation); + Expr *BindingExpr = cast(B)->getBinding(); + ResolvedPack = cast_if_present(BindingExpr); + if (!ResolvedPack) { + ShouldExpand = false; + continue; + } + } else std::tie(Depth, Index) = getDepthAndIndex(ND); Name = ND->getIdentifier(); @@ -783,8 +817,6 @@ bool Sema::CheckParameterPacksForExpansion( unsigned NewPackSize, PendingPackExpansionSize = 0; if (IsVarDeclPack) { // Figure out whether we're instantiating to an argument pack or not. - typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; - llvm::PointerUnion *Instantiation = CurrentInstantiationScope->findInstantiationOf( cast(ParmPack.first)); @@ -797,6 +829,8 @@ bool Sema::CheckParameterPacksForExpansion( ShouldExpand = false; continue; } + } else if (ResolvedPack) { + NewPackSize = ResolvedPack->getNumExprs(); } else { // If we don't have a template argument at this depth/index, then we // cannot expand the pack expansion. Make a note of this, but we still @@ -833,7 +867,7 @@ bool Sema::CheckParameterPacksForExpansion( // Template argument deduction can extend the sequence of template // arguments corresponding to a template parameter pack, even when the // sequence contains explicitly specified template arguments. - if (!IsVarDeclPack && CurrentInstantiationScope) { + if (!IsVarDeclPack && !ResolvedPack && CurrentInstantiationScope) { if (NamedDecl *PartialPack = CurrentInstantiationScope->getPartiallySubstitutedPack()) { unsigned PartialDepth, PartialIndex; @@ -939,6 +973,12 @@ std::optional Sema::getNumArgumentsInExpansionFromUnexpanded( Unexpanded[I].first.dyn_cast()) { Depth = TTP->getDepth(); Index = TTP->getIndex(); + } else if (auto *PE = Unexpanded[I] + .first.dyn_cast()) { + unsigned Size = PE->getNumExprs(); + assert((!Result || *Result == Size) && "inconsistent pack sizes"); + Result = Size; + continue; } else { NamedDecl *ND = cast(Unexpanded[I].first); if (isa(ND)) { @@ -1167,8 +1207,12 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, MarkAnyDeclReferenced(OpLoc, ParameterPack, true); + std::optional Length; + if (auto *RP = ResolvedUnexpandedPackExpr::getFromDecl(ParameterPack)) + Length = RP->getNumExprs(); + return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc, - RParenLoc); + RParenLoc, Length); } static bool isParameterPack(Expr *PackExpression) { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 2ccf5a8e1d6f3..6f30a36621601 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1826,7 +1826,8 @@ QualType Sema::BuildPointerType(QualType T, if (checkQualifiedFunction(*this, T, Loc, QFK_Pointer)) return QualType(); - assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType"); + if (T->isObjCObjectType()) + return Context.getObjCObjectPointerType(T); // In ARC, it is forbidden to build pointers to unqualified pointers. if (getLangOpts().ObjCAutoRefCount) @@ -5182,6 +5183,11 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, if (ParamTy.hasQualifiers()) S.Diag(DeclType.Loc, diag::err_void_param_qualified); + for (const auto *A : Param->attrs()) { + S.Diag(A->getLoc(), diag::warn_attribute_on_void_param) + << A << A->getRange(); + } + // Reject, but continue to parse 'float(this void)' as // 'float(void)'. if (Param->isExplicitObjectParameter()) { @@ -8306,7 +8312,8 @@ static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) { BTy->getKind() == BuiltinType::ULongLong || BTy->getKind() == BuiltinType::Float || BTy->getKind() == BuiltinType::Half || - BTy->getKind() == BuiltinType::BFloat16; + BTy->getKind() == BuiltinType::BFloat16 || + BTy->getKind() == BuiltinType::MFloat8; } static bool verifyValidIntegerConstantExpr(Sema &S, const ParsedAttr &Attr, @@ -8490,7 +8497,8 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType, return; } - auto VScale = S.Context.getTargetInfo().getVScaleRange(S.getLangOpts()); + auto VScale = + S.Context.getTargetInfo().getVScaleRange(S.getLangOpts(), false); if (!VScale || !VScale->first || VScale->first != VScale->second) { S.Diag(Attr.getLoc(), diag::err_attribute_riscv_rvv_bits_unsupported) << Attr; @@ -9396,7 +9404,7 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, runWithSufficientStackSpace(Loc, [&] { Diagnosed = InstantiateClassTemplateSpecialization( Loc, ClassTemplateSpec, TSK_ImplicitInstantiation, - /*Complain=*/Diagnoser); + /*Complain=*/Diagnoser, ClassTemplateSpec->hasStrictPackMatch()); }); Instantiated = true; } @@ -9806,8 +9814,7 @@ QualType Sema::BuiltinAddPointer(QualType BaseType, SourceLocation Loc) { } QualType Sema::BuiltinRemovePointer(QualType BaseType, SourceLocation Loc) { - // We don't want block pointers or ObjectiveC's id type. - if (!BaseType->isAnyPointerType() || BaseType->isObjCIdType()) + if (!BaseType->isAnyPointerType()) return BaseType; return BaseType->getPointeeType(); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 12680843a434a..813b172c4d89e 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -3680,6 +3680,13 @@ class TreeTransform { FullySubstituted); } + ExprResult RebuildResolvedUnexpandedPackExpr(SourceLocation BeginLoc, + QualType T, + ArrayRef Exprs) { + return ResolvedUnexpandedPackExpr::Create(SemaRef.Context, BeginLoc, T, + Exprs); + } + /// Build a new expression representing a call to a source location /// builtin. /// @@ -4204,6 +4211,17 @@ class TreeTransform { Exprs, RParenLoc, EndLoc, Clauses, {}); } + StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc, + SourceLocation DirLoc, + OpenACCAtomicKind AtKind, + SourceLocation EndLoc, + StmtResult AssociatedStmt) { + return getSema().OpenACC().ActOnEndStmtDirective( + OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{}, + SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, {}, + AssociatedStmt); + } + ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) { return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc); } @@ -7335,8 +7353,10 @@ QualType TreeTransform::TransformTemplateSpecializationType( NewTemplateArgs)) return QualType(); - // FIXME: maybe don't rebuild if all the template arguments are the same. - + // This needs to be rebuilt if either the arguments changed, or if the + // original template changed. If the template changed, and even if the + // arguments didn't change, these arguments might not correspond to their + // respective parameters, therefore needing conversions. QualType Result = getDerived().RebuildTemplateSpecializationType(Template, TL.getTemplateNameLoc(), @@ -10607,6 +10627,11 @@ OMPClause *TreeTransform::TransformOMPNoOpenMPRoutinesClause( return C; } template +OMPClause *TreeTransform::TransformOMPNoOpenMPConstructsClause( + OMPNoOpenMPConstructsClause *C) { + return C; +} +template OMPClause *TreeTransform::TransformOMPNoParallelismClause( OMPNoParallelismClause *C) { return C; @@ -12604,6 +12629,29 @@ TreeTransform::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) { QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses); } +template +StmtResult TreeTransform::TransformOpenACCAtomicConstruct( + OpenACCAtomicConstruct *C) { + getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc()); + + if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(), + C->getBeginLoc(), {})) + return StmtError(); + + // Transform Associated Stmt. + SemaOpenACC::AssociatedStmtRAII AssocStmtRAII( + getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {}); + + StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt()); + AssocStmt = getSema().OpenACC().ActOnAssociatedStmt( + C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {}, + AssocStmt); + + return getDerived().RebuildOpenACCAtomicConstruct( + C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(), + C->getEndLoc(), AssocStmt); +} + template ExprResult TreeTransform::TransformOpenACCAsteriskSizeExpr( OpenACCAsteriskSizeExpr *E) { @@ -14903,7 +14951,7 @@ TreeTransform::TransformExprRequirement(concepts::ExprRequirement *Req) TransRetReq.emplace(TPL); } assert(TransRetReq && "All code paths leading here must set TransRetReq"); - if (Expr *E = TransExpr.dyn_cast()) + if (Expr *E = dyn_cast(TransExpr)) return getDerived().RebuildExprRequirement(E, Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq)); @@ -14947,9 +14995,6 @@ TreeTransform::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { SubExpr = getDerived().TransformExpr(E->getDimensionExpression()); if (SubExpr.isInvalid()) return ExprError(); - - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression()) - return E; } return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T, @@ -15428,12 +15473,11 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { // The transform has determined that we should perform an expansion; // transform and capture each of the arguments. // expansion of the pattern. Do so. - auto *Pack = cast(C->getCapturedVar()); + auto *Pack = cast(C->getCapturedVar()); for (unsigned I = 0; I != *NumExpansions; ++I) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); - VarDecl *CapturedVar - = cast_or_null(getDerived().TransformDecl(C->getLocation(), - Pack)); + ValueDecl *CapturedVar = cast_if_present( + getDerived().TransformDecl(C->getLocation(), Pack)); if (!CapturedVar) { Invalid = true; continue; @@ -16128,6 +16172,24 @@ TreeTransform::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) { return E; } +template +ExprResult TreeTransform::TransformResolvedUnexpandedPackExpr( + ResolvedUnexpandedPackExpr *E) { + bool ArgumentChanged = false; + SmallVector NewExprs; + if (TransformExprs(E->getExprs().begin(), E->getNumExprs(), + /*IsCall=*/false, NewExprs, &ArgumentChanged)) + return ExprError(); + + if (!AlwaysRebuild() && !ArgumentChanged) + return E; + + // NOTE: The type is just a superficial PackExpansionType + // that needs no substitution. + return RebuildResolvedUnexpandedPackExpr(E->getBeginLoc(), E->getType(), + NewExprs); +} + template ExprResult TreeTransform::TransformMaterializeTemporaryExpr( diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 08801d22fdca8..3c64b67503195 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -645,10 +645,11 @@ collectMacroDefinitions(const PreprocessorOptions &PPOpts, // For an #undef'd macro, we only care about the name. if (IsUndef) { - if (MacroNames && !Macros.count(MacroName)) + auto [It, Inserted] = Macros.try_emplace(MacroName); + if (MacroNames && Inserted) MacroNames->push_back(MacroName); - Macros[MacroName] = std::make_pair("", true); + It->second = std::make_pair("", true); continue; } @@ -661,9 +662,10 @@ collectMacroDefinitions(const PreprocessorOptions &PPOpts, MacroBody = MacroBody.substr(0, End); } - if (MacroNames && !Macros.count(MacroName)) + auto [It, Inserted] = Macros.try_emplace(MacroName); + if (MacroNames && Inserted) MacroNames->push_back(MacroName); - Macros[MacroName] = std::make_pair(MacroBody, false); + It->second = std::make_pair(MacroBody, false); } } @@ -6864,7 +6866,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) { // command line (-w, -Weverything, -Werror, ...) along with any explicit // -Wblah flags. unsigned Flags = Record[Idx++]; - DiagState Initial; + DiagState Initial(*Diag.getDiagnosticIDs()); Initial.SuppressSystemWarnings = Flags & 1; Flags >>= 1; Initial.ErrorsAsFatal = Flags & 1; Flags >>= 1; Initial.WarningsAsErrors = Flags & 1; Flags >>= 1; @@ -10186,12 +10188,12 @@ void ASTReader::visitTopLevelModuleMaps( } void ASTReader::finishPendingActions() { - while ( - !PendingIdentifierInfos.empty() || !PendingDeducedFunctionTypes.empty() || - !PendingDeducedVarTypes.empty() || !PendingIncompleteDeclChains.empty() || - !PendingDeclChains.empty() || !PendingMacroIDs.empty() || - !PendingDeclContextInfos.empty() || !PendingUpdateRecords.empty() || - !PendingObjCExtensionIvarRedeclarations.empty()) { + while (!PendingIdentifierInfos.empty() || + !PendingDeducedFunctionTypes.empty() || + !PendingDeducedVarTypes.empty() || !PendingDeclChains.empty() || + !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() || + !PendingUpdateRecords.empty() || + !PendingObjCExtensionIvarRedeclarations.empty()) { // If any identifiers with corresponding top-level declarations have // been loaded, load those declarations now. using TopLevelDeclsMap = @@ -10239,13 +10241,6 @@ void ASTReader::finishPendingActions() { } PendingDeducedVarTypes.clear(); - // For each decl chain that we wanted to complete while deserializing, mark - // it as "still needs to be completed". - for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) { - markIncompleteDeclChain(PendingIncompleteDeclChains[I]); - } - PendingIncompleteDeclChains.clear(); - // Load pending declaration chains. for (unsigned I = 0; I != PendingDeclChains.size(); ++I) loadPendingDeclChain(PendingDeclChains[I].first, @@ -10483,6 +10478,12 @@ void ASTReader::finishPendingActions() { for (auto *ND : PendingMergedDefinitionsToDeduplicate) getContext().deduplicateMergedDefinitonsFor(ND); PendingMergedDefinitionsToDeduplicate.clear(); + + // For each decl chain that we wanted to complete while deserializing, mark + // it as "still needs to be completed". + for (Decl *D : PendingIncompleteDeclChains) + markIncompleteDeclChain(D); + PendingIncompleteDeclChains.clear(); } void ASTReader::diagnoseOdrViolations() { @@ -11060,6 +11061,9 @@ OMPClause *OMPClauseReader::readClause() { case llvm::omp::OMPC_no_openmp_routines: C = new (Context) OMPNoOpenMPRoutinesClause(); break; + case llvm::omp::OMPC_no_openmp_constructs: + C = new (Context) OMPNoOpenMPConstructsClause(); + break; case llvm::omp::OMPC_no_parallelism: C = new (Context) OMPNoParallelismClause(); break; @@ -11501,6 +11505,9 @@ void OMPClauseReader::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {} void OMPClauseReader::VisitOMPNoOpenMPRoutinesClause( OMPNoOpenMPRoutinesClause *) {} +void OMPClauseReader::VisitOMPNoOpenMPConstructsClause( + OMPNoOpenMPConstructsClause *) {} + void OMPClauseReader::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {} void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {} diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 0b75468a94103..17a41fff2267c 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1064,6 +1064,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setHasImplicitReturnZero(FunctionDeclBits.getNextBit()); FD->setIsMultiVersion(FunctionDeclBits.getNextBit()); FD->setLateTemplateParsed(FunctionDeclBits.getNextBit()); + FD->setInstantiatedFromMemberTemplate(FunctionDeclBits.getNextBit()); FD->setFriendConstraintRefersToEnclosingTemplate( FunctionDeclBits.getNextBit()); FD->setUsesSEHTry(FunctionDeclBits.getNextBit()); @@ -2295,6 +2296,10 @@ void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { VisitFunctionDecl(D); D->setDeductionCandidateKind( static_cast(Record.readInt())); + D->setSourceDeductionGuide(readDeclAs()); + D->setSourceDeductionGuideKind( + static_cast( + Record.readInt())); } void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { @@ -2528,6 +2533,7 @@ RedeclarableResult ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs); D->PointOfInstantiation = readSourceLocation(); D->SpecializationKind = (TemplateSpecializationKind)Record.readInt(); + D->StrictPackMatch = Record.readBool(); bool writtenAsCanonicalDecl = Record.readInt(); if (writtenAsCanonicalDecl) { @@ -3742,6 +3748,18 @@ void ASTDeclReader::checkMultipleDefinitionInNamedModules(ASTReader &Reader, Func && Func->getTemplateSpecializationInfo()) return; + // The module ownership of in-class friend declaration is not straightforward. + // Avoid diagnosing such cases. + if (D->getFriendObjectKind() || Previous->getFriendObjectKind()) + return; + + // Skip diagnosing in-class declarations. + if (!Previous->getLexicalDeclContext() + ->getNonTransparentContext() + ->isFileContext() || + !D->getLexicalDeclContext()->getNonTransparentContext()->isFileContext()) + return; + Module *M = Previous->getOwningModule(); if (!M) return; @@ -4678,8 +4696,8 @@ void ASTDeclReader::UpdateDecl(Decl *D) { MSInfo->setPointOfInstantiation(POI); } else { auto *FD = cast(D); - if (auto *FTSInfo = FD->TemplateOrSpecialization - .dyn_cast()) + if (auto *FTSInfo = dyn_cast( + FD->TemplateOrSpecialization)) FTSInfo->setPointOfInstantiation(POI); else cast(FD->TemplateOrSpecialization) diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 990235a310d90..dc953ddeee85c 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2208,6 +2208,16 @@ void ASTStmtReader::VisitPackIndexingExpr(PackIndexingExpr *E) { Exprs[I] = Record.readExpr(); } +void ASTStmtReader::VisitResolvedUnexpandedPackExpr( + ResolvedUnexpandedPackExpr *E) { + VisitExpr(E); + E->NumExprs = Record.readInt(); + E->BeginLoc = readSourceLocation(); + auto **Exprs = E->getTrailingObjects(); + for (unsigned I = 0; I < E->NumExprs; ++I) + Exprs[I] = Record.readExpr(); +} + void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr( SubstNonTypeTemplateParmExpr *E) { VisitExpr(E); @@ -2913,6 +2923,15 @@ void ASTStmtReader::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) { } } +void ASTStmtReader::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) { + VisitStmt(S); + S->Kind = Record.readEnum(); + S->Range = Record.readSourceRange(); + S->DirectiveLoc = Record.readSourceLocation(); + S->AtomicKind = Record.readEnum(); + S->setAssociatedStmt(Record.readSubStmt()); +} + //===----------------------------------------------------------------------===// // HLSL Constructs/Directives. //===----------------------------------------------------------------------===// @@ -4291,6 +4310,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /*TransformedExprs=*/Record[ASTStmtReader::NumExprFields]); break; + case EXPR_RESOLVED_UNEXPANDED_PACK: + S = ResolvedUnexpandedPackExpr::CreateDeserialized( + Context, + /*NumExprs=*/Record[ASTStmtReader::NumExprFields]); + break; + case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM: S = new (Context) SubstNonTypeTemplateParmExpr(Empty); break; @@ -4438,6 +4463,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = OpenACCUpdateConstruct::CreateEmpty(Context, NumClauses); break; } + case STMT_OPENACC_ATOMIC_CONSTRUCT: { + S = OpenACCAtomicConstruct::CreateEmpty(Context); + break; + } case EXPR_REQUIRES: { unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields]; unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1]; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index a580f375aee35..903a165ee75c6 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -874,6 +874,7 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream, RECORD(EXPR_PACK_EXPANSION); RECORD(EXPR_SIZEOF_PACK); RECORD(EXPR_PACK_INDEXING); + RECORD(EXPR_RESOLVED_UNEXPANDED_PACK); RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM); RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK); RECORD(EXPR_FUNCTION_PARM_PACK); @@ -3264,7 +3265,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, // Skip default mappings. We have a mapping for every diagnostic ever // emitted, regardless of whether it was customized. if (!I.second.isPragma() && - I.second == DiagnosticIDs::getDefaultMapping(I.first)) + I.second == Diag.getDiagnosticIDs()->getDefaultMapping(I.first)) continue; Mappings.push_back(I); } @@ -5358,7 +5359,7 @@ ASTWriter::WriteAST(llvm::PointerUnion Subject, llvm::TimeTraceScope scope("WriteAST", OutputFile); WritingAST = true; - Sema *SemaPtr = Subject.dyn_cast(); + Sema *SemaPtr = dyn_cast(Subject); Preprocessor &PPRef = SemaPtr ? SemaPtr->getPreprocessor() : *cast(Subject); @@ -7885,6 +7886,9 @@ void OMPClauseWriter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {} void OMPClauseWriter::VisitOMPNoOpenMPRoutinesClause( OMPNoOpenMPRoutinesClause *) {} +void OMPClauseWriter::VisitOMPNoOpenMPConstructsClause( + OMPNoOpenMPConstructsClause *) {} + void OMPClauseWriter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {} void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {} diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 8b9ba04dce91c..b25dadab656b0 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -679,7 +679,7 @@ void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) { } void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { - static_assert(DeclContext::NumFunctionDeclBits == 44, + static_assert(DeclContext::NumFunctionDeclBits == 45, "You need to update the serializer after you change the " "FunctionDeclBits"); @@ -785,6 +785,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { FunctionDeclBits.addBit(D->hasImplicitReturnZero()); FunctionDeclBits.addBit(D->isMultiVersion()); FunctionDeclBits.addBit(D->isLateTemplateParsed()); + FunctionDeclBits.addBit(D->isInstantiatedFromMemberTemplate()); FunctionDeclBits.addBit(D->FriendConstraintRefersToEnclosingTemplate()); FunctionDeclBits.addBit(D->usesSEHTry()); Record.push_back(FunctionDeclBits); @@ -846,6 +847,9 @@ void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { Record.AddDeclRef(D->Ctor); VisitFunctionDecl(D); Record.push_back(static_cast(D->getDeductionCandidateKind())); + Record.AddDeclRef(D->getSourceDeductionGuide()); + Record.push_back( + static_cast(D->getSourceDeductionGuideKind())); Code = serialization::DECL_CXX_DEDUCTION_GUIDE; } @@ -1840,6 +1844,7 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( Record.AddTemplateArgumentList(&D->getTemplateArgs()); Record.AddSourceLocation(D->getPointOfInstantiation()); Record.push_back(D->getSpecializationKind()); + Record.push_back(D->hasStrictPackMatch()); Record.push_back(D->isCanonicalDecl()); if (D->isCanonicalDecl()) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 651553244812f..e5caf3debc023 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -475,7 +475,7 @@ addConstraintSatisfaction(ASTRecordWriter &Record, if (!Satisfaction.IsSatisfied) { Record.push_back(Satisfaction.NumRecords); for (const auto &DetailRecord : Satisfaction) { - auto *E = DetailRecord.dyn_cast(); + auto *E = dyn_cast(DetailRecord); Record.push_back(/* IsDiagnostic */ E == nullptr); if (E) Record.AddStmt(E); @@ -2210,6 +2210,16 @@ void ASTStmtWriter::VisitPackIndexingExpr(PackIndexingExpr *E) { Code = serialization::EXPR_PACK_INDEXING; } +void ASTStmtWriter::VisitResolvedUnexpandedPackExpr( + ResolvedUnexpandedPackExpr *E) { + VisitExpr(E); + Record.push_back(E->getNumExprs()); + Record.AddSourceLocation(E->getBeginLoc()); + for (Expr *Sub : E->getExprs()) + Record.AddStmt(Sub); + Code = serialization::EXPR_RESOLVED_UNEXPANDED_PACK; +} + void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr( SubstNonTypeTemplateParmExpr *E) { VisitExpr(E); @@ -2997,6 +3007,17 @@ void ASTStmtWriter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) { Code = serialization::STMT_OPENACC_WAIT_CONSTRUCT; } +void ASTStmtWriter::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) { + VisitStmt(S); + Record.writeEnum(S->Kind); + Record.AddSourceRange(S->Range); + Record.AddSourceLocation(S->DirectiveLoc); + Record.writeEnum(S->getAtomicKind()); + Record.AddStmt(S->getAssociatedStmt()); + + Code = serialization::STMT_OPENACC_ATOMIC_CONSTRUCT; +} + //===----------------------------------------------------------------------===// // HLSL Constructs/Directives. //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp index c990ad138f890..109faacf1726a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp @@ -1,4 +1,4 @@ -//== ArrayBoundChecker.cpp ------------------------------*- C++ -*--==// +//== ArrayBoundChecker.cpp -------------------------------------------------==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,81 +6,767 @@ // //===----------------------------------------------------------------------===// // -// This file defines ArrayBoundChecker, which is a path-sensitive check -// which looks for an out-of-bound array element access. +// This file defines security.ArrayBound, which is a path-sensitive checker +// that looks for out of bounds access of memory regions. // //===----------------------------------------------------------------------===// +#include "clang/AST/CharUnits.h" +#include "clang/AST/ParentMapContext.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Checkers/Taint.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" +#include using namespace clang; using namespace ento; +using namespace taint; +using llvm::formatv; namespace { -class ArrayBoundChecker : - public Checker { - const BugType BT{this, "Out-of-bound array access"}; +/// If `E` is a "clean" array subscript expression, return the type of the +/// accessed element. If the base of the subscript expression is modified by +/// pointer arithmetic (and not the beginning of a "full" memory region), this +/// always returns nullopt because that's the right (or the least bad) thing to +/// do for the diagnostic output that's relying on this. +static std::optional determineElementType(const Expr *E, + const CheckerContext &C) { + const auto *ASE = dyn_cast(E); + if (!ASE) + return std::nullopt; + + const MemRegion *SubscriptBaseReg = C.getSVal(ASE->getBase()).getAsRegion(); + if (!SubscriptBaseReg) + return std::nullopt; + + // The base of the subscript expression is affected by pointer arithmetics, + // so we want to report byte offsets instead of indices. + if (isa(SubscriptBaseReg->StripCasts())) + return std::nullopt; + + return ASE->getType(); +} + +static std::optional +determineElementSize(const std::optional T, const CheckerContext &C) { + if (!T) + return std::nullopt; + return C.getASTContext().getTypeSizeInChars(*T).getQuantity(); +} + +class StateUpdateReporter { + const SubRegion *Reg; + const NonLoc ByteOffsetVal; + const std::optional ElementType; + const std::optional ElementSize; + bool AssumedNonNegative = false; + std::optional AssumedUpperBound = std::nullopt; public: - void checkLocation(SVal l, bool isLoad, const Stmt* S, - CheckerContext &C) const; + StateUpdateReporter(const SubRegion *R, NonLoc ByteOffsVal, const Expr *E, + CheckerContext &C) + : Reg(R), ByteOffsetVal(ByteOffsVal), + ElementType(determineElementType(E, C)), + ElementSize(determineElementSize(ElementType, C)) {} + + void recordNonNegativeAssumption() { AssumedNonNegative = true; } + void recordUpperBoundAssumption(NonLoc UpperBoundVal) { + AssumedUpperBound = UpperBoundVal; + } + + bool assumedNonNegative() { return AssumedNonNegative; } + + const NoteTag *createNoteTag(CheckerContext &C) const; + +private: + std::string getMessage(PathSensitiveBugReport &BR) const; + + /// Return true if information about the value of `Sym` can put constraints + /// on some symbol which is interesting within the bug report `BR`. + /// In particular, this returns true when `Sym` is interesting within `BR`; + /// but it also returns true if `Sym` is an expression that contains integer + /// constants and a single symbolic operand which is interesting (in `BR`). + /// We need to use this instead of plain `BR.isInteresting()` because if we + /// are analyzing code like + /// int array[10]; + /// int f(int arg) { + /// return array[arg] && array[arg + 10]; + /// } + /// then the byte offsets are `arg * 4` and `(arg + 10) * 4`, which are not + /// sub-expressions of each other (but `getSimplifiedOffsets` is smart enough + /// to detect this out of bounds access). + static bool providesInformationAboutInteresting(SymbolRef Sym, + PathSensitiveBugReport &BR); + static bool providesInformationAboutInteresting(SVal SV, + PathSensitiveBugReport &BR) { + return providesInformationAboutInteresting(SV.getAsSymbol(), BR); + } }; + +struct Messages { + std::string Short, Full; +}; + +// NOTE: The `ArraySubscriptExpr` and `UnaryOperator` callbacks are `PostStmt` +// instead of `PreStmt` because the current implementation passes the whole +// expression to `CheckerContext::getSVal()` which only works after the +// symbolic evaluation of the expression. (To turn them into `PreStmt` +// callbacks, we'd need to duplicate the logic that evaluates these +// expressions.) The `MemberExpr` callback would work as `PreStmt` but it's +// defined as `PostStmt` for the sake of consistency with the other callbacks. +class ArrayBoundChecker : public Checker, + check::PostStmt, + check::PostStmt> { + BugType BT{this, "Out-of-bound access"}; + BugType TaintBT{this, "Out-of-bound access", categories::TaintedData}; + + void performCheck(const Expr *E, CheckerContext &C) const; + + void reportOOB(CheckerContext &C, ProgramStateRef ErrorState, Messages Msgs, + NonLoc Offset, std::optional Extent, + bool IsTaintBug = false) const; + + static void markPartsInteresting(PathSensitiveBugReport &BR, + ProgramStateRef ErrorState, NonLoc Val, + bool MarkTaint); + + static bool isFromCtypeMacro(const Stmt *S, ASTContext &AC); + + static bool isIdiomaticPastTheEndPtr(const Expr *E, ProgramStateRef State, + NonLoc Offset, NonLoc Limit, + CheckerContext &C); + static bool isInAddressOf(const Stmt *S, ASTContext &AC); + +public: + void checkPostStmt(const ArraySubscriptExpr *E, CheckerContext &C) const { + performCheck(E, C); + } + void checkPostStmt(const UnaryOperator *E, CheckerContext &C) const { + if (E->getOpcode() == UO_Deref) + performCheck(E, C); + } + void checkPostStmt(const MemberExpr *E, CheckerContext &C) const { + if (E->isArrow()) + performCheck(E->getBase(), C); + } +}; + +} // anonymous namespace + +/// For a given Location that can be represented as a symbolic expression +/// Arr[Idx] (or perhaps Arr[Idx1][Idx2] etc.), return the parent memory block +/// Arr and the distance of Location from the beginning of Arr (expressed in a +/// NonLoc that specifies the number of CharUnits). Returns nullopt when these +/// cannot be determined. +static std::optional> +computeOffset(ProgramStateRef State, SValBuilder &SVB, SVal Location) { + QualType T = SVB.getArrayIndexType(); + auto EvalBinOp = [&SVB, State, T](BinaryOperatorKind Op, NonLoc L, NonLoc R) { + // We will use this utility to add and multiply values. + return SVB.evalBinOpNN(State, Op, L, R, T).getAs(); + }; + + const SubRegion *OwnerRegion = nullptr; + std::optional Offset = SVB.makeZeroArrayIndex(); + + const ElementRegion *CurRegion = + dyn_cast_or_null(Location.getAsRegion()); + + while (CurRegion) { + const auto Index = CurRegion->getIndex().getAs(); + if (!Index) + return std::nullopt; + + QualType ElemType = CurRegion->getElementType(); + + // FIXME: The following early return was presumably added to safeguard the + // getTypeSizeInChars() call (which doesn't accept an incomplete type), but + // it seems that `ElemType` cannot be incomplete at this point. + if (ElemType->isIncompleteType()) + return std::nullopt; + + // Calculate Delta = Index * sizeof(ElemType). + NonLoc Size = SVB.makeArrayIndex( + SVB.getContext().getTypeSizeInChars(ElemType).getQuantity()); + auto Delta = EvalBinOp(BO_Mul, *Index, Size); + if (!Delta) + return std::nullopt; + + // Perform Offset += Delta. + Offset = EvalBinOp(BO_Add, *Offset, *Delta); + if (!Offset) + return std::nullopt; + + OwnerRegion = CurRegion->getSuperRegion()->getAs(); + // When this is just another ElementRegion layer, we need to continue the + // offset calculations: + CurRegion = dyn_cast_or_null(OwnerRegion); + } + + if (OwnerRegion) + return std::make_pair(OwnerRegion, *Offset); + + return std::nullopt; } -void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS, - CheckerContext &C) const { - // Check for out of bound array element access. - const MemRegion *R = l.getAsRegion(); - if (!R) - return; +// NOTE: This function is the "heart" of this checker. It simplifies +// inequalities with transformations that are valid (and very elementary) in +// pure mathematics, but become invalid if we use them in C++ number model +// where the calculations may overflow. +// Due to the overflow issues I think it's impossible (or at least not +// practical) to integrate this kind of simplification into the resolution of +// arbitrary inequalities (i.e. the code of `evalBinOp`); but this function +// produces valid results when the calculations are handling memory offsets +// and every value is well below SIZE_MAX. +// TODO: This algorithm should be moved to a central location where it's +// available for other checkers that need to compare memory offsets. +// NOTE: the simplification preserves the order of the two operands in a +// mathematical sense, but it may change the result produced by a C++ +// comparison operator (and the automatic type conversions). +// For example, consider a comparison "X+1 < 0", where the LHS is stored as a +// size_t and the RHS is stored in an int. (As size_t is unsigned, this +// comparison is false for all values of "X".) However, the simplification may +// turn it into "X < -1", which is still always false in a mathematical sense, +// but can produce a true result when evaluated by `evalBinOp` (which follows +// the rules of C++ and casts -1 to SIZE_MAX). +static std::pair +getSimplifiedOffsets(NonLoc offset, nonloc::ConcreteInt extent, + SValBuilder &svalBuilder) { + const llvm::APSInt &extentVal = extent.getValue(); + std::optional SymVal = offset.getAs(); + if (SymVal && SymVal->isExpression()) { + if (const SymIntExpr *SIE = dyn_cast(SymVal->getSymbol())) { + llvm::APSInt constant = APSIntType(extentVal).convert(SIE->getRHS()); + switch (SIE->getOpcode()) { + case BO_Mul: + // The constant should never be 0 here, becasue multiplication by zero + // is simplified by the engine. + if ((extentVal % constant) != 0) + return std::pair(offset, extent); + else + return getSimplifiedOffsets( + nonloc::SymbolVal(SIE->getLHS()), + svalBuilder.makeIntVal(extentVal / constant), svalBuilder); + case BO_Add: + return getSimplifiedOffsets( + nonloc::SymbolVal(SIE->getLHS()), + svalBuilder.makeIntVal(extentVal - constant), svalBuilder); + default: + break; + } + } + } + + return std::pair(offset, extent); +} + +static bool isNegative(SValBuilder &SVB, ProgramStateRef State, NonLoc Value) { + const llvm::APSInt *MaxV = SVB.getMaxValue(State, Value); + return MaxV && MaxV->isNegative(); +} + +static bool isUnsigned(SValBuilder &SVB, NonLoc Value) { + QualType T = Value.getType(SVB.getContext()); + return T->isUnsignedIntegerType(); +} + +// Evaluate the comparison Value < Threshold with the help of the custom +// simplification algorithm defined for this checker. Return a pair of states, +// where the first one corresponds to "value below threshold" and the second +// corresponds to "value at or above threshold". Returns {nullptr, nullptr} in +// the case when the evaluation fails. +// If the optional argument CheckEquality is true, then use BO_EQ instead of +// the default BO_LT after consistently applying the same simplification steps. +static std::pair +compareValueToThreshold(ProgramStateRef State, NonLoc Value, NonLoc Threshold, + SValBuilder &SVB, bool CheckEquality = false) { + if (auto ConcreteThreshold = Threshold.getAs()) { + std::tie(Value, Threshold) = + getSimplifiedOffsets(Value, *ConcreteThreshold, SVB); + } + + // We want to perform a _mathematical_ comparison between the numbers `Value` + // and `Threshold`; but `evalBinOpNN` evaluates a C/C++ operator that may + // perform automatic conversions. For example the number -1 is less than the + // number 1000, but -1 < `1000ull` will evaluate to `false` because the `int` + // -1 is converted to ULONGLONG_MAX. + // To avoid automatic conversions, we evaluate the "obvious" cases without + // calling `evalBinOpNN`: + if (isNegative(SVB, State, Value) && isUnsigned(SVB, Threshold)) { + if (CheckEquality) { + // negative_value == unsigned_threshold is always false + return {nullptr, State}; + } + // negative_value < unsigned_threshold is always true + return {State, nullptr}; + } + if (isUnsigned(SVB, Value) && isNegative(SVB, State, Threshold)) { + // unsigned_value == negative_threshold and + // unsigned_value < negative_threshold are both always false + return {nullptr, State}; + } + // FIXME: These special cases are sufficient for handling real-world + // comparisons, but in theory there could be contrived situations where + // automatic conversion of a symbolic value (which can be negative and can be + // positive) leads to incorrect results. + // NOTE: We NEED to use the `evalBinOpNN` call in the "common" case, because + // we want to ensure that assumptions coming from this precondition and + // assumptions coming from regular C/C++ operator calls are represented by + // constraints on the same symbolic expression. A solution that would + // evaluate these "mathematical" compariosns through a separate pathway would + // be a step backwards in this sense. + + const BinaryOperatorKind OpKind = CheckEquality ? BO_EQ : BO_LT; + auto BelowThreshold = + SVB.evalBinOpNN(State, OpKind, Value, Threshold, SVB.getConditionType()) + .getAs(); + + if (BelowThreshold) + return State->assume(*BelowThreshold); + + return {nullptr, nullptr}; +} + +static std::string getRegionName(const SubRegion *Region) { + if (std::string RegName = Region->getDescriptiveName(); !RegName.empty()) + return RegName; + + // Field regions only have descriptive names when their parent has a + // descriptive name; so we provide a fallback representation for them: + if (const auto *FR = Region->getAs()) { + if (StringRef Name = FR->getDecl()->getName(); !Name.empty()) + return formatv("the field '{0}'", Name); + return "the unnamed field"; + } + + if (isa(Region)) + return "the memory returned by 'alloca'"; + + if (isa(Region) && + isa(Region->getMemorySpace())) + return "the heap area"; + + if (isa(Region)) + return "the string literal"; + + return "the region"; +} + +static std::optional getConcreteValue(NonLoc SV) { + if (auto ConcreteVal = SV.getAs()) { + return ConcreteVal->getValue()->tryExtValue(); + } + return std::nullopt; +} - const ElementRegion *ER = dyn_cast(R); - if (!ER) +static std::optional getConcreteValue(std::optional SV) { + return SV ? getConcreteValue(*SV) : std::nullopt; +} + +static Messages getPrecedesMsgs(const SubRegion *Region, NonLoc Offset) { + std::string RegName = getRegionName(Region), OffsetStr = ""; + + if (auto ConcreteOffset = getConcreteValue(Offset)) + OffsetStr = formatv(" {0}", ConcreteOffset); + + return { + formatv("Out of bound access to memory preceding {0}", RegName), + formatv("Access of {0} at negative byte offset{1}", RegName, OffsetStr)}; +} + +/// Try to divide `Val1` and `Val2` (in place) by `Divisor` and return true if +/// it can be performed (`Divisor` is nonzero and there is no remainder). The +/// values `Val1` and `Val2` may be nullopt and in that case the corresponding +/// division is considered to be successful. +static bool tryDividePair(std::optional &Val1, + std::optional &Val2, int64_t Divisor) { + if (!Divisor) + return false; + const bool Val1HasRemainder = Val1 && *Val1 % Divisor; + const bool Val2HasRemainder = Val2 && *Val2 % Divisor; + if (!Val1HasRemainder && !Val2HasRemainder) { + if (Val1) + *Val1 /= Divisor; + if (Val2) + *Val2 /= Divisor; + return true; + } + return false; +} + +static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region, + NonLoc Offset, NonLoc Extent, SVal Location, + bool AlsoMentionUnderflow) { + std::string RegName = getRegionName(Region); + const auto *EReg = Location.getAsRegion()->getAs(); + assert(EReg && "this checker only handles element access"); + QualType ElemType = EReg->getElementType(); + + std::optional OffsetN = getConcreteValue(Offset); + std::optional ExtentN = getConcreteValue(Extent); + + int64_t ElemSize = ACtx.getTypeSizeInChars(ElemType).getQuantity(); + + bool UseByteOffsets = !tryDividePair(OffsetN, ExtentN, ElemSize); + const char *OffsetOrIndex = UseByteOffsets ? "byte offset" : "index"; + + SmallString<256> Buf; + llvm::raw_svector_ostream Out(Buf); + Out << "Access of "; + if (!ExtentN && !UseByteOffsets) + Out << "'" << ElemType.getAsString() << "' element in "; + Out << RegName << " at "; + if (AlsoMentionUnderflow) { + Out << "a negative or overflowing " << OffsetOrIndex; + } else if (OffsetN) { + Out << OffsetOrIndex << " " << *OffsetN; + } else { + Out << "an overflowing " << OffsetOrIndex; + } + if (ExtentN) { + Out << ", while it holds only "; + if (*ExtentN != 1) + Out << *ExtentN; + else + Out << "a single"; + if (UseByteOffsets) + Out << " byte"; + else + Out << " '" << ElemType.getAsString() << "' element"; + + if (*ExtentN > 1) + Out << "s"; + } + + return {formatv("Out of bound access to memory {0} {1}", + AlsoMentionUnderflow ? "around" : "after the end of", + RegName), + std::string(Buf)}; +} + +static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName, + bool AlsoMentionUnderflow) { + std::string RegName = getRegionName(Region); + return {formatv("Potential out of bound access to {0} with tainted {1}", + RegName, OffsetName), + formatv("Access of {0} with a tainted {1} that may be {2}too large", + RegName, OffsetName, + AlsoMentionUnderflow ? "negative or " : "")}; +} + +const NoteTag *StateUpdateReporter::createNoteTag(CheckerContext &C) const { + // Don't create a note tag if we didn't assume anything: + if (!AssumedNonNegative && !AssumedUpperBound) + return nullptr; + + return C.getNoteTag([*this](PathSensitiveBugReport &BR) -> std::string { + return getMessage(BR); + }); +} + +std::string StateUpdateReporter::getMessage(PathSensitiveBugReport &BR) const { + bool ShouldReportNonNegative = AssumedNonNegative; + if (!providesInformationAboutInteresting(ByteOffsetVal, BR)) { + if (AssumedUpperBound && + providesInformationAboutInteresting(*AssumedUpperBound, BR)) { + // Even if the byte offset isn't interesting (e.g. it's a constant value), + // the assumption can still be interesting if it provides information + // about an interesting symbolic upper bound. + ShouldReportNonNegative = false; + } else { + // We don't have anything interesting, don't report the assumption. + return ""; + } + } + + std::optional OffsetN = getConcreteValue(ByteOffsetVal); + std::optional ExtentN = getConcreteValue(AssumedUpperBound); + + const bool UseIndex = + ElementSize && tryDividePair(OffsetN, ExtentN, *ElementSize); + + SmallString<256> Buf; + llvm::raw_svector_ostream Out(Buf); + Out << "Assuming "; + if (UseIndex) { + Out << "index "; + if (OffsetN) + Out << "'" << OffsetN << "' "; + } else if (AssumedUpperBound) { + Out << "byte offset "; + if (OffsetN) + Out << "'" << OffsetN << "' "; + } else { + Out << "offset "; + } + + Out << "is"; + if (ShouldReportNonNegative) { + Out << " non-negative"; + } + if (AssumedUpperBound) { + if (ShouldReportNonNegative) + Out << " and"; + Out << " less than "; + if (ExtentN) + Out << *ExtentN << ", "; + if (UseIndex && ElementType) + Out << "the number of '" << ElementType->getAsString() + << "' elements in "; + else + Out << "the extent of "; + Out << getRegionName(Reg); + } + return std::string(Out.str()); +} + +bool StateUpdateReporter::providesInformationAboutInteresting( + SymbolRef Sym, PathSensitiveBugReport &BR) { + if (!Sym) + return false; + for (SymbolRef PartSym : Sym->symbols()) { + // The interestingess mark may appear on any layer as we're stripping off + // the SymIntExpr, UnarySymExpr etc. layers... + if (BR.isInteresting(PartSym)) + return true; + // ...but if both sides of the expression are symbolic, then there is no + // practical algorithm to produce separate constraints for the two + // operands (from the single combined result). + if (isa(PartSym)) + return false; + } + return false; +} + +void ArrayBoundChecker::performCheck(const Expr *E, CheckerContext &C) const { + const SVal Location = C.getSVal(E); + + // The header ctype.h (from e.g. glibc) implements the isXXXXX() macros as + // #define isXXXXX(arg) (LOOKUP_TABLE[arg] & BITMASK_FOR_XXXXX) + // and incomplete analysis of these leads to false positives. As even + // accurate reports would be confusing for the users, just disable reports + // from these macros: + if (isFromCtypeMacro(E, C.getASTContext())) return; - // Get the index of the accessed element. - DefinedOrUnknownSVal Idx = ER->getIndex().castAs(); + ProgramStateRef State = C.getState(); + SValBuilder &SVB = C.getSValBuilder(); - // Zero index is always in bound, this also passes ElementRegions created for - // pointer casts. - if (Idx.isZeroConstant()) + const std::optional> &RawOffset = + computeOffset(State, SVB, Location); + + if (!RawOffset) return; - ProgramStateRef state = C.getState(); + auto [Reg, ByteOffset] = *RawOffset; - // Get the size of the array. - DefinedOrUnknownSVal ElementCount = getDynamicElementCount( - state, ER->getSuperRegion(), C.getSValBuilder(), ER->getValueType()); + // The state updates will be reported as a single note tag, which will be + // composed by this helper class. + StateUpdateReporter SUR(Reg, ByteOffset, E, C); - ProgramStateRef StInBound, StOutBound; - std::tie(StInBound, StOutBound) = state->assumeInBoundDual(Idx, ElementCount); - if (StOutBound && !StInBound) { - ExplodedNode *N = C.generateErrorNode(StOutBound); - if (!N) - return; + // CHECK LOWER BOUND + const MemSpaceRegion *Space = Reg->getMemorySpace(); + if (!(isa(Reg) && isa(Space))) { + // A symbolic region in unknown space represents an unknown pointer that + // may point into the middle of an array, so we don't look for underflows. + // Both conditions are significant because we want to check underflows in + // symbolic regions on the heap (which may be introduced by checkers like + // MallocChecker that call SValBuilder::getConjuredHeapSymbolVal()) and + // non-symbolic regions (e.g. a field subregion of a symbolic region) in + // unknown space. + auto [PrecedesLowerBound, WithinLowerBound] = compareValueToThreshold( + State, ByteOffset, SVB.makeZeroArrayIndex(), SVB); - // FIXME: It would be nice to eventually make this diagnostic more clear, - // e.g., by referencing the original declaration or by saying *why* this - // reference is outside the range. + if (PrecedesLowerBound) { + // The offset may be invalid (negative)... + if (!WithinLowerBound) { + // ...and it cannot be valid (>= 0), so report an error. + Messages Msgs = getPrecedesMsgs(Reg, ByteOffset); + reportOOB(C, PrecedesLowerBound, Msgs, ByteOffset, std::nullopt); + return; + } + // ...but it can be valid as well, so the checker will (optimistically) + // assume that it's valid and mention this in the note tag. + SUR.recordNonNegativeAssumption(); + } - // Generate a report for this bug. - auto report = std::make_unique( - BT, "Access out-of-bound array element (buffer overflow)", N); + // Actually update the state. The "if" only fails in the extremely unlikely + // case when compareValueToThreshold returns {nullptr, nullptr} becasue + // evalBinOpNN fails to evaluate the less-than operator. + if (WithinLowerBound) + State = WithinLowerBound; + } - report->addRange(LoadS->getSourceRange()); - C.emitReport(std::move(report)); - return; + // CHECK UPPER BOUND + DefinedOrUnknownSVal Size = getDynamicExtent(State, Reg, SVB); + if (auto KnownSize = Size.getAs()) { + // In a situation where both underflow and overflow are possible (but the + // index is either tainted or known to be invalid), the logic of this + // checker will first assume that the offset is non-negative, and then + // (with this additional assumption) it will detect an overflow error. + // In this situation the warning message should mention both possibilities. + bool AlsoMentionUnderflow = SUR.assumedNonNegative(); + + auto [WithinUpperBound, ExceedsUpperBound] = + compareValueToThreshold(State, ByteOffset, *KnownSize, SVB); + + if (ExceedsUpperBound) { + // The offset may be invalid (>= Size)... + if (!WithinUpperBound) { + // ...and it cannot be within bounds, so report an error, unless we can + // definitely determine that this is an idiomatic `&array[size]` + // expression that calculates the past-the-end pointer. + if (isIdiomaticPastTheEndPtr(E, ExceedsUpperBound, ByteOffset, + *KnownSize, C)) { + C.addTransition(ExceedsUpperBound, SUR.createNoteTag(C)); + return; + } + + Messages Msgs = + getExceedsMsgs(C.getASTContext(), Reg, ByteOffset, *KnownSize, + Location, AlsoMentionUnderflow); + reportOOB(C, ExceedsUpperBound, Msgs, ByteOffset, KnownSize); + return; + } + // ...and it can be valid as well... + if (isTainted(State, ByteOffset)) { + // ...but it's tainted, so report an error. + + // Diagnostic detail: saying "tainted offset" is always correct, but + // the common case is that 'idx' is tainted in 'arr[idx]' and then it's + // nicer to say "tainted index". + const char *OffsetName = "offset"; + if (const auto *ASE = dyn_cast(E)) + if (isTainted(State, ASE->getIdx(), C.getLocationContext())) + OffsetName = "index"; + + Messages Msgs = getTaintMsgs(Reg, OffsetName, AlsoMentionUnderflow); + reportOOB(C, ExceedsUpperBound, Msgs, ByteOffset, KnownSize, + /*IsTaintBug=*/true); + return; + } + // ...and it isn't tainted, so the checker will (optimistically) assume + // that the offset is in bounds and mention this in the note tag. + SUR.recordUpperBoundAssumption(*KnownSize); + } + + // Actually update the state. The "if" only fails in the extremely unlikely + // case when compareValueToThreshold returns {nullptr, nullptr} becasue + // evalBinOpNN fails to evaluate the less-than operator. + if (WithinUpperBound) + State = WithinUpperBound; + } + + // Add a transition, reporting the state updates that we accumulated. + C.addTransition(State, SUR.createNoteTag(C)); +} + +void ArrayBoundChecker::markPartsInteresting(PathSensitiveBugReport &BR, + ProgramStateRef ErrorState, + NonLoc Val, bool MarkTaint) { + if (SymbolRef Sym = Val.getAsSymbol()) { + // If the offset is a symbolic value, iterate over its "parts" with + // `SymExpr::symbols()` and mark each of them as interesting. + // For example, if the offset is `x*4 + y` then we put interestingness onto + // the SymSymExpr `x*4 + y`, the SymIntExpr `x*4` and the two data symbols + // `x` and `y`. + for (SymbolRef PartSym : Sym->symbols()) + BR.markInteresting(PartSym); + } + + if (MarkTaint) { + // If the issue that we're reporting depends on the taintedness of the + // offset, then put interestingness onto symbols that could be the origin + // of the taint. Note that this may find symbols that did not appear in + // `Sym->symbols()` (because they're only loosely connected to `Val`). + for (SymbolRef Sym : getTaintedSymbols(ErrorState, Val)) + BR.markInteresting(Sym); } +} + +void ArrayBoundChecker::reportOOB(CheckerContext &C, ProgramStateRef ErrorState, + Messages Msgs, NonLoc Offset, + std::optional Extent, + bool IsTaintBug /*=false*/) const { + + ExplodedNode *ErrorNode = C.generateErrorNode(ErrorState); + if (!ErrorNode) + return; + + auto BR = std::make_unique( + IsTaintBug ? TaintBT : BT, Msgs.Short, Msgs.Full, ErrorNode); + + // FIXME: ideally we would just call trackExpressionValue() and that would + // "do the right thing": mark the relevant symbols as interesting, track the + // control dependencies and statements storing the relevant values and add + // helpful diagnostic pieces. However, right now trackExpressionValue() is + // a heap of unreliable heuristics, so it would cause several issues: + // - Interestingness is not applied consistently, e.g. if `array[x+10]` + // causes an overflow, then `x` is not marked as interesting. + // - We get irrelevant diagnostic pieces, e.g. in the code + // `int *p = (int*)malloc(2*sizeof(int)); p[3] = 0;` + // it places a "Storing uninitialized value" note on the `malloc` call + // (which is technically true, but irrelevant). + // If trackExpressionValue() becomes reliable, it should be applied instead + // of this custom markPartsInteresting(). + markPartsInteresting(*BR, ErrorState, Offset, IsTaintBug); + if (Extent) + markPartsInteresting(*BR, ErrorState, *Extent, IsTaintBug); + + C.emitReport(std::move(BR)); +} - // Array bound check succeeded. From this point forward the array bound - // should always succeed. - C.addTransition(StInBound); +bool ArrayBoundChecker::isFromCtypeMacro(const Stmt *S, ASTContext &ACtx) { + SourceLocation Loc = S->getBeginLoc(); + if (!Loc.isMacroID()) + return false; + + StringRef MacroName = Lexer::getImmediateMacroName( + Loc, ACtx.getSourceManager(), ACtx.getLangOpts()); + + if (MacroName.size() < 7 || MacroName[0] != 'i' || MacroName[1] != 's') + return false; + + return ((MacroName == "isalnum") || (MacroName == "isalpha") || + (MacroName == "isblank") || (MacroName == "isdigit") || + (MacroName == "isgraph") || (MacroName == "islower") || + (MacroName == "isnctrl") || (MacroName == "isprint") || + (MacroName == "ispunct") || (MacroName == "isspace") || + (MacroName == "isupper") || (MacroName == "isxdigit")); +} + +bool ArrayBoundChecker::isInAddressOf(const Stmt *S, ASTContext &ACtx) { + ParentMapContext &ParentCtx = ACtx.getParentMapContext(); + do { + const DynTypedNodeList Parents = ParentCtx.getParents(*S); + if (Parents.empty()) + return false; + S = Parents[0].get(); + } while (isa_and_nonnull(S)); + const auto *UnaryOp = dyn_cast_or_null(S); + return UnaryOp && UnaryOp->getOpcode() == UO_AddrOf; +} + +bool ArrayBoundChecker::isIdiomaticPastTheEndPtr(const Expr *E, + ProgramStateRef State, + NonLoc Offset, NonLoc Limit, + CheckerContext &C) { + if (isa(E) && isInAddressOf(E, C.getASTContext())) { + auto [EqualsToThreshold, NotEqualToThreshold] = compareValueToThreshold( + State, Offset, Limit, C.getSValBuilder(), /*CheckEquality=*/true); + return EqualsToThreshold && !NotEqualToThreshold; + } + return false; } void ento::registerArrayBoundChecker(CheckerManager &mgr) { diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp deleted file mode 100644 index 6422933c8828a..0000000000000 --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ /dev/null @@ -1,777 +0,0 @@ -//== ArrayBoundCheckerV2.cpp ------------------------------------*- C++ -*--==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines ArrayBoundCheckerV2, which is a path-sensitive check -// which looks for an out-of-bound array element access. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/CharUnits.h" -#include "clang/AST/ParentMapContext.h" -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" -#include "clang/StaticAnalyzer/Checkers/Taint.h" -#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/Checker.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" -#include "llvm/ADT/APSInt.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/raw_ostream.h" -#include - -using namespace clang; -using namespace ento; -using namespace taint; -using llvm::formatv; - -namespace { -/// If `E` is a "clean" array subscript expression, return the type of the -/// accessed element. If the base of the subscript expression is modified by -/// pointer arithmetic (and not the beginning of a "full" memory region), this -/// always returns nullopt because that's the right (or the least bad) thing to -/// do for the diagnostic output that's relying on this. -static std::optional determineElementType(const Expr *E, - const CheckerContext &C) { - const auto *ASE = dyn_cast(E); - if (!ASE) - return std::nullopt; - - const MemRegion *SubscriptBaseReg = C.getSVal(ASE->getBase()).getAsRegion(); - if (!SubscriptBaseReg) - return std::nullopt; - - // The base of the subscript expression is affected by pointer arithmetics, - // so we want to report byte offsets instead of indices. - if (isa(SubscriptBaseReg->StripCasts())) - return std::nullopt; - - return ASE->getType(); -} - -static std::optional -determineElementSize(const std::optional T, const CheckerContext &C) { - if (!T) - return std::nullopt; - return C.getASTContext().getTypeSizeInChars(*T).getQuantity(); -} - -class StateUpdateReporter { - const SubRegion *Reg; - const NonLoc ByteOffsetVal; - const std::optional ElementType; - const std::optional ElementSize; - bool AssumedNonNegative = false; - std::optional AssumedUpperBound = std::nullopt; - -public: - StateUpdateReporter(const SubRegion *R, NonLoc ByteOffsVal, const Expr *E, - CheckerContext &C) - : Reg(R), ByteOffsetVal(ByteOffsVal), - ElementType(determineElementType(E, C)), - ElementSize(determineElementSize(ElementType, C)) {} - - void recordNonNegativeAssumption() { AssumedNonNegative = true; } - void recordUpperBoundAssumption(NonLoc UpperBoundVal) { - AssumedUpperBound = UpperBoundVal; - } - - bool assumedNonNegative() { return AssumedNonNegative; } - - const NoteTag *createNoteTag(CheckerContext &C) const; - -private: - std::string getMessage(PathSensitiveBugReport &BR) const; - - /// Return true if information about the value of `Sym` can put constraints - /// on some symbol which is interesting within the bug report `BR`. - /// In particular, this returns true when `Sym` is interesting within `BR`; - /// but it also returns true if `Sym` is an expression that contains integer - /// constants and a single symbolic operand which is interesting (in `BR`). - /// We need to use this instead of plain `BR.isInteresting()` because if we - /// are analyzing code like - /// int array[10]; - /// int f(int arg) { - /// return array[arg] && array[arg + 10]; - /// } - /// then the byte offsets are `arg * 4` and `(arg + 10) * 4`, which are not - /// sub-expressions of each other (but `getSimplifiedOffsets` is smart enough - /// to detect this out of bounds access). - static bool providesInformationAboutInteresting(SymbolRef Sym, - PathSensitiveBugReport &BR); - static bool providesInformationAboutInteresting(SVal SV, - PathSensitiveBugReport &BR) { - return providesInformationAboutInteresting(SV.getAsSymbol(), BR); - } -}; - -struct Messages { - std::string Short, Full; -}; - -// NOTE: The `ArraySubscriptExpr` and `UnaryOperator` callbacks are `PostStmt` -// instead of `PreStmt` because the current implementation passes the whole -// expression to `CheckerContext::getSVal()` which only works after the -// symbolic evaluation of the expression. (To turn them into `PreStmt` -// callbacks, we'd need to duplicate the logic that evaluates these -// expressions.) The `MemberExpr` callback would work as `PreStmt` but it's -// defined as `PostStmt` for the sake of consistency with the other callbacks. -class ArrayBoundCheckerV2 : public Checker, - check::PostStmt, - check::PostStmt> { - BugType BT{this, "Out-of-bound access"}; - BugType TaintBT{this, "Out-of-bound access", categories::TaintedData}; - - void performCheck(const Expr *E, CheckerContext &C) const; - - void reportOOB(CheckerContext &C, ProgramStateRef ErrorState, Messages Msgs, - NonLoc Offset, std::optional Extent, - bool IsTaintBug = false) const; - - static void markPartsInteresting(PathSensitiveBugReport &BR, - ProgramStateRef ErrorState, NonLoc Val, - bool MarkTaint); - - static bool isFromCtypeMacro(const Stmt *S, ASTContext &AC); - - static bool isIdiomaticPastTheEndPtr(const Expr *E, ProgramStateRef State, - NonLoc Offset, NonLoc Limit, - CheckerContext &C); - static bool isInAddressOf(const Stmt *S, ASTContext &AC); - -public: - void checkPostStmt(const ArraySubscriptExpr *E, CheckerContext &C) const { - performCheck(E, C); - } - void checkPostStmt(const UnaryOperator *E, CheckerContext &C) const { - if (E->getOpcode() == UO_Deref) - performCheck(E, C); - } - void checkPostStmt(const MemberExpr *E, CheckerContext &C) const { - if (E->isArrow()) - performCheck(E->getBase(), C); - } -}; - -} // anonymous namespace - -/// For a given Location that can be represented as a symbolic expression -/// Arr[Idx] (or perhaps Arr[Idx1][Idx2] etc.), return the parent memory block -/// Arr and the distance of Location from the beginning of Arr (expressed in a -/// NonLoc that specifies the number of CharUnits). Returns nullopt when these -/// cannot be determined. -static std::optional> -computeOffset(ProgramStateRef State, SValBuilder &SVB, SVal Location) { - QualType T = SVB.getArrayIndexType(); - auto EvalBinOp = [&SVB, State, T](BinaryOperatorKind Op, NonLoc L, NonLoc R) { - // We will use this utility to add and multiply values. - return SVB.evalBinOpNN(State, Op, L, R, T).getAs(); - }; - - const SubRegion *OwnerRegion = nullptr; - std::optional Offset = SVB.makeZeroArrayIndex(); - - const ElementRegion *CurRegion = - dyn_cast_or_null(Location.getAsRegion()); - - while (CurRegion) { - const auto Index = CurRegion->getIndex().getAs(); - if (!Index) - return std::nullopt; - - QualType ElemType = CurRegion->getElementType(); - - // FIXME: The following early return was presumably added to safeguard the - // getTypeSizeInChars() call (which doesn't accept an incomplete type), but - // it seems that `ElemType` cannot be incomplete at this point. - if (ElemType->isIncompleteType()) - return std::nullopt; - - // Calculate Delta = Index * sizeof(ElemType). - NonLoc Size = SVB.makeArrayIndex( - SVB.getContext().getTypeSizeInChars(ElemType).getQuantity()); - auto Delta = EvalBinOp(BO_Mul, *Index, Size); - if (!Delta) - return std::nullopt; - - // Perform Offset += Delta. - Offset = EvalBinOp(BO_Add, *Offset, *Delta); - if (!Offset) - return std::nullopt; - - OwnerRegion = CurRegion->getSuperRegion()->getAs(); - // When this is just another ElementRegion layer, we need to continue the - // offset calculations: - CurRegion = dyn_cast_or_null(OwnerRegion); - } - - if (OwnerRegion) - return std::make_pair(OwnerRegion, *Offset); - - return std::nullopt; -} - -// NOTE: This function is the "heart" of this checker. It simplifies -// inequalities with transformations that are valid (and very elementary) in -// pure mathematics, but become invalid if we use them in C++ number model -// where the calculations may overflow. -// Due to the overflow issues I think it's impossible (or at least not -// practical) to integrate this kind of simplification into the resolution of -// arbitrary inequalities (i.e. the code of `evalBinOp`); but this function -// produces valid results when the calculations are handling memory offsets -// and every value is well below SIZE_MAX. -// TODO: This algorithm should be moved to a central location where it's -// available for other checkers that need to compare memory offsets. -// NOTE: the simplification preserves the order of the two operands in a -// mathematical sense, but it may change the result produced by a C++ -// comparison operator (and the automatic type conversions). -// For example, consider a comparison "X+1 < 0", where the LHS is stored as a -// size_t and the RHS is stored in an int. (As size_t is unsigned, this -// comparison is false for all values of "X".) However, the simplification may -// turn it into "X < -1", which is still always false in a mathematical sense, -// but can produce a true result when evaluated by `evalBinOp` (which follows -// the rules of C++ and casts -1 to SIZE_MAX). -static std::pair -getSimplifiedOffsets(NonLoc offset, nonloc::ConcreteInt extent, - SValBuilder &svalBuilder) { - const llvm::APSInt &extentVal = extent.getValue(); - std::optional SymVal = offset.getAs(); - if (SymVal && SymVal->isExpression()) { - if (const SymIntExpr *SIE = dyn_cast(SymVal->getSymbol())) { - llvm::APSInt constant = APSIntType(extentVal).convert(SIE->getRHS()); - switch (SIE->getOpcode()) { - case BO_Mul: - // The constant should never be 0 here, becasue multiplication by zero - // is simplified by the engine. - if ((extentVal % constant) != 0) - return std::pair(offset, extent); - else - return getSimplifiedOffsets( - nonloc::SymbolVal(SIE->getLHS()), - svalBuilder.makeIntVal(extentVal / constant), svalBuilder); - case BO_Add: - return getSimplifiedOffsets( - nonloc::SymbolVal(SIE->getLHS()), - svalBuilder.makeIntVal(extentVal - constant), svalBuilder); - default: - break; - } - } - } - - return std::pair(offset, extent); -} - -static bool isNegative(SValBuilder &SVB, ProgramStateRef State, NonLoc Value) { - const llvm::APSInt *MaxV = SVB.getMaxValue(State, Value); - return MaxV && MaxV->isNegative(); -} - -static bool isUnsigned(SValBuilder &SVB, NonLoc Value) { - QualType T = Value.getType(SVB.getContext()); - return T->isUnsignedIntegerType(); -} - -// Evaluate the comparison Value < Threshold with the help of the custom -// simplification algorithm defined for this checker. Return a pair of states, -// where the first one corresponds to "value below threshold" and the second -// corresponds to "value at or above threshold". Returns {nullptr, nullptr} in -// the case when the evaluation fails. -// If the optional argument CheckEquality is true, then use BO_EQ instead of -// the default BO_LT after consistently applying the same simplification steps. -static std::pair -compareValueToThreshold(ProgramStateRef State, NonLoc Value, NonLoc Threshold, - SValBuilder &SVB, bool CheckEquality = false) { - if (auto ConcreteThreshold = Threshold.getAs()) { - std::tie(Value, Threshold) = getSimplifiedOffsets(Value, *ConcreteThreshold, SVB); - } - - // We want to perform a _mathematical_ comparison between the numbers `Value` - // and `Threshold`; but `evalBinOpNN` evaluates a C/C++ operator that may - // perform automatic conversions. For example the number -1 is less than the - // number 1000, but -1 < `1000ull` will evaluate to `false` because the `int` - // -1 is converted to ULONGLONG_MAX. - // To avoid automatic conversions, we evaluate the "obvious" cases without - // calling `evalBinOpNN`: - if (isNegative(SVB, State, Value) && isUnsigned(SVB, Threshold)) { - if (CheckEquality) { - // negative_value == unsigned_threshold is always false - return {nullptr, State}; - } - // negative_value < unsigned_threshold is always true - return {State, nullptr}; - } - if (isUnsigned(SVB, Value) && isNegative(SVB, State, Threshold)) { - // unsigned_value == negative_threshold and - // unsigned_value < negative_threshold are both always false - return {nullptr, State}; - } - // FIXME: These special cases are sufficient for handling real-world - // comparisons, but in theory there could be contrived situations where - // automatic conversion of a symbolic value (which can be negative and can be - // positive) leads to incorrect results. - // NOTE: We NEED to use the `evalBinOpNN` call in the "common" case, because - // we want to ensure that assumptions coming from this precondition and - // assumptions coming from regular C/C++ operator calls are represented by - // constraints on the same symbolic expression. A solution that would - // evaluate these "mathematical" compariosns through a separate pathway would - // be a step backwards in this sense. - - const BinaryOperatorKind OpKind = CheckEquality ? BO_EQ : BO_LT; - auto BelowThreshold = - SVB.evalBinOpNN(State, OpKind, Value, Threshold, SVB.getConditionType()) - .getAs(); - - if (BelowThreshold) - return State->assume(*BelowThreshold); - - return {nullptr, nullptr}; -} - -static std::string getRegionName(const SubRegion *Region) { - if (std::string RegName = Region->getDescriptiveName(); !RegName.empty()) - return RegName; - - // Field regions only have descriptive names when their parent has a - // descriptive name; so we provide a fallback representation for them: - if (const auto *FR = Region->getAs()) { - if (StringRef Name = FR->getDecl()->getName(); !Name.empty()) - return formatv("the field '{0}'", Name); - return "the unnamed field"; - } - - if (isa(Region)) - return "the memory returned by 'alloca'"; - - if (isa(Region) && - isa(Region->getMemorySpace())) - return "the heap area"; - - if (isa(Region)) - return "the string literal"; - - return "the region"; -} - -static std::optional getConcreteValue(NonLoc SV) { - if (auto ConcreteVal = SV.getAs()) { - return ConcreteVal->getValue()->tryExtValue(); - } - return std::nullopt; -} - -static std::optional getConcreteValue(std::optional SV) { - return SV ? getConcreteValue(*SV) : std::nullopt; -} - -static Messages getPrecedesMsgs(const SubRegion *Region, NonLoc Offset) { - std::string RegName = getRegionName(Region), OffsetStr = ""; - - if (auto ConcreteOffset = getConcreteValue(Offset)) - OffsetStr = formatv(" {0}", ConcreteOffset); - - return { - formatv("Out of bound access to memory preceding {0}", RegName), - formatv("Access of {0} at negative byte offset{1}", RegName, OffsetStr)}; -} - -/// Try to divide `Val1` and `Val2` (in place) by `Divisor` and return true if -/// it can be performed (`Divisor` is nonzero and there is no remainder). The -/// values `Val1` and `Val2` may be nullopt and in that case the corresponding -/// division is considered to be successful. -static bool tryDividePair(std::optional &Val1, - std::optional &Val2, int64_t Divisor) { - if (!Divisor) - return false; - const bool Val1HasRemainder = Val1 && *Val1 % Divisor; - const bool Val2HasRemainder = Val2 && *Val2 % Divisor; - if (!Val1HasRemainder && !Val2HasRemainder) { - if (Val1) - *Val1 /= Divisor; - if (Val2) - *Val2 /= Divisor; - return true; - } - return false; -} - -static Messages getExceedsMsgs(ASTContext &ACtx, const SubRegion *Region, - NonLoc Offset, NonLoc Extent, SVal Location, - bool AlsoMentionUnderflow) { - std::string RegName = getRegionName(Region); - const auto *EReg = Location.getAsRegion()->getAs(); - assert(EReg && "this checker only handles element access"); - QualType ElemType = EReg->getElementType(); - - std::optional OffsetN = getConcreteValue(Offset); - std::optional ExtentN = getConcreteValue(Extent); - - int64_t ElemSize = ACtx.getTypeSizeInChars(ElemType).getQuantity(); - - bool UseByteOffsets = !tryDividePair(OffsetN, ExtentN, ElemSize); - const char *OffsetOrIndex = UseByteOffsets ? "byte offset" : "index"; - - SmallString<256> Buf; - llvm::raw_svector_ostream Out(Buf); - Out << "Access of "; - if (!ExtentN && !UseByteOffsets) - Out << "'" << ElemType.getAsString() << "' element in "; - Out << RegName << " at "; - if (AlsoMentionUnderflow) { - Out << "a negative or overflowing " << OffsetOrIndex; - } else if (OffsetN) { - Out << OffsetOrIndex << " " << *OffsetN; - } else { - Out << "an overflowing " << OffsetOrIndex; - } - if (ExtentN) { - Out << ", while it holds only "; - if (*ExtentN != 1) - Out << *ExtentN; - else - Out << "a single"; - if (UseByteOffsets) - Out << " byte"; - else - Out << " '" << ElemType.getAsString() << "' element"; - - if (*ExtentN > 1) - Out << "s"; - } - - return {formatv("Out of bound access to memory {0} {1}", - AlsoMentionUnderflow ? "around" : "after the end of", - RegName), - std::string(Buf)}; -} - -static Messages getTaintMsgs(const SubRegion *Region, const char *OffsetName, - bool AlsoMentionUnderflow) { - std::string RegName = getRegionName(Region); - return {formatv("Potential out of bound access to {0} with tainted {1}", - RegName, OffsetName), - formatv("Access of {0} with a tainted {1} that may be {2}too large", - RegName, OffsetName, - AlsoMentionUnderflow ? "negative or " : "")}; -} - -const NoteTag *StateUpdateReporter::createNoteTag(CheckerContext &C) const { - // Don't create a note tag if we didn't assume anything: - if (!AssumedNonNegative && !AssumedUpperBound) - return nullptr; - - return C.getNoteTag([*this](PathSensitiveBugReport &BR) -> std::string { - return getMessage(BR); - }); -} - -std::string StateUpdateReporter::getMessage(PathSensitiveBugReport &BR) const { - bool ShouldReportNonNegative = AssumedNonNegative; - if (!providesInformationAboutInteresting(ByteOffsetVal, BR)) { - if (AssumedUpperBound && - providesInformationAboutInteresting(*AssumedUpperBound, BR)) { - // Even if the byte offset isn't interesting (e.g. it's a constant value), - // the assumption can still be interesting if it provides information - // about an interesting symbolic upper bound. - ShouldReportNonNegative = false; - } else { - // We don't have anything interesting, don't report the assumption. - return ""; - } - } - - std::optional OffsetN = getConcreteValue(ByteOffsetVal); - std::optional ExtentN = getConcreteValue(AssumedUpperBound); - - const bool UseIndex = - ElementSize && tryDividePair(OffsetN, ExtentN, *ElementSize); - - SmallString<256> Buf; - llvm::raw_svector_ostream Out(Buf); - Out << "Assuming "; - if (UseIndex) { - Out << "index "; - if (OffsetN) - Out << "'" << OffsetN << "' "; - } else if (AssumedUpperBound) { - Out << "byte offset "; - if (OffsetN) - Out << "'" << OffsetN << "' "; - } else { - Out << "offset "; - } - - Out << "is"; - if (ShouldReportNonNegative) { - Out << " non-negative"; - } - if (AssumedUpperBound) { - if (ShouldReportNonNegative) - Out << " and"; - Out << " less than "; - if (ExtentN) - Out << *ExtentN << ", "; - if (UseIndex && ElementType) - Out << "the number of '" << ElementType->getAsString() - << "' elements in "; - else - Out << "the extent of "; - Out << getRegionName(Reg); - } - return std::string(Out.str()); -} - -bool StateUpdateReporter::providesInformationAboutInteresting( - SymbolRef Sym, PathSensitiveBugReport &BR) { - if (!Sym) - return false; - for (SymbolRef PartSym : Sym->symbols()) { - // The interestingess mark may appear on any layer as we're stripping off - // the SymIntExpr, UnarySymExpr etc. layers... - if (BR.isInteresting(PartSym)) - return true; - // ...but if both sides of the expression are symbolic, then there is no - // practical algorithm to produce separate constraints for the two - // operands (from the single combined result). - if (isa(PartSym)) - return false; - } - return false; -} - -void ArrayBoundCheckerV2::performCheck(const Expr *E, CheckerContext &C) const { - const SVal Location = C.getSVal(E); - - // The header ctype.h (from e.g. glibc) implements the isXXXXX() macros as - // #define isXXXXX(arg) (LOOKUP_TABLE[arg] & BITMASK_FOR_XXXXX) - // and incomplete analysis of these leads to false positives. As even - // accurate reports would be confusing for the users, just disable reports - // from these macros: - if (isFromCtypeMacro(E, C.getASTContext())) - return; - - ProgramStateRef State = C.getState(); - SValBuilder &SVB = C.getSValBuilder(); - - const std::optional> &RawOffset = - computeOffset(State, SVB, Location); - - if (!RawOffset) - return; - - auto [Reg, ByteOffset] = *RawOffset; - - // The state updates will be reported as a single note tag, which will be - // composed by this helper class. - StateUpdateReporter SUR(Reg, ByteOffset, E, C); - - // CHECK LOWER BOUND - const MemSpaceRegion *Space = Reg->getMemorySpace(); - if (!(isa(Reg) && isa(Space))) { - // A symbolic region in unknown space represents an unknown pointer that - // may point into the middle of an array, so we don't look for underflows. - // Both conditions are significant because we want to check underflows in - // symbolic regions on the heap (which may be introduced by checkers like - // MallocChecker that call SValBuilder::getConjuredHeapSymbolVal()) and - // non-symbolic regions (e.g. a field subregion of a symbolic region) in - // unknown space. - auto [PrecedesLowerBound, WithinLowerBound] = compareValueToThreshold( - State, ByteOffset, SVB.makeZeroArrayIndex(), SVB); - - if (PrecedesLowerBound) { - // The offset may be invalid (negative)... - if (!WithinLowerBound) { - // ...and it cannot be valid (>= 0), so report an error. - Messages Msgs = getPrecedesMsgs(Reg, ByteOffset); - reportOOB(C, PrecedesLowerBound, Msgs, ByteOffset, std::nullopt); - return; - } - // ...but it can be valid as well, so the checker will (optimistically) - // assume that it's valid and mention this in the note tag. - SUR.recordNonNegativeAssumption(); - } - - // Actually update the state. The "if" only fails in the extremely unlikely - // case when compareValueToThreshold returns {nullptr, nullptr} becasue - // evalBinOpNN fails to evaluate the less-than operator. - if (WithinLowerBound) - State = WithinLowerBound; - } - - // CHECK UPPER BOUND - DefinedOrUnknownSVal Size = getDynamicExtent(State, Reg, SVB); - if (auto KnownSize = Size.getAs()) { - // In a situation where both underflow and overflow are possible (but the - // index is either tainted or known to be invalid), the logic of this - // checker will first assume that the offset is non-negative, and then - // (with this additional assumption) it will detect an overflow error. - // In this situation the warning message should mention both possibilities. - bool AlsoMentionUnderflow = SUR.assumedNonNegative(); - - auto [WithinUpperBound, ExceedsUpperBound] = - compareValueToThreshold(State, ByteOffset, *KnownSize, SVB); - - if (ExceedsUpperBound) { - // The offset may be invalid (>= Size)... - if (!WithinUpperBound) { - // ...and it cannot be within bounds, so report an error, unless we can - // definitely determine that this is an idiomatic `&array[size]` - // expression that calculates the past-the-end pointer. - if (isIdiomaticPastTheEndPtr(E, ExceedsUpperBound, ByteOffset, - *KnownSize, C)) { - C.addTransition(ExceedsUpperBound, SUR.createNoteTag(C)); - return; - } - - Messages Msgs = - getExceedsMsgs(C.getASTContext(), Reg, ByteOffset, *KnownSize, - Location, AlsoMentionUnderflow); - reportOOB(C, ExceedsUpperBound, Msgs, ByteOffset, KnownSize); - return; - } - // ...and it can be valid as well... - if (isTainted(State, ByteOffset)) { - // ...but it's tainted, so report an error. - - // Diagnostic detail: saying "tainted offset" is always correct, but - // the common case is that 'idx' is tainted in 'arr[idx]' and then it's - // nicer to say "tainted index". - const char *OffsetName = "offset"; - if (const auto *ASE = dyn_cast(E)) - if (isTainted(State, ASE->getIdx(), C.getLocationContext())) - OffsetName = "index"; - - Messages Msgs = getTaintMsgs(Reg, OffsetName, AlsoMentionUnderflow); - reportOOB(C, ExceedsUpperBound, Msgs, ByteOffset, KnownSize, - /*IsTaintBug=*/true); - return; - } - // ...and it isn't tainted, so the checker will (optimistically) assume - // that the offset is in bounds and mention this in the note tag. - SUR.recordUpperBoundAssumption(*KnownSize); - } - - // Actually update the state. The "if" only fails in the extremely unlikely - // case when compareValueToThreshold returns {nullptr, nullptr} becasue - // evalBinOpNN fails to evaluate the less-than operator. - if (WithinUpperBound) - State = WithinUpperBound; - } - - // Add a transition, reporting the state updates that we accumulated. - C.addTransition(State, SUR.createNoteTag(C)); -} - -void ArrayBoundCheckerV2::markPartsInteresting(PathSensitiveBugReport &BR, - ProgramStateRef ErrorState, - NonLoc Val, bool MarkTaint) { - if (SymbolRef Sym = Val.getAsSymbol()) { - // If the offset is a symbolic value, iterate over its "parts" with - // `SymExpr::symbols()` and mark each of them as interesting. - // For example, if the offset is `x*4 + y` then we put interestingness onto - // the SymSymExpr `x*4 + y`, the SymIntExpr `x*4` and the two data symbols - // `x` and `y`. - for (SymbolRef PartSym : Sym->symbols()) - BR.markInteresting(PartSym); - } - - if (MarkTaint) { - // If the issue that we're reporting depends on the taintedness of the - // offset, then put interestingness onto symbols that could be the origin - // of the taint. Note that this may find symbols that did not appear in - // `Sym->symbols()` (because they're only loosely connected to `Val`). - for (SymbolRef Sym : getTaintedSymbols(ErrorState, Val)) - BR.markInteresting(Sym); - } -} - -void ArrayBoundCheckerV2::reportOOB(CheckerContext &C, - ProgramStateRef ErrorState, Messages Msgs, - NonLoc Offset, std::optional Extent, - bool IsTaintBug /*=false*/) const { - - ExplodedNode *ErrorNode = C.generateErrorNode(ErrorState); - if (!ErrorNode) - return; - - auto BR = std::make_unique( - IsTaintBug ? TaintBT : BT, Msgs.Short, Msgs.Full, ErrorNode); - - // FIXME: ideally we would just call trackExpressionValue() and that would - // "do the right thing": mark the relevant symbols as interesting, track the - // control dependencies and statements storing the relevant values and add - // helpful diagnostic pieces. However, right now trackExpressionValue() is - // a heap of unreliable heuristics, so it would cause several issues: - // - Interestingness is not applied consistently, e.g. if `array[x+10]` - // causes an overflow, then `x` is not marked as interesting. - // - We get irrelevant diagnostic pieces, e.g. in the code - // `int *p = (int*)malloc(2*sizeof(int)); p[3] = 0;` - // it places a "Storing uninitialized value" note on the `malloc` call - // (which is technically true, but irrelevant). - // If trackExpressionValue() becomes reliable, it should be applied instead - // of this custom markPartsInteresting(). - markPartsInteresting(*BR, ErrorState, Offset, IsTaintBug); - if (Extent) - markPartsInteresting(*BR, ErrorState, *Extent, IsTaintBug); - - C.emitReport(std::move(BR)); -} - -bool ArrayBoundCheckerV2::isFromCtypeMacro(const Stmt *S, ASTContext &ACtx) { - SourceLocation Loc = S->getBeginLoc(); - if (!Loc.isMacroID()) - return false; - - StringRef MacroName = Lexer::getImmediateMacroName( - Loc, ACtx.getSourceManager(), ACtx.getLangOpts()); - - if (MacroName.size() < 7 || MacroName[0] != 'i' || MacroName[1] != 's') - return false; - - return ((MacroName == "isalnum") || (MacroName == "isalpha") || - (MacroName == "isblank") || (MacroName == "isdigit") || - (MacroName == "isgraph") || (MacroName == "islower") || - (MacroName == "isnctrl") || (MacroName == "isprint") || - (MacroName == "ispunct") || (MacroName == "isspace") || - (MacroName == "isupper") || (MacroName == "isxdigit")); -} - -bool ArrayBoundCheckerV2::isInAddressOf(const Stmt *S, ASTContext &ACtx) { - ParentMapContext &ParentCtx = ACtx.getParentMapContext(); - do { - const DynTypedNodeList Parents = ParentCtx.getParents(*S); - if (Parents.empty()) - return false; - S = Parents[0].get(); - } while (isa_and_nonnull(S)); - const auto *UnaryOp = dyn_cast_or_null(S); - return UnaryOp && UnaryOp->getOpcode() == UO_AddrOf; -} - -bool ArrayBoundCheckerV2::isIdiomaticPastTheEndPtr(const Expr *E, - ProgramStateRef State, - NonLoc Offset, NonLoc Limit, - CheckerContext &C) { - if (isa(E) && isInAddressOf(E, C.getASTContext())) { - auto [EqualsToThreshold, NotEqualToThreshold] = compareValueToThreshold( - State, Offset, Limit, C.getSValBuilder(), /*CheckEquality=*/true); - return EqualsToThreshold && !NotEqualToThreshold; - } - return false; -} - -void ento::registerArrayBoundCheckerV2(CheckerManager &mgr) { - mgr.registerChecker(); -} - -bool ento::shouldRegisterArrayBoundCheckerV2(const CheckerManager &mgr) { - return true; -} diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index fcbe8b864b6e4..5910043440987 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -8,7 +8,6 @@ add_clang_library(clangStaticAnalyzerCheckers AnalysisOrderChecker.cpp AnalyzerStatsChecker.cpp ArrayBoundChecker.cpp - ArrayBoundCheckerV2.cpp BasicObjCFoundationChecks.cpp BitwiseShiftChecker.cpp BlockInCriticalSectionChecker.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 1a14f38e34f0e..39dcaf02dbe25 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -547,8 +547,10 @@ ProgramStateRef CStringChecker::checkInit(CheckerContext &C, } return State; } - -// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor? +// FIXME: The root of this logic was copied from the old checker +// alpha.security.ArrayBound (which is removed within this commit). +// It should be refactored to use the different, more sophisticated bounds +// checking logic used by the new checker ``security.ArrayBound``. ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C, ProgramStateRef state, AnyArgExpr Buffer, SVal Element, diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp index 5534ef86a7bef..28898bb370823 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp @@ -227,10 +227,11 @@ void ExprInspectionChecker::analyzerWarnIfReached(const CallExpr *CE, void ExprInspectionChecker::analyzerNumTimesReached(const CallExpr *CE, CheckerContext &C) const { - ++ReachedStats[CE].NumTimesReached; - if (!ReachedStats[CE].ExampleNode) { + ReachedStat &Stat = ReachedStats[CE]; + ++Stat.NumTimesReached; + if (!Stat.ExampleNode) { // Later, in checkEndAnalysis, we'd throw a report against it. - ReachedStats[CE].ExampleNode = C.generateNonFatalErrorNode(); + Stat.ExampleNode = C.generateNonFatalErrorNode(); } } diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp index f4de3b500499c..c9df15ceb3b40 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp @@ -54,8 +54,8 @@ class StackAddrEscapeChecker CheckerContext &C) const; void checkAsyncExecutedBlockCaptures(const BlockDataRegion &B, CheckerContext &C) const; - void EmitStackError(CheckerContext &C, const MemRegion *R, - const Expr *RetE) const; + void EmitReturnLeakError(CheckerContext &C, const MemRegion *LeakedRegion, + const Expr *RetE) const; bool isSemaphoreCaptured(const BlockDecl &B) const; static SourceRange genName(raw_ostream &os, const MemRegion *R, ASTContext &Ctx); @@ -147,9 +147,22 @@ StackAddrEscapeChecker::getCapturedStackRegions(const BlockDataRegion &B, return Regions; } -void StackAddrEscapeChecker::EmitStackError(CheckerContext &C, - const MemRegion *R, - const Expr *RetE) const { +static void EmitReturnedAsPartOfError(llvm::raw_ostream &OS, SVal ReturnedVal, + const MemRegion *LeakedRegion) { + if (const MemRegion *ReturnedRegion = ReturnedVal.getAsRegion()) { + if (isa(ReturnedRegion)) { + OS << " is captured by a returned block"; + return; + } + } + + // Generic message + OS << " returned to caller"; +} + +void StackAddrEscapeChecker::EmitReturnLeakError(CheckerContext &C, + const MemRegion *R, + const Expr *RetE) const { ExplodedNode *N = C.generateNonFatalErrorNode(); if (!N) return; @@ -157,11 +170,15 @@ void StackAddrEscapeChecker::EmitStackError(CheckerContext &C, BT_returnstack = std::make_unique( CheckNames[CK_StackAddrEscapeChecker], "Return of address to stack-allocated memory"); + // Generate a report for this bug. SmallString<128> buf; llvm::raw_svector_ostream os(buf); + + // Error message formatting SourceRange range = genName(os, R, C.getASTContext()); - os << " returned to caller"; + EmitReturnedAsPartOfError(os, C.getSVal(RetE), R); + auto report = std::make_unique(*BT_returnstack, os.str(), N); report->addRange(RetE->getSourceRange()); @@ -209,30 +226,6 @@ void StackAddrEscapeChecker::checkAsyncExecutedBlockCaptures( } } -void StackAddrEscapeChecker::checkReturnedBlockCaptures( - const BlockDataRegion &B, CheckerContext &C) const { - for (const MemRegion *Region : getCapturedStackRegions(B, C)) { - if (isNotInCurrentFrame(Region, C)) - continue; - ExplodedNode *N = C.generateNonFatalErrorNode(); - if (!N) - continue; - if (!BT_capturedstackret) - BT_capturedstackret = std::make_unique( - CheckNames[CK_StackAddrEscapeChecker], - "Address of stack-allocated memory is captured"); - SmallString<128> Buf; - llvm::raw_svector_ostream Out(Buf); - SourceRange Range = genName(Out, Region, C.getASTContext()); - Out << " is captured by a returned block"; - auto Report = std::make_unique(*BT_capturedstackret, - Out.str(), N); - if (Range.isValid()) - Report->addRange(Range); - C.emitReport(std::move(Report)); - } -} - void StackAddrEscapeChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const { if (!ChecksEnabled[CK_StackAddrAsyncEscapeChecker]) @@ -247,45 +240,128 @@ void StackAddrEscapeChecker::checkPreCall(const CallEvent &Call, } } -void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS, - CheckerContext &C) const { - if (!ChecksEnabled[CK_StackAddrEscapeChecker]) - return; +/// A visitor made for use with a ScanReachableSymbols scanner, used +/// for finding stack regions within an SVal that live on the current +/// stack frame of the given checker context. This visitor excludes +/// NonParamVarRegion that data is bound to in a BlockDataRegion's +/// bindings, since these are likely uninteresting, e.g., in case a +/// temporary is constructed on the stack, but it captures values +/// that would leak. +class FindStackRegionsSymbolVisitor final : public SymbolVisitor { + CheckerContext &Ctxt; + const StackFrameContext *PoppedStackFrame; + SmallVectorImpl &EscapingStackRegions; - const Expr *RetE = RS->getRetValue(); - if (!RetE) - return; - RetE = RetE->IgnoreParens(); +public: + explicit FindStackRegionsSymbolVisitor( + CheckerContext &Ctxt, + SmallVectorImpl &StorageForStackRegions) + : Ctxt(Ctxt), PoppedStackFrame(Ctxt.getStackFrame()), + EscapingStackRegions(StorageForStackRegions) {} - SVal V = C.getSVal(RetE); - const MemRegion *R = V.getAsRegion(); - if (!R) - return; + bool VisitSymbol(SymbolRef sym) override { return true; } - if (const BlockDataRegion *B = dyn_cast(R)) - checkReturnedBlockCaptures(*B, C); + bool VisitMemRegion(const MemRegion *MR) override { + SaveIfEscapes(MR); - if (!isa(R->getMemorySpace()) || isNotInCurrentFrame(R, C)) - return; + if (const BlockDataRegion *BDR = MR->getAs()) + return VisitBlockDataRegionCaptures(BDR); + + return true; + } + +private: + void SaveIfEscapes(const MemRegion *MR) { + const StackSpaceRegion *SSR = + MR->getMemorySpace()->getAs(); + if (SSR && SSR->getStackFrame() == PoppedStackFrame) + EscapingStackRegions.push_back(MR); + } + + bool VisitBlockDataRegionCaptures(const BlockDataRegion *BDR) { + for (auto Var : BDR->referenced_vars()) { + SVal Val = Ctxt.getState()->getSVal(Var.getCapturedRegion()); + const MemRegion *Region = Val.getAsRegion(); + if (Region) { + SaveIfEscapes(Region); + VisitMemRegion(Region); + } + } + + return false; + } +}; + +/// Given some memory regions that are flagged by FindStackRegionsSymbolVisitor, +/// this function filters out memory regions that are being returned that are +/// likely not true leaks: +/// 1. If returning a block data region that has stack memory space +/// 2. If returning a constructed object that has stack memory space +static SmallVector FilterReturnExpressionLeaks( + const SmallVectorImpl &MaybeEscaped, CheckerContext &C, + const Expr *RetE, SVal &RetVal) { + + SmallVector WillEscape; + + const MemRegion *RetRegion = RetVal.getAsRegion(); // Returning a record by value is fine. (In this case, the returned // expression will be a copy-constructor, possibly wrapped in an // ExprWithCleanups node.) if (const ExprWithCleanups *Cleanup = dyn_cast(RetE)) RetE = Cleanup->getSubExpr(); - if (isa(RetE) && RetE->getType()->isRecordType()) - return; + bool IsConstructExpr = + isa(RetE) && RetE->getType()->isRecordType(); // The CK_CopyAndAutoreleaseBlockObject cast causes the block to be copied // so the stack address is not escaping here. + bool IsCopyAndAutoreleaseBlockObj = false; if (const auto *ICE = dyn_cast(RetE)) { - if (isa(R) && - ICE->getCastKind() == CK_CopyAndAutoreleaseBlockObject) { - return; - } + IsCopyAndAutoreleaseBlockObj = + isa_and_nonnull(RetRegion) && + ICE->getCastKind() == CK_CopyAndAutoreleaseBlockObject; + } + + for (const MemRegion *MR : MaybeEscaped) { + if (RetRegion == MR && (IsCopyAndAutoreleaseBlockObj || IsConstructExpr)) + continue; + + WillEscape.push_back(MR); } - EmitStackError(C, R, RetE); + return WillEscape; +} + +/// For use in finding regions that live on the checker context's current +/// stack frame, deep in the SVal representing the return value. +static SmallVector +FindEscapingStackRegions(CheckerContext &C, const Expr *RetE, SVal RetVal) { + SmallVector FoundStackRegions; + + FindStackRegionsSymbolVisitor Finder(C, FoundStackRegions); + ScanReachableSymbols Scanner(C.getState(), Finder); + Scanner.scan(RetVal); + + return FilterReturnExpressionLeaks(FoundStackRegions, C, RetE, RetVal); +} + +void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS, + CheckerContext &C) const { + if (!ChecksEnabled[CK_StackAddrEscapeChecker]) + return; + + const Expr *RetE = RS->getRetValue(); + if (!RetE) + return; + RetE = RetE->IgnoreParens(); + + SVal V = C.getSVal(RetE); + + SmallVector EscapedStackRegions = + FindEscapingStackRegions(C, RetE, V); + + for (const MemRegion *ER : EscapedStackRegions) + EmitReturnLeakError(C, ER, RetE); } static const MemSpaceRegion *getStackOrGlobalSpaceRegion(const MemRegion *R) { diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index abf5d3ec193a4..a12853d01819f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -154,19 +154,20 @@ bool isConstOwnerPtrMemberExpr(const clang::Expr *E) { if (auto *MCE = dyn_cast(E)) { if (auto *Callee = MCE->getDirectCallee()) { auto Name = safeGetName(Callee); - if (Name == "get" || Name == "ptr") { - auto *ThisArg = MCE->getImplicitObjectArgument(); - E = ThisArg; - } + if (Name == "get" || Name == "ptr") + E = MCE->getImplicitObjectArgument(); + if (isa(Callee)) + E = MCE->getImplicitObjectArgument(); } } else if (auto *OCE = dyn_cast(E)) { if (OCE->getOperator() == OO_Star && OCE->getNumArgs() == 1) E = OCE->getArg(0); } - auto *ME = dyn_cast(E); - if (!ME) - return false; - auto *D = ME->getMemberDecl(); + const ValueDecl *D = nullptr; + if (auto *ME = dyn_cast(E)) + D = ME->getMemberDecl(); + else if (auto *IVR = dyn_cast(E)) + D = IVR->getDecl(); if (!D) return false; auto T = D->getType(); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index 5487fea1b956c..d40b4b4dbb560 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -636,6 +636,11 @@ class TrivialFunctionAnalysisVisitor return true; } + bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *IVIE) { + // An implicit value initialization is trvial. + return true; + } + private: CacheTy &Cache; CacheTy RecursiveFn; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp index d7e5ebee9a9b4..79f88553feb95 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefMemberChecker.cpp @@ -48,7 +48,7 @@ class RawPtrRefMemberChecker // The calls to checkAST* from AnalysisConsumer don't // visit template instantiations or lambda classes. We // want to visit those, so we make our own RecursiveASTVisitor. - struct LocalVisitor : DynamicRecursiveASTVisitor { + struct LocalVisitor : ConstDynamicRecursiveASTVisitor { const RawPtrRefMemberChecker *Checker; explicit LocalVisitor(const RawPtrRefMemberChecker *Checker) : Checker(Checker) { @@ -57,14 +57,14 @@ class RawPtrRefMemberChecker ShouldVisitImplicitCode = false; } - bool VisitRecordDecl(RecordDecl *RD) override { + bool VisitRecordDecl(const RecordDecl *RD) override { Checker->visitRecordDecl(RD); return true; } }; LocalVisitor visitor(this); - visitor.TraverseDecl(const_cast(TUD)); + visitor.TraverseDecl(TUD); } void visitRecordDecl(const RecordDecl *RD) const { diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp index a57499d52acd0..a56f48c83c660 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp @@ -109,8 +109,8 @@ class UncountedLambdaCapturesChecker bool VisitCallExpr(CallExpr *CE) override { checkCalleeLambda(CE); if (auto *Callee = CE->getDirectCallee()) { + unsigned ArgIndex = isa(CE); bool TreatAllArgsAsNoEscape = shouldTreatAllArgAsNoEscape(Callee); - unsigned ArgIndex = 0; for (auto *Param : Callee->parameters()) { if (ArgIndex >= CE->getNumArgs()) return true; diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 2904eab0097dc..13677ed341d0c 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -62,6 +62,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -287,6 +288,33 @@ class PathDiagnosticBuilder : public BugReporterContext { const PathSensitiveBugReport *getBugReport() const { return R; } }; +std::string timeTraceName(const BugReportEquivClass &EQ) { + if (!llvm::timeTraceProfilerEnabled()) + return ""; + const auto &BugReports = EQ.getReports(); + if (BugReports.empty()) + return "Empty Equivalence Class"; + const BugReport *R = BugReports.front().get(); + const auto &BT = R->getBugType(); + return ("Flushing EQC " + BT.getDescription()).str(); +} + +llvm::TimeTraceMetadata timeTraceMetadata(const BugReportEquivClass &EQ, + const SourceManager &SM) { + // Must be called only when constructing non-bogus TimeTraceScope + assert(llvm::timeTraceProfilerEnabled()); + + const auto &BugReports = EQ.getReports(); + if (BugReports.empty()) + return {}; + const BugReport *R = BugReports.front().get(); + const auto &BT = R->getBugType(); + auto Loc = R->getLocation().asLocation(); + std::string File = SM.getFilename(Loc).str(); + return {BT.getCheckerName().str(), std::move(File), + static_cast(Loc.getLineNumber())}; +} + } // namespace //===----------------------------------------------------------------------===// @@ -2892,6 +2920,7 @@ std::optional PathDiagnosticBuilder::findValidReport( if (R->isValid()) { if (Reporter.getAnalyzerOptions().ShouldCrosscheckWithZ3) { + llvm::TimeTraceScope TCS{"Crosscheck with Z3"}; // If crosscheck is enabled, remove all visitors, add the refutation // visitor and check again R->clearVisitors(); @@ -3119,7 +3148,10 @@ BugReport *PathSensitiveBugReporter::findReportInEquivalenceClass( return exampleReport; } -void BugReporter::FlushReport(BugReportEquivClass& EQ) { +void BugReporter::FlushReport(BugReportEquivClass &EQ) { + llvm::TimeTraceScope TCS{timeTraceName(EQ), [&]() { + return timeTraceMetadata(EQ, getSourceManager()); + }}; SmallVector bugReports; BugReport *report = findReportInEquivalenceClass(EQ, bugReports); if (!report) diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index a9b4dbb39b5bd..a6142063895db 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1198,7 +1198,10 @@ static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR) { // If we ever directly evaluate global DeclStmts, this assertion will be // invalid, but this still seems preferable to silently accepting an // initialization that may be for a path-sensitive variable. - assert(VR->getDecl()->isStaticLocal() && "non-static stackless VarRegion"); + [[maybe_unused]] bool IsLocalStaticOrLocalExtern = + VR->getDecl()->isStaticLocal() || VR->getDecl()->isLocalExternDecl(); + assert(IsLocalStaticOrLocalExtern && + "Declared a variable on the stack without Stack memspace?"); return true; } diff --git a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp index 05c99c4a844e9..5b5f9df9cb0dc 100644 --- a/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugSuppression.cpp @@ -9,6 +9,8 @@ #include "clang/StaticAnalyzer/Core/BugReporter/BugSuppression.h" #include "clang/AST/DynamicRecursiveASTVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/TimeProfiler.h" using namespace clang; using namespace ento; @@ -119,6 +121,29 @@ class CacheInitializer : public DynamicRecursiveASTVisitor { Ranges &Result; }; +std::string timeScopeName(const Decl *DeclWithIssue) { + if (!llvm::timeTraceProfilerEnabled()) + return ""; + return llvm::formatv( + "BugSuppression::isSuppressed init suppressions cache for {0}", + DeclWithIssue->getDeclKindName()) + .str(); +} + +llvm::TimeTraceMetadata getDeclTimeTraceMetadata(const Decl *DeclWithIssue) { + assert(DeclWithIssue); + assert(llvm::timeTraceProfilerEnabled()); + std::string Name = ""; + if (const auto *ND = dyn_cast(DeclWithIssue)) { + Name = ND->getNameAsString(); + } + const auto &SM = DeclWithIssue->getASTContext().getSourceManager(); + auto Line = SM.getPresumedLineNumber(DeclWithIssue->getBeginLoc()); + auto Fname = SM.getFilename(DeclWithIssue->getBeginLoc()); + return llvm::TimeTraceMetadata{std::move(Name), Fname.str(), + static_cast(Line)}; +} + } // end anonymous namespace // TODO: Introduce stable IDs for checkers and check for those here @@ -177,6 +202,9 @@ bool BugSuppression::isSuppressed(const PathDiagnosticLocation &Location, std::make_pair(DeclWithIssue, CachedRanges{})); Ranges &SuppressionRanges = InsertionResult.first->second; if (InsertionResult.second) { + llvm::TimeTraceScope TimeScope( + timeScopeName(DeclWithIssue), + [DeclWithIssue]() { return getDeclTimeTraceMetadata(DeclWithIssue); }); // We haven't checked this declaration for suppressions yet! CacheInitializer::initialize(DeclWithIssue, SuppressionRanges); } diff --git a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp index 96464b30c078f..d0145293fa3e5 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerContext.cpp @@ -55,7 +55,7 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD, if (BId != 0) { if (Name.empty()) return true; - StringRef BName = FD->getASTContext().BuiltinInfo.getName(BId); + std::string BName = FD->getASTContext().BuiltinInfo.getName(BId); size_t start = BName.find(Name); if (start != StringRef::npos) { // Accept exact match. diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp index 9f7a0fcc2edb3..53929d370e2fe 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -27,6 +27,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/TimeProfiler.h" #include #include #include @@ -134,6 +135,14 @@ static void expandGraphWithCheckers(CHECK_CTX checkCtx, namespace { +std::string checkerScopeName(StringRef Name, const CheckerBase *Checker) { + if (!llvm::timeTraceProfilerEnabled()) + return ""; + StringRef CheckerName = + Checker ? Checker->getCheckerName().getName() : ""; + return (Name + ":" + CheckerName).str(); +} + struct CheckStmtContext { using CheckersTy = SmallVectorImpl; @@ -153,6 +162,7 @@ namespace { void runChecker(CheckerManager::CheckStmtFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope(checkerScopeName("Stmt", checkFn.Checker)); // FIXME: Remove respondsToCallback from CheckerContext; ProgramPoint::Kind K = IsPreVisit ? ProgramPoint::PreStmtKind : ProgramPoint::PostStmtKind; @@ -174,6 +184,9 @@ void CheckerManager::runCheckersForStmt(bool isPreVisit, bool WasInlined) { CheckStmtContext C(isPreVisit, getCachedStmtCheckersFor(S, isPreVisit), S, Eng, WasInlined); + llvm::TimeTraceScope TimeScope( + isPreVisit ? "CheckerManager::runCheckersForStmt (Pre)" + : "CheckerManager::runCheckersForStmt (Post)"); expandGraphWithCheckers(C, Dst, Src); } @@ -200,6 +213,8 @@ namespace { void runChecker(CheckerManager::CheckObjCMessageFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope( + checkerScopeName("ObjCMsg", checkFn.Checker)); bool IsPreVisit; switch (Kind) { @@ -230,6 +245,7 @@ void CheckerManager::runCheckersForObjCMessage(ObjCMessageVisitKind visitKind, bool WasInlined) { const auto &checkers = getObjCMessageCheckers(visitKind); CheckObjCMessageContext C(visitKind, checkers, msg, Eng, WasInlined); + llvm::TimeTraceScope TimeScope("CheckerManager::runCheckersForObjCMessage"); expandGraphWithCheckers(C, Dst, Src); } @@ -270,6 +286,7 @@ namespace { void runChecker(CheckerManager::CheckCallFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope(checkerScopeName("Call", checkFn.Checker)); const ProgramPoint &L = Call.getProgramPoint(IsPreVisit,checkFn.Checker); CheckerContext C(Bldr, Eng, Pred, L, WasInlined); @@ -290,6 +307,9 @@ void CheckerManager::runCheckersForCallEvent(bool isPreVisit, isPreVisit ? PreCallCheckers : PostCallCheckers, Call, Eng, WasInlined); + llvm::TimeTraceScope TimeScope( + isPreVisit ? "CheckerManager::runCheckersForCallEvent (Pre)" + : "CheckerManager::runCheckersForCallEvent (Post)"); expandGraphWithCheckers(C, Dst, Src); } @@ -317,6 +337,7 @@ namespace { void runChecker(CheckerManager::CheckLocationFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope(checkerScopeName("Loc", checkFn.Checker)); ProgramPoint::Kind K = IsLoad ? ProgramPoint::PreLoadKind : ProgramPoint::PreStoreKind; const ProgramPoint &L = @@ -340,6 +361,9 @@ void CheckerManager::runCheckersForLocation(ExplodedNodeSet &Dst, ExprEngine &Eng) { CheckLocationContext C(LocationCheckers, location, isLoad, NodeEx, BoundEx, Eng); + llvm::TimeTraceScope TimeScope( + isLoad ? "CheckerManager::runCheckersForLocation (Load)" + : "CheckerManager::runCheckersForLocation (Store)"); expandGraphWithCheckers(C, Dst, Src); } @@ -365,6 +389,7 @@ namespace { void runChecker(CheckerManager::CheckBindFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope(checkerScopeName("Bind", checkFn.Checker)); const ProgramPoint &L = PP.withTag(checkFn.Checker); CheckerContext C(Bldr, Eng, Pred, L); @@ -372,6 +397,14 @@ namespace { } }; + llvm::TimeTraceMetadata getTimeTraceBindMetadata(SVal Val) { + assert(llvm::timeTraceProfilerEnabled()); + std::string Name; + llvm::raw_string_ostream OS(Name); + Val.dumpToStream(OS); + return llvm::TimeTraceMetadata{OS.str(), ""}; + } + } // namespace /// Run checkers for binding of a value to a location. @@ -381,6 +414,9 @@ void CheckerManager::runCheckersForBind(ExplodedNodeSet &Dst, const Stmt *S, ExprEngine &Eng, const ProgramPoint &PP) { CheckBindContext C(BindCheckers, location, val, S, Eng, PP); + llvm::TimeTraceScope TimeScope{ + "CheckerManager::runCheckersForBind", + [&val]() { return getTimeTraceBindMetadata(val); }}; expandGraphWithCheckers(C, Dst, Src); } @@ -409,6 +445,7 @@ struct CheckBeginFunctionContext { void runChecker(CheckerManager::CheckBeginFunctionFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope(checkerScopeName("Begin", checkFn.Checker)); const ProgramPoint &L = PP.withTag(checkFn.Checker); CheckerContext C(Bldr, Eng, Pred, L); @@ -425,6 +462,7 @@ void CheckerManager::runCheckersForBeginFunction(ExplodedNodeSet &Dst, ExplodedNodeSet Src; Src.insert(Pred); CheckBeginFunctionContext C(BeginFunctionCheckers, Eng, L); + llvm::TimeTraceScope TimeScope("CheckerManager::runCheckersForBeginFunction"); expandGraphWithCheckers(C, Dst, Src); } @@ -444,6 +482,7 @@ void CheckerManager::runCheckersForEndFunction(NodeBuilderContext &BC, const ProgramPoint &L = FunctionExitPoint(RS, Pred->getLocationContext(), checkFn.Checker); CheckerContext C(Bldr, Eng, Pred, L); + llvm::TimeTraceScope TimeScope(checkerScopeName("End", checkFn.Checker)); checkFn(RS, C); } } @@ -466,6 +505,8 @@ namespace { void runChecker(CheckerManager::CheckBranchConditionFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope( + checkerScopeName("BranchCond", checkFn.Checker)); ProgramPoint L = PostCondition(Condition, Pred->getLocationContext(), checkFn.Checker); CheckerContext C(Bldr, Eng, Pred, L); @@ -483,6 +524,8 @@ void CheckerManager::runCheckersForBranchCondition(const Stmt *Condition, ExplodedNodeSet Src; Src.insert(Pred); CheckBranchConditionContext C(BranchConditionCheckers, Condition, Eng); + llvm::TimeTraceScope TimeScope( + "CheckerManager::runCheckersForBranchCondition"); expandGraphWithCheckers(C, Dst, Src); } @@ -506,6 +549,8 @@ namespace { void runChecker(CheckerManager::CheckNewAllocatorFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope( + checkerScopeName("Allocator", checkFn.Checker)); ProgramPoint L = PostAllocatorCall(Call.getOriginExpr(), Pred->getLocationContext()); CheckerContext C(Bldr, Eng, Pred, L, WasInlined); @@ -524,6 +569,7 @@ void CheckerManager::runCheckersForNewAllocator(const CXXAllocatorCall &Call, ExplodedNodeSet Src; Src.insert(Pred); CheckNewAllocatorContext C(NewAllocatorCheckers, Call, WasInlined, Eng); + llvm::TimeTraceScope TimeScope("CheckerManager::runCheckersForNewAllocator"); expandGraphWithCheckers(C, Dst, Src); } @@ -555,6 +601,8 @@ namespace { void runChecker(CheckerManager::CheckDeadSymbolsFunc checkFn, NodeBuilder &Bldr, ExplodedNode *Pred) { + llvm::TimeTraceScope TimeScope( + checkerScopeName("DeadSymbols", checkFn.Checker)); const ProgramPoint &L = ProgramPoint::getProgramPoint(S, ProgarmPointKind, Pred->getLocationContext(), checkFn.Checker); CheckerContext C(Bldr, Eng, Pred, L); @@ -576,6 +624,7 @@ void CheckerManager::runCheckersForDeadSymbols(ExplodedNodeSet &Dst, ExprEngine &Eng, ProgramPoint::Kind K) { CheckDeadSymbolsContext C(DeadSymbolsCheckers, SymReaper, S, Eng, K); + llvm::TimeTraceScope TimeScope("CheckerManager::runCheckersForDeadSymbols"); expandGraphWithCheckers(C, Dst, Src); } diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 775a22e18c619..bf1fd7c2356dc 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -30,6 +30,8 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/TimeProfiler.h" #include #include #include @@ -179,8 +181,41 @@ bool CoreEngine::ExecuteWorkList(const LocationContext *L, unsigned MaxSteps, return WList->hasWork(); } -void CoreEngine::dispatchWorkItem(ExplodedNode* Pred, ProgramPoint Loc, - const WorkListUnit& WU) { +static std::string timeTraceScopeName(const ProgramPoint &Loc) { + if (llvm::timeTraceProfilerEnabled()) { + return llvm::formatv("Loc {0}", + ProgramPoint::getProgramPointKindName(Loc.getKind())) + .str(); + } + return ""; +} + +static llvm::TimeTraceMetadata timeTraceMetadata(const ExplodedNode *Pred, + const ProgramPoint &Loc) { + // If time-trace profiler is not enabled, this function is never called. + assert(llvm::timeTraceProfilerEnabled()); + std::string Detail = ""; + if (const auto SP = Loc.getAs()) { + if (const Stmt *S = SP->getStmt()) + Detail = S->getStmtClassName(); + } + auto SLoc = Loc.getSourceLocation(); + if (!SLoc) + return llvm::TimeTraceMetadata{Detail, ""}; + const auto &SM = Pred->getLocationContext() + ->getAnalysisDeclContext() + ->getASTContext() + .getSourceManager(); + auto Line = SM.getPresumedLineNumber(*SLoc); + auto Fname = SM.getFilename(*SLoc); + return llvm::TimeTraceMetadata{Detail, Fname.str(), static_cast(Line)}; +} + +void CoreEngine::dispatchWorkItem(ExplodedNode *Pred, ProgramPoint Loc, + const WorkListUnit &WU) { + llvm::TimeTraceScope tcs{timeTraceScopeName(Loc), [Loc, Pred]() { + return timeTraceMetadata(Pred, Loc); + }}; // Dispatch on the location type. switch (Loc.getKind()) { case ProgramPoint::BlockEdgeKind: diff --git a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp index 55bcb6e220e1e..7b2cccce93cfe 100644 --- a/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -488,15 +488,17 @@ ExplodedGraph::trim(ArrayRef Sinks, while (!WL2.empty()) { const ExplodedNode *N = WL2.pop_back_val(); + auto [Place, Inserted] = Pass2.try_emplace(N); + // Skip this node if we have already processed it. - if (Pass2.contains(N)) + if (!Inserted) continue; // Create the corresponding node in the new graph and record the mapping // from the old node to the new node. ExplodedNode *NewN = G->createUncachedNode(N->getLocation(), N->State, N->getID(), N->isSink()); - Pass2[N] = NewN; + Place->second = NewN; // Also record the reverse mapping from the new node to the old node. if (InverseMap) (*InverseMap)[NewN] = N; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 140c77790496d..e3ec7c57571c8 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -74,6 +74,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/SaveAndRestore.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -1031,6 +1032,7 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out, const LocationContext *LC, const Stmt *DiagnosticStmt, ProgramPoint::Kind K) { + llvm::TimeTraceScope TimeScope("ExprEngine::removeDead"); assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind || ReferenceStmt == nullptr || isa(ReferenceStmt)) && "PostStmt is not generally supported by the SymbolReaper yet"); @@ -1743,6 +1745,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::DependentCoawaitExprClass: case Stmt::CoreturnStmtClass: case Stmt::CoyieldExprClass: + case Stmt::ResolvedUnexpandedPackExprClass: case Stmt::SEHTryStmtClass: case Stmt::SEHExceptStmtClass: case Stmt::SEHLeaveStmtClass: @@ -1835,6 +1838,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OpenACCShutdownConstructClass: case Stmt::OpenACCSetConstructClass: case Stmt::OpenACCUpdateConstructClass: + case Stmt::OpenACCAtomicConstructClass: case Stmt::OMPUnrollDirectiveClass: case Stmt::OMPMetaDirectiveClass: case Stmt::HLSLOutArgExprClass: { diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 7a900780384a9..3a983421358c7 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -522,6 +522,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, case CK_ToUnion: case CK_MatrixCast: case CK_VectorSplat: + case CK_HLSLElementwiseCast: case CK_HLSLVectorTruncation: { QualType resultType = CastE->getType(); if (CastE->isGLValue()) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp index f075df3ab5e4d..9426e0afd65a0 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp @@ -124,24 +124,26 @@ void ExprEngine::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, bool isContainerNull = state->isNull(collectionV).isConstrainedTrue(); - ExplodedNodeSet dstLocation; - evalLocation(dstLocation, S, elem, Pred, state, elementV, false); + ExplodedNodeSet DstLocation; // states in `DstLocation` may differ from `Pred` + evalLocation(DstLocation, S, elem, Pred, state, elementV, false); - ExplodedNodeSet Tmp; - StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); + for (ExplodedNode *dstLocation : DstLocation) { + ExplodedNodeSet DstLocationSingleton{dstLocation}, Tmp; + StmtNodeBuilder Bldr(dstLocation, Tmp, *currBldrCtx); - if (!isContainerNull) - populateObjCForDestinationSet(dstLocation, svalBuilder, S, elem, elementV, - SymMgr, currBldrCtx, Bldr, - /*hasElements=*/true); + if (!isContainerNull) + populateObjCForDestinationSet(DstLocationSingleton, svalBuilder, S, elem, + elementV, SymMgr, currBldrCtx, Bldr, + /*hasElements=*/true); - populateObjCForDestinationSet(dstLocation, svalBuilder, S, elem, elementV, - SymMgr, currBldrCtx, Bldr, - /*hasElements=*/false); + populateObjCForDestinationSet(DstLocationSingleton, svalBuilder, S, elem, + elementV, SymMgr, currBldrCtx, Bldr, + /*hasElements=*/false); - // Finally, run any custom checkers. - // FIXME: Eventually all pre- and post-checks should live in VisitStmt. - getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); + // Finally, run any custom checkers. + // FIXME: Eventually all pre- and post-checks should live in VisitStmt. + getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this); + } } void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME, diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 2c5cd2cf7630f..c81bb632b83e9 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -891,9 +891,8 @@ DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR, return Size; } - // FIXME: The following are being used in 'SimpleSValBuilder' and in - // 'ArrayBoundChecker::checkLocation' because there is no symbol to - // represent the regions more appropriately. + // FIXME: The following are being used in 'SimpleSValBuilder' because there + // is no symbol to represent the regions more appropriately. case MemRegion::BlockDataRegionKind: case MemRegion::BlockCodeRegionKind: case MemRegion::FunctionCodeRegionKind: diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 6266878565c52..d01b6ae55f611 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -29,6 +29,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "llvm/ADT/ImmutableMap.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -112,6 +113,13 @@ class BindingKey { LLVM_DUMP_METHOD void dump() const; }; + +std::string locDescr(Loc L) { + std::string S; + llvm::raw_string_ostream OS(S); + L.dumpToStream(OS); + return OS.str(); +} } // end anonymous namespace BindingKey BindingKey::Make(const MemRegion *R, Kind k) { @@ -2408,6 +2416,8 @@ StoreRef RegionStoreManager::killBinding(Store ST, Loc L) { RegionBindingsRef RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) { + llvm::TimeTraceScope TimeScope("RegionStoreManager::bind", + [&L]() { return locDescr(L); }); // We only care about region locations. auto MemRegVal = L.getAs(); if (!MemRegVal) @@ -2514,6 +2524,8 @@ RegionBindingsRef RegionStoreManager::bindArray(RegionBindingsConstRef B, const TypedValueRegion* R, SVal Init) { + llvm::TimeTraceScope TimeScope("RegionStoreManager::bindArray", + [R]() { return R->getDescriptiveName(); }); const ArrayType *AT =cast(Ctx.getCanonicalType(R->getValueType())); QualType ElementTy = AT->getElementType(); @@ -2578,6 +2590,8 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B, RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B, const TypedValueRegion* R, SVal V) { + llvm::TimeTraceScope TimeScope("RegionStoreManager::bindVector", + [R]() { return R->getDescriptiveName(); }); QualType T = R->getValueType(); const VectorType *VT = T->castAs(); // Use castAs for typedefs. @@ -2700,6 +2714,8 @@ std::optional RegionStoreManager::tryBindSmallStruct( RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B, const TypedValueRegion *R, SVal V) { + llvm::TimeTraceScope TimeScope("RegionStoreManager::bindStruct", + [R]() { return R->getDescriptiveName(); }); QualType T = R->getValueType(); assert(T->isStructureOrClassType()); @@ -2818,6 +2834,8 @@ RegionBindingsRef RegionStoreManager::bindAggregate(RegionBindingsConstRef B, const TypedRegion *R, SVal Val) { + llvm::TimeTraceScope TimeScope("RegionStoreManager::bindAggregate", + [R]() { return R->getDescriptiveName(); }); // Remove the old bindings, using 'R' as the root of all regions // we will invalidate. Then add the new binding. return removeSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val); diff --git a/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp index e8cf367b83346..79ee430988b7c 100644 --- a/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp @@ -91,7 +91,6 @@ class TextDiagnostics : public PathDiagnosticConsumer { ? " [" + PD->getCheckerName() + "]" : "") .str(); - reportPiece(WarnID, PD->getLocation().asLocation(), (PD->getShortDescription() + WarningMsg).str(), PD->path.back()->getRanges(), PD->path.back()->getFixits()); diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 91c9b085f6829..189d7d6bede8e 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -39,6 +39,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include @@ -358,9 +359,40 @@ class AnalysisConsumer : public AnalysisASTConsumer, /// Print \p S to stderr if \c Opts.AnalyzerDisplayProgress is set. void reportAnalyzerProgress(StringRef S); -}; // namespace -} // end anonymous namespace +}; +std::string timeTraceScopeDeclName(StringRef FunName, const Decl *D) { + if (llvm::timeTraceProfilerEnabled()) { + if (const NamedDecl *ND = dyn_cast(D)) + return (FunName + " " + ND->getQualifiedNameAsString()).str(); + return (FunName + " ").str(); + } + return ""; +} + +llvm::TimeTraceMetadata timeTraceScopeDeclMetadata(const Decl *D) { + // If time-trace profiler is not enabled, this function is never called. + assert(llvm::timeTraceProfilerEnabled()); + if (const auto &Loc = D->getBeginLoc(); Loc.isValid()) { + const auto &SM = D->getASTContext().getSourceManager(); + std::string DeclName = AnalysisDeclContext::getFunctionName(D); + return llvm::TimeTraceMetadata{ + std::move(DeclName), SM.getFilename(Loc).str(), + static_cast(SM.getExpansionLineNumber(Loc))}; + } + return llvm::TimeTraceMetadata{"", ""}; +} + +void flushReports(llvm::Timer *BugReporterTimer, BugReporter &BR) { + llvm::TimeTraceScope TCS{"Flushing reports"}; + // Display warnings. + if (BugReporterTimer) + BugReporterTimer->startTimer(); + BR.FlushReports(); + if (BugReporterTimer) + BugReporterTimer->stopTimer(); +} +} // namespace //===----------------------------------------------------------------------===// // AnalysisConsumer implementation. @@ -658,6 +690,8 @@ AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) { void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode, ExprEngine::InliningModes IMode, SetOfConstDecls *VisitedCallees) { + llvm::TimeTraceScope TCS(timeTraceScopeDeclName("HandleCode", D), + [D]() { return timeTraceScopeDeclMetadata(D); }); if (!D->hasBody()) return; Mode = getModeForDecl(D, Mode); @@ -742,12 +776,7 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, if (Mgr->options.visualizeExplodedGraphWithGraphViz) Eng.ViewGraph(Mgr->options.TrimGraph); - // Display warnings. - if (BugReporterTimer) - BugReporterTimer->startTimer(); - Eng.getBugReporter().FlushReports(); - if (BugReporterTimer) - BugReporterTimer->stopTimer(); + flushReports(BugReporterTimer.get(), Eng.getBugReporter()); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp index 4219f67165861..2b4c2bb76434a 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp @@ -142,11 +142,13 @@ llvm::Expected DependencyScanningTool::getTranslationUnitDependencies( const std::vector &CommandLine, StringRef CWD, const llvm::DenseSet &AlreadySeen, - LookupModuleOutputCallback LookupModuleOutput) { + LookupModuleOutputCallback LookupModuleOutput, + std::optional TUBuffer) { FullDependencyConsumer Consumer(AlreadySeen); CallbackActionController Controller(LookupModuleOutput); - llvm::Error Result = - Worker.computeDependencies(CWD, CommandLine, Consumer, Controller); + llvm::Error Result = Worker.computeDependencies(CWD, CommandLine, Consumer, + Controller, TUBuffer); + if (Result) return std::move(Result); return Consumer.takeTranslationUnitDeps(); diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 5a648df05e4fd..d15b74a28ab24 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -24,9 +24,11 @@ #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" #include "clang/Tooling/Tooling.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Error.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/TargetParser/Host.h" #include @@ -521,20 +523,43 @@ DependencyScanningWorker::DependencyScanningWorker( } } -llvm::Error DependencyScanningWorker::computeDependencies( - StringRef WorkingDirectory, const std::vector &CommandLine, - DependencyConsumer &Consumer, DependencyActionController &Controller, - std::optional ModuleName) { +static std::unique_ptr +createDiagOptions(const std::vector &CommandLine) { std::vector CLI; for (const std::string &Arg : CommandLine) CLI.push_back(Arg.c_str()); auto DiagOpts = CreateAndPopulateDiagOpts(CLI); sanitizeDiagOpts(*DiagOpts); + return DiagOpts; +} + +llvm::Error DependencyScanningWorker::computeDependencies( + StringRef WorkingDirectory, const std::vector &CommandLine, + DependencyConsumer &Consumer, DependencyActionController &Controller, + std::optional TUBuffer) { + // Capture the emitted diagnostics and report them to the client + // in the case of a failure. + std::string DiagnosticOutput; + llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput); + auto DiagOpts = createDiagOptions(CommandLine); + TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.release()); + if (computeDependencies(WorkingDirectory, CommandLine, Consumer, Controller, + DiagPrinter, TUBuffer)) + return llvm::Error::success(); + return llvm::make_error(DiagnosticsOS.str(), + llvm::inconvertibleErrorCode()); +} + +llvm::Error DependencyScanningWorker::computeDependencies( + StringRef WorkingDirectory, const std::vector &CommandLine, + DependencyConsumer &Consumer, DependencyActionController &Controller, + StringRef ModuleName) { // Capture the emitted diagnostics and report them to the client // in the case of a failure. std::string DiagnosticOutput; llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput); + auto DiagOpts = createDiagOptions(CommandLine); TextDiagnosticPrinter DiagPrinter(DiagnosticsOS, DiagOpts.release()); if (computeDependencies(WorkingDirectory, CommandLine, Consumer, Controller, @@ -604,54 +629,22 @@ static bool createAndRunToolInvocation( return true; } -bool DependencyScanningWorker::computeDependencies( +bool DependencyScanningWorker::scanDependencies( StringRef WorkingDirectory, const std::vector &CommandLine, DependencyConsumer &Consumer, DependencyActionController &Controller, - DiagnosticConsumer &DC, std::optional ModuleName) { - // Reset what might have been modified in the previous worker invocation. - BaseFS->setCurrentWorkingDirectory(WorkingDirectory); - - std::optional> ModifiedCommandLine; - llvm::IntrusiveRefCntPtr ModifiedFS; - - // If we're scanning based on a module name alone, we don't expect the client - // to provide us with an input file. However, the driver really wants to have - // one. Let's just make it up to make the driver happy. - if (ModuleName) { - auto OverlayFS = - llvm::makeIntrusiveRefCnt(BaseFS); - auto InMemoryFS = - llvm::makeIntrusiveRefCnt(); - InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory); - OverlayFS->pushOverlay(InMemoryFS); - ModifiedFS = OverlayFS; - - SmallString<128> FakeInputPath; - // TODO: We should retry the creation if the path already exists. - llvm::sys::fs::createUniquePath(*ModuleName + "-%%%%%%%%.input", - FakeInputPath, - /*MakeAbsolute=*/false); - InMemoryFS->addFile(FakeInputPath, 0, llvm::MemoryBuffer::getMemBuffer("")); - - ModifiedCommandLine = CommandLine; - ModifiedCommandLine->emplace_back(FakeInputPath); - } - - const std::vector &FinalCommandLine = - ModifiedCommandLine ? *ModifiedCommandLine : CommandLine; - auto &FinalFS = ModifiedFS ? ModifiedFS : BaseFS; - + DiagnosticConsumer &DC, llvm::IntrusiveRefCntPtr FS, + std::optional ModuleName) { auto FileMgr = - llvm::makeIntrusiveRefCnt(FileSystemOptions{}, FinalFS); + llvm::makeIntrusiveRefCnt(FileSystemOptions{}, FS); - std::vector FinalCCommandLine(FinalCommandLine.size(), nullptr); - llvm::transform(FinalCommandLine, FinalCCommandLine.begin(), + std::vector CCommandLine(CommandLine.size(), nullptr); + llvm::transform(CommandLine, CCommandLine.begin(), [](const std::string &Str) { return Str.c_str(); }); - - auto DiagOpts = CreateAndPopulateDiagOpts(FinalCCommandLine); + auto DiagOpts = CreateAndPopulateDiagOpts(CCommandLine); sanitizeDiagOpts(*DiagOpts); IntrusiveRefCntPtr Diags = - CompilerInstance::createDiagnostics(*FinalFS, DiagOpts.release(), &DC, + CompilerInstance::createDiagnostics(FileMgr->getVirtualFileSystem(), + DiagOpts.release(), &DC, /*ShouldOwnClient=*/false); // Although `Diagnostics` are used only for command-line parsing, the @@ -667,12 +660,12 @@ bool DependencyScanningWorker::computeDependencies( DisableFree, ModuleName); bool Success = false; - if (FinalCommandLine[1] == "-cc1") { - Success = createAndRunToolInvocation(FinalCommandLine, Action, *FileMgr, + if (CommandLine[1] == "-cc1") { + Success = createAndRunToolInvocation(CommandLine, Action, *FileMgr, PCHContainerOps, *Diags, Consumer); } else { Success = forEachDriverJob( - FinalCommandLine, *Diags, *FileMgr, [&](const driver::Command &Cmd) { + CommandLine, *Diags, *FileMgr, [&](const driver::Command &Cmd) { if (StringRef(Cmd.getCreator().getName()) != "clang") { // Non-clang command. Just pass through to the dependency // consumer. @@ -699,8 +692,77 @@ bool DependencyScanningWorker::computeDependencies( if (Success && !Action.hasScanned()) Diags->Report(diag::err_fe_expected_compiler_job) - << llvm::join(FinalCommandLine, " "); + << llvm::join(CommandLine, " "); return Success && Action.hasScanned(); } +bool DependencyScanningWorker::computeDependencies( + StringRef WorkingDirectory, const std::vector &CommandLine, + DependencyConsumer &Consumer, DependencyActionController &Controller, + DiagnosticConsumer &DC, std::optional TUBuffer) { + // Reset what might have been modified in the previous worker invocation. + BaseFS->setCurrentWorkingDirectory(WorkingDirectory); + + std::optional> ModifiedCommandLine; + llvm::IntrusiveRefCntPtr ModifiedFS; + + // If we're scanning based on a module name alone, we don't expect the client + // to provide us with an input file. However, the driver really wants to have + // one. Let's just make it up to make the driver happy. + if (TUBuffer) { + auto OverlayFS = + llvm::makeIntrusiveRefCnt(BaseFS); + auto InMemoryFS = + llvm::makeIntrusiveRefCnt(); + InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory); + auto InputPath = TUBuffer->getBufferIdentifier(); + InMemoryFS->addFile( + InputPath, 0, + llvm::MemoryBuffer::getMemBufferCopy(TUBuffer->getBuffer())); + llvm::IntrusiveRefCntPtr InMemoryOverlay = + InMemoryFS; + + OverlayFS->pushOverlay(InMemoryOverlay); + ModifiedFS = OverlayFS; + ModifiedCommandLine = CommandLine; + ModifiedCommandLine->emplace_back(InputPath); + } + + const std::vector &FinalCommandLine = + ModifiedCommandLine ? *ModifiedCommandLine : CommandLine; + auto &FinalFS = ModifiedFS ? ModifiedFS : BaseFS; + + return scanDependencies(WorkingDirectory, FinalCommandLine, Consumer, + Controller, DC, FinalFS, /*ModuleName=*/std::nullopt); +} + +bool DependencyScanningWorker::computeDependencies( + StringRef WorkingDirectory, const std::vector &CommandLine, + DependencyConsumer &Consumer, DependencyActionController &Controller, + DiagnosticConsumer &DC, StringRef ModuleName) { + // Reset what might have been modified in the previous worker invocation. + BaseFS->setCurrentWorkingDirectory(WorkingDirectory); + + // If we're scanning based on a module name alone, we don't expect the client + // to provide us with an input file. However, the driver really wants to have + // one. Let's just make it up to make the driver happy. + auto OverlayFS = + llvm::makeIntrusiveRefCnt(BaseFS); + auto InMemoryFS = llvm::makeIntrusiveRefCnt(); + InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory); + SmallString<128> FakeInputPath; + // TODO: We should retry the creation if the path already exists. + llvm::sys::fs::createUniquePath(ModuleName + "-%%%%%%%%.input", FakeInputPath, + /*MakeAbsolute=*/false); + InMemoryFS->addFile(FakeInputPath, 0, llvm::MemoryBuffer::getMemBuffer("")); + llvm::IntrusiveRefCntPtr InMemoryOverlay = InMemoryFS; + + OverlayFS->pushOverlay(InMemoryOverlay); + auto ModifiedCommandLine = CommandLine; + ModifiedCommandLine.emplace_back(FakeInputPath); + + return scanDependencies(WorkingDirectory, ModifiedCommandLine, Consumer, + Controller, DC, OverlayFS, ModuleName); +} + DependencyActionController::~DependencyActionController() {} diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index 2e97cac0796ce..1c5f4c4b50ab6 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -214,9 +214,6 @@ makeCommonInvocationForModuleBuild(CompilerInvocation CI) { CI.getDependencyOutputOpts().Targets.clear(); CI.getFrontendOpts().ProgramAction = frontend::GenerateModule; - CI.getFrontendOpts().ARCMTAction = FrontendOptions::ARCMT_None; - CI.getFrontendOpts().ObjCMTAction = FrontendOptions::ObjCMT_None; - CI.getFrontendOpts().MTMigrateDir.clear(); CI.getLangOpts().ModuleName.clear(); // Remove any macro definitions that are explicitly ignored. @@ -397,9 +394,91 @@ void ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) { } } +static bool isSafeToIgnoreCWD(const CowCompilerInvocation &CI) { + // Check if the command line input uses relative paths. + // It is not safe to ignore the current working directory if any of the + // command line inputs use relative paths. +#define IF_RELATIVE_RETURN_FALSE(PATH) \ + do { \ + if (!PATH.empty() && !llvm::sys::path::is_absolute(PATH)) \ + return false; \ + } while (0) + +#define IF_ANY_RELATIVE_RETURN_FALSE(PATHS) \ + do { \ + if (llvm::any_of(PATHS, [](const auto &P) { \ + return !P.empty() && !llvm::sys::path::is_absolute(P); \ + })) \ + return false; \ + } while (0) + + // Header search paths. + const auto &HeaderSearchOpts = CI.getHeaderSearchOpts(); + IF_RELATIVE_RETURN_FALSE(HeaderSearchOpts.Sysroot); + for (auto &Entry : HeaderSearchOpts.UserEntries) + if (Entry.IgnoreSysRoot) + IF_RELATIVE_RETURN_FALSE(Entry.Path); + IF_RELATIVE_RETURN_FALSE(HeaderSearchOpts.ResourceDir); + IF_RELATIVE_RETURN_FALSE(HeaderSearchOpts.ModuleCachePath); + IF_RELATIVE_RETURN_FALSE(HeaderSearchOpts.ModuleUserBuildPath); + for (auto I = HeaderSearchOpts.PrebuiltModuleFiles.begin(), + E = HeaderSearchOpts.PrebuiltModuleFiles.end(); + I != E;) { + auto Current = I++; + IF_RELATIVE_RETURN_FALSE(Current->second); + } + IF_ANY_RELATIVE_RETURN_FALSE(HeaderSearchOpts.PrebuiltModulePaths); + IF_ANY_RELATIVE_RETURN_FALSE(HeaderSearchOpts.VFSOverlayFiles); + + // Preprocessor options. + const auto &PPOpts = CI.getPreprocessorOpts(); + IF_ANY_RELATIVE_RETURN_FALSE(PPOpts.MacroIncludes); + IF_ANY_RELATIVE_RETURN_FALSE(PPOpts.Includes); + IF_RELATIVE_RETURN_FALSE(PPOpts.ImplicitPCHInclude); + + // Frontend options. + const auto &FrontendOpts = CI.getFrontendOpts(); + for (const FrontendInputFile &Input : FrontendOpts.Inputs) { + if (Input.isBuffer()) + continue; // FIXME: Can this happen when parsing command-line? + + IF_RELATIVE_RETURN_FALSE(Input.getFile()); + } + IF_RELATIVE_RETURN_FALSE(FrontendOpts.CodeCompletionAt.FileName); + IF_ANY_RELATIVE_RETURN_FALSE(FrontendOpts.ModuleMapFiles); + IF_ANY_RELATIVE_RETURN_FALSE(FrontendOpts.ModuleFiles); + IF_ANY_RELATIVE_RETURN_FALSE(FrontendOpts.ModulesEmbedFiles); + IF_ANY_RELATIVE_RETURN_FALSE(FrontendOpts.ASTMergeFiles); + IF_RELATIVE_RETURN_FALSE(FrontendOpts.OverrideRecordLayoutsFile); + IF_RELATIVE_RETURN_FALSE(FrontendOpts.StatsFile); + + // Filesystem options. + const auto &FileSystemOpts = CI.getFileSystemOpts(); + IF_RELATIVE_RETURN_FALSE(FileSystemOpts.WorkingDir); + + // Codegen options. + const auto &CodeGenOpts = CI.getCodeGenOpts(); + IF_RELATIVE_RETURN_FALSE(CodeGenOpts.DebugCompilationDir); + IF_RELATIVE_RETURN_FALSE(CodeGenOpts.CoverageCompilationDir); + + // Sanitizer options. + IF_ANY_RELATIVE_RETURN_FALSE(CI.getLangOpts().NoSanitizeFiles); + + // Coverage mappings. + IF_RELATIVE_RETURN_FALSE(CodeGenOpts.ProfileInstrumentUsePath); + IF_RELATIVE_RETURN_FALSE(CodeGenOpts.SampleProfileFile); + IF_RELATIVE_RETURN_FALSE(CodeGenOpts.ProfileRemappingFile); + + // Dependency output options. + for (auto &ExtraDep : CI.getDependencyOutputOpts().ExtraDeps) + IF_RELATIVE_RETURN_FALSE(ExtraDep.first); + + return true; +} + static std::string getModuleContextHash(const ModuleDeps &MD, const CowCompilerInvocation &CI, - bool EagerLoadModules, + bool EagerLoadModules, bool IgnoreCWD, llvm::vfs::FileSystem &VFS) { llvm::HashBuilder, llvm::endianness::native> HashBuilder; @@ -410,8 +489,11 @@ static std::string getModuleContextHash(const ModuleDeps &MD, HashBuilder.add(getClangFullRepositoryVersion()); HashBuilder.add(serialization::VERSION_MAJOR, serialization::VERSION_MINOR); llvm::ErrorOr CWD = VFS.getCurrentWorkingDirectory(); - if (CWD) + auto &FSOpts = const_cast(CI.getFileSystemOpts()); + if (CWD && !IgnoreCWD) HashBuilder.add(*CWD); + else + FSOpts.WorkingDir.clear(); // Hash the BuildInvocation without any input files. SmallString<0> ArgVec; @@ -443,8 +525,11 @@ static std::string getModuleContextHash(const ModuleDeps &MD, void ModuleDepCollector::associateWithContextHash( const CowCompilerInvocation &CI, ModuleDeps &Deps) { - Deps.ID.ContextHash = getModuleContextHash( - Deps, CI, EagerLoadModules, ScanInstance.getVirtualFileSystem()); + bool IgnoreCWD = any(OptimizeArgs & ScanningOptimizations::IgnoreCWD) && + isSafeToIgnoreCWD(CI); + Deps.ID.ContextHash = + getModuleContextHash(Deps, CI, EagerLoadModules, IgnoreCWD, + ScanInstance.getVirtualFileSystem()); bool Inserted = ModuleDepsByID.insert({Deps.ID, &Deps}).second; (void)Inserted; assert(Inserted && "duplicate module mapping"); diff --git a/clang/test/ARCMT/Common.h b/clang/test/ARCMT/Common.h deleted file mode 100644 index b388ecab74109..0000000000000 --- a/clang/test/ARCMT/Common.h +++ /dev/null @@ -1,110 +0,0 @@ -#if __has_feature(objc_arr) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#define CF_CONSUMED __attribute__((cf_consumed)) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) - -#define NS_INLINE static __inline__ __attribute__((always_inline)) -#define nil ((void*) 0) -#define NULL ((void*)0) - -typedef int BOOL; -typedef unsigned NSUInteger; -typedef int int32_t; -typedef unsigned char uint8_t; -typedef int32_t UChar32; -typedef unsigned char UChar; - -typedef struct _NSZone NSZone; - -typedef const void * CFTypeRef; -CFTypeRef CFRetain(CFTypeRef cf); -CFTypeRef CFMakeCollectable(CFTypeRef cf) NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - -NS_INLINE NS_RETURNS_RETAINED id NSMakeCollectable(CFTypeRef CF_CONSUMED cf) NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -NS_AUTOMATED_REFCOUNT_UNAVAILABLE -@interface NSAutoreleasePool : NSObject { -@private - void *_token; - void *_reserved3; - void *_reserved2; - void *_reserved; -} - -+ (void)addObject:(id)anObject; - -- (void)addObject:(id)anObject; - -- (void)drain; - -@end - -typedef const void* objc_objectptr_t; -extern __attribute__((ns_returns_retained)) id objc_retainedObject(objc_objectptr_t __attribute__((cf_consumed)) pointer); -extern __attribute__((ns_returns_not_retained)) id objc_unretainedObject(objc_objectptr_t pointer); -extern objc_objectptr_t objc_unretainedPointer(id object); - -#define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; }) -#define dispatch_release(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); [_o release]; }) -#define xpc_retain(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o retain]; }) -#define xpc_release(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o release]; }) - -typedef id dispatch_object_t; -typedef id xpc_object_t; - -void _dispatch_object_validate(dispatch_object_t object); -void _xpc_object_validate(xpc_object_t object); - -#if __has_feature(objc_arc) - -NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetain(id X) { - return (__bridge_retained CFTypeRef)X; -} - -NS_INLINE id CFBridgingRelease(CFTypeRef CF_CONSUMED X) { - return (__bridge_transfer id)X; -} - -#else - -NS_INLINE CF_RETURNS_RETAINED CFTypeRef CFBridgingRetain(id X) { - return X ? CFRetain((CFTypeRef)X) : NULL; -} - -NS_INLINE id CFBridgingRelease(CFTypeRef CF_CONSUMED X) { - return [(id)CFMakeCollectable(X) autorelease]; -} - -#endif - -void *_Block_copy(const void *aBlock); -void _Block_release(const void *aBlock); -#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) -#define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) diff --git a/clang/test/ARCMT/GC-check-warn-nsalloc.m b/clang/test/ARCMT/GC-check-warn-nsalloc.m deleted file mode 100644 index 1c33de5b65b25..0000000000000 --- a/clang/test/ARCMT/GC-check-warn-nsalloc.m +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only %s 2>&1 | grep 'warning: \[rewriter\] call returns pointer to GC managed memory' -// RUN: %clang_cc1 -arcmt-action=check -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s 2>&1 | grep 'warning: \[rewriter\] call returns pointer to GC managed memory' -// TODO: Investigate VerifyDiagnosticConsumer failures on these tests when using -verify. - -typedef unsigned NSUInteger; -void *__strong NSAllocateCollectable(NSUInteger size, NSUInteger options); - -void test1(void) { - NSAllocateCollectable(100, 0); -} diff --git a/clang/test/ARCMT/GC-check.m b/clang/test/ARCMT/GC-check.m deleted file mode 100644 index e95e285432e0f..0000000000000 --- a/clang/test/ARCMT/GC-check.m +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only %s -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s - -#define CF_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -typedef unsigned NSUInteger; -typedef const void * CFTypeRef; -CFTypeRef CFMakeCollectable(CFTypeRef cf) CF_AUTOMATED_REFCOUNT_UNAVAILABLE; // expected-note {{unavailable}} -void *__strong NSAllocateCollectable(NSUInteger size, NSUInteger options); - -void test1(CFTypeRef *cft) { - CFTypeRef c = CFMakeCollectable(cft); // expected-error {{CFMakeCollectable will leak the object that it receives in ARC}} \ - // expected-error {{unavailable}} - NSAllocateCollectable(100, 0); // expected-error {{call returns pointer to GC managed memory; it will become unmanaged in ARC}} -} - -@interface I1 { - __strong void *gcVar; // expected-error {{GC managed memory will become unmanaged in ARC}} -} -@end; diff --git a/clang/test/ARCMT/GC-no-arc-runtime.m b/clang/test/ARCMT/GC-no-arc-runtime.m deleted file mode 100644 index 99ba2eb5f7aef..0000000000000 --- a/clang/test/ARCMT/GC-no-arc-runtime.m +++ /dev/null @@ -1,80 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -// MRC __weak broke this test somehow. -// XFAIL: * - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = NSMakeCollectable(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - --(void)finalize { - // finalize - test1(0); -} -@end - -@interface I2 -@property (retain) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __weak QQ *q; -} -@end - -@interface I3 -@property (assign) I3 *__weak pw1, *__weak pw2; -@property (assign) I3 *__strong ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *pds2; -} -@property (assign) I4Impl *__weak pw1, *__weak pw2; -@property (assign) I4Impl *__strong ps; -@property (assign) I4Impl * pds; -@property (assign) I4Impl * pds2; -@end - -@implementation I4Impl -@synthesize pw1, pw2, ps, pds, pds2; - --(void)test1:(CFTypeRef *)cft { - id x = NSMakeCollectable(cft); -} -@end - -@interface I5 { - __weak id prop; -} -@property (readonly) __weak id prop; -@end diff --git a/clang/test/ARCMT/GC-no-arc-runtime.m.result b/clang/test/ARCMT/GC-no-arc-runtime.m.result deleted file mode 100644 index c338bdb2ed471..0000000000000 --- a/clang/test/ARCMT/GC-no-arc-runtime.m.result +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = CFBridgingRelease(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - -@end - -@interface I2 -@property (strong) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)dealloc { - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __unsafe_unretained id s; - __unsafe_unretained QQ *q; -} -@end - -@interface I3 -@property (unsafe_unretained) I3 * pw1, * pw2; -@property (strong) I3 * ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *__strong pds2; -} -@property (unsafe_unretained) I4Impl * pw1, * pw2; -@property (strong) I4Impl * ps; -@property (strong) I4Impl * pds; -@property (strong) I4Impl * pds2; -@end - -@implementation I4Impl -@synthesize pw1, pw2, ps, pds, pds2; - --(void)test1:(CFTypeRef *)cft { - id x = CFBridgingRelease(cft); -} -@end - -@interface I5 { - __unsafe_unretained id prop; -} -@property (unsafe_unretained, readonly) id prop; -@end diff --git a/clang/test/ARCMT/GC-no-finalize-removal.m b/clang/test/ARCMT/GC-no-finalize-removal.m deleted file mode 100644 index 07a737c1b7757..0000000000000 --- a/clang/test/ARCMT/GC-no-finalize-removal.m +++ /dev/null @@ -1,88 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = NSMakeCollectable(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - --(void)finalize { - // finalize - test1(0); -} -@end - -@interface I2 -@property (retain) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __weak QQ *q; -} -@end - -@interface I3 -@property (assign) I3 *__weak pw1, *__weak pw2; -@property (assign) I3 *__strong ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (assign) I4Impl *__weak pw1, *__weak pw2; -@property (assign) I4Impl *__strong ps; -@property (assign) I4Impl * pds; -@property (assign) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (readonly) __weak I4Impl *pw3; -@property (assign) __weak I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = NSMakeCollectable(cft); -} -@end - -@interface rdar10532449 -@property (assign) id assign_prop; -@property (assign, readonly) id __strong strong_readonly_prop; -@property (assign) id __weak weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end diff --git a/clang/test/ARCMT/GC-no-finalize-removal.m.result b/clang/test/ARCMT/GC-no-finalize-removal.m.result deleted file mode 100644 index a2105b32fc755..0000000000000 --- a/clang/test/ARCMT/GC-no-finalize-removal.m.result +++ /dev/null @@ -1,96 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = CFBridgingRelease(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - -#if !__has_feature(objc_arc) --(void)finalize { - // finalize - test1(0); -} -#endif -@end - -@interface I2 -@property (strong) id prop; -@end - -@implementation I2 -@synthesize prop; - -#if !__has_feature(objc_arc) --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -#endif --(void)dealloc { - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __unsafe_unretained QQ *q; -} -@end - -@interface I3 -@property (weak) I3 * pw1, * pw2; -@property (strong) I3 * ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *__strong pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (weak) I4Impl * pw1, * pw2; -@property (strong) I4Impl * ps; -@property (strong) I4Impl * pds; -@property (strong) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (weak, readonly) I4Impl *pw3; -@property (weak) I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = CFBridgingRelease(cft); -} -@end - -@interface rdar10532449 -@property (strong) id assign_prop; -@property (strong, readonly) id strong_readonly_prop; -@property (weak) id weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end diff --git a/clang/test/ARCMT/GC.h b/clang/test/ARCMT/GC.h deleted file mode 100644 index 4301baf272465..0000000000000 --- a/clang/test/ARCMT/GC.h +++ /dev/null @@ -1,6 +0,0 @@ - -@interface ExtInterface { - __strong ExtInterface *myivar; - __strong void *gcVar; -} -@end diff --git a/clang/test/ARCMT/GC.m b/clang/test/ARCMT/GC.m deleted file mode 100644 index 97723e89ed369..0000000000000 --- a/clang/test/ARCMT/GC.m +++ /dev/null @@ -1,93 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = NSMakeCollectable(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - --(void)finalize { - // finalize - test1(0); -} -@end - -@interface I2 -@property (retain) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)finalize { - self.prop = 0; - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __weak QQ *q; -} -@end - -@interface I3 -@property (assign) I3 *__weak pw1, *__weak pw2; -@property (assign) I3 *__strong ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (assign) I4Impl *__weak pw1, *__weak pw2; -@property (assign) I4Impl *__strong ps; -@property (assign) I4Impl * pds; -@property (assign) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (readonly) __weak I4Impl *pw3; -@property (assign) __weak I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = NSMakeCollectable(cft); -} -@end - -@interface rdar10532449 -@property (assign) id assign_prop; -@property (assign, readonly) id __strong strong_readonly_prop; -@property (assign) id __weak weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end - -void test2(id p, __strong I1 *ap[]) { - for (__strong I1 *specRule in p) { - } -} diff --git a/clang/test/ARCMT/GC.m.result b/clang/test/ARCMT/GC.m.result deleted file mode 100644 index b60b07ac9c110..0000000000000 --- a/clang/test/ARCMT/GC.m.result +++ /dev/null @@ -1,88 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c %s > %t -// RUN: diff %t %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" -#include "GC.h" - -void test1(CFTypeRef *cft) { - id x = CFBridgingRelease(cft); -} - -@interface I1 -@end - -@implementation I1 --(void)dealloc { - // dealloc - test1(0); -} - -@end - -@interface I2 -@property (strong) id prop; -@end - -@implementation I2 -@synthesize prop; - --(void)dealloc { - // finalize - test1(0); -} -@end - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface QQ { - __weak id s; - __unsafe_unretained QQ *q; -} -@end - -@interface I3 -@property (weak) I3 * pw1, * pw2; -@property (strong) I3 * ps; -@property (assign) I3 * pds; -@end - -@interface I4Impl { - I4Impl *__strong pds2; - I4Impl *pds3; - __weak I4Impl *pw3; - __weak I4Impl *pw4; -} -@property (weak) I4Impl * pw1, * pw2; -@property (strong) I4Impl * ps; -@property (strong) I4Impl * pds; -@property (strong) I4Impl * pds2; -@property (readwrite) I4Impl * pds3; -@property (readonly) I4Impl * pds4; -@property (weak, readonly) I4Impl *pw3; -@property (weak) I4Impl *pw4; -@end - -@implementation I4Impl -@synthesize pw1, pw2, pw3, pw4, ps, pds, pds2, pds3, pds4; - --(void)test1:(CFTypeRef *)cft { - id x = CFBridgingRelease(cft); -} -@end - -@interface rdar10532449 -@property (strong) id assign_prop; -@property (strong, readonly) id strong_readonly_prop; -@property (weak) id weak_prop; -@end - -@implementation rdar10532449 -@synthesize assign_prop, strong_readonly_prop, weak_prop; -@end - -void test2(id p, __strong I1 *ap[]) { - for (__strong I1 *specRule in p) { - } -} diff --git a/clang/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h b/clang/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h deleted file mode 100644 index f7f9fb66c9e94..0000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef MODULE_SUBFRAMEWORK_H -#define MODULE_SUBFRAMEWORK_H -#__private_macro MODULE_SUBFRAMEWORK_H -char *module_subframework; -#endif diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h deleted file mode 100644 index 6e81adcb2b60c..0000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h +++ /dev/null @@ -1 +0,0 @@ -unsigned *Buried_Treasure; diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Module.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Module.h deleted file mode 100644 index 3d2476b20431d..0000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Module.h +++ /dev/null @@ -1,28 +0,0 @@ -// expected-warning 0-1 {{umbrella header}} - -// FIXME: The "umbrella header" warning should be moved to a separate test. -// This "0-1" is only here because the warning is only emitted when the -// module is (otherwise) successfully included. - -#ifndef MODULE_H -#define MODULE_H -const char *getModuleVersion(void); - -#ifdef FOO -# error Module should have been built without -DFOO -#endif - -@interface Module -+(const char *)version; // retrieve module version -+alloc; -@end - -#define MODULE_H_MACRO 1 -#__private_macro MODULE_H_MACRO - -#include -#include - -__asm("foo"); - -#endif // MODULE_H diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h deleted file mode 100644 index 6b15791eb2c70..0000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h +++ /dev/null @@ -1 +0,0 @@ -int not_in_module; diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub.h deleted file mode 100644 index dea76e7646176..0000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub.h +++ /dev/null @@ -1,3 +0,0 @@ -#include -int *Module_Sub; - diff --git a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h b/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h deleted file mode 100644 index beed4a862dcaf..0000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h +++ /dev/null @@ -1 +0,0 @@ -int *Module_Sub2; diff --git a/clang/test/ARCMT/Inputs/Module.framework/Module b/clang/test/ARCMT/Inputs/Module.framework/Module deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/clang/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h b/clang/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h deleted file mode 100644 index 0782336df9dec..0000000000000 --- a/clang/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h +++ /dev/null @@ -1 +0,0 @@ -int module_private; diff --git a/clang/test/ARCMT/Inputs/module.modulemap b/clang/test/ARCMT/Inputs/module.modulemap deleted file mode 100644 index 061abbd24d570..0000000000000 --- a/clang/test/ARCMT/Inputs/module.modulemap +++ /dev/null @@ -1,309 +0,0 @@ -module c_library [extern_c] { module inner { header "c-header.h" } } -module cxx_library { header "cxx-header.h" requires cplusplus } -module c_library_bad [extern_c] { header "c-header-bad.h" } -module diamond_top { header "diamond_top.h" } -module diamond_left { - header "diamond_left.h" - export diamond_top -} -module diamond_right { - header "diamond_right.h" - export diamond_top -} -module diamond_bottom { - header "diamond_bottom.h" - export * -} -module irgen { header "irgen.h" } -module cxx_irgen_top { header "cxx-irgen-top.h" } -module cxx_irgen_left { header "cxx-irgen-left.h" } -module cxx_irgen_right { header "cxx-irgen-right.h" } -module lookup_left_objc { header "lookup_left.h" } -module lookup_right_objc { header "lookup_right.h" } -module lookup_left_cxx { header "lookup_left.hpp" } -module lookup_right_cxx { header "lookup_right.hpp" } -module module_private_left { header "module_private_left.h" } -module module_private_right { header "module_private_right.h" } -module macros_top { - header "macros_top.h" - explicit module b { header "macros_top_b.h" } - explicit module c { header "macros_top_c.h" } -} -module macros_left { - header "macros_left.h" - export * -} -module macros_right { - header "macros_right.h" - export * - explicit module undef { - header "macros_right_undef.h" - } -} -module macros { header "macros.h" } -module macros_other { header "macros_other.h" } -module category_top { header "category_top.h" } -module category_left { - header "category_left.h" - export category_top - - explicit module sub { - header "category_left_sub.h" - } -} -module category_right { - header "category_right.h" - export category_top - - explicit module sub { - header "category_right_sub.h" - } -} -module category_bottom { - header "category_bottom.h" - export category_left - export category_right -} -module category_other { header "category_other.h" } -module redeclarations_left { header "redeclarations_left.h" } -module redeclarations_right { header "redeclarations_right.h" } -module redecl_namespaces_left { header "redecl_namespaces_left.h" } -module redecl_namespaces_right { header "redecl_namespaces_right.h" } -module redecl_add_after_load_top { header "redecl-add-after-load-top.h" } -module redecl_add_after_load { header "redecl-add-after-load.h" } -module load_failure { header "load_failure.h" } - -module decldef { - explicit module Decl { header "decl.h" } - explicit module Decl2 { header "decl2.h" } - explicit module Def { header "def.h" } -} - -module redecl_merge_top { - header "redecl-merge-top.h" - explicit module Explicit { header "redecl-merge-top-explicit.h" } - exclude header "nonexistent.h" -} -module redecl_merge_left { - header "redecl-merge-left.h" - export * -} -module redecl_merge_left_left { - header "redecl-merge-left-left.h" - export * -} -module redecl_merge_right { - header "redecl-merge-right.h" - export * -} -module redecl_merge_bottom { - explicit module prefix { - header "redecl-merge-bottom-prefix.h" - } - - header "redecl-merge-bottom.h" - export * -} -module namespaces_top { - header "namespaces-top.h" - export * -} -module namespaces_left { - header "namespaces-left.h" - export * -} -module namespaces_right { - header "namespaces-right.h" - export * -} -module templates_top { - header "templates-top.h" - export * -} -module templates_left { - header "templates-left.h" - export * -} -module templates_right { - header "templates-right.h" - export * -} -module MethodPoolA { - header "MethodPoolA.h" - - explicit module Sub2 { - header "MethodPoolASub2.h" - } - - explicit module Sub { - header "MethodPoolASub.h" - } -} -module MethodPoolB { - header "MethodPoolB.h" - - explicit module Sub2 { - header "MethodPoolBSub2.h" - } - - explicit module Sub { - header "MethodPoolBSub.h" - } -} -module import_decl { - header "import-decl.h" -} - -framework module * { - exclude NotAModule -} - -module linkage_merge_left { - explicit module sub { - header "linkage-merge-sub.h" - } -} - -module autolink { - header "autolink.h" - link "autolink" - - explicit module sub { - header "autolink-sub.h" - link "autolink_sub" - } - - explicit module sub2 { - header "autolink-sub2.h" - link framework "autolink_framework" - } - - explicit module sub3 { - header "autolink-sub3.h" - link "autolink_from_pch" - } -} - -module weird_objc { - header "weird_objc.h" -} - -module ignored_macros { - header "ignored_macros.h" -} - -module cxx_many_overloads { - header "cxx-many-overloads.h" -} - -module cxx_inline_namespace { - header "cxx-inline-namespace.h" -} - -module cxx_inline_namespace_b { - header "cxx-inline-namespace-b.h" -} - -module cxx_linkage_cache { - header "cxx-linkage-cache.h" -} - -module cxx_templates_common { - header "cxx-templates-common.h" -} - -module cxx_templates_a { - header "cxx-templates-a.h" -} - -module cxx_templates_b_impl { - header "cxx-templates-b-impl.h" -} - -module cxx_templates_b { - header "cxx-templates-b.h" -} - -module cxx_templates_c { - header "cxx-templates-c.h" -} - -module cxx_decls { - module unimported { - header "cxx-decls-unimported.h" - } - module imported { - header "cxx-decls-imported.h" - } -} - -module config { - header "config.h" - config_macros [exhaustive] WANT_FOO, WANT_BAR -} - -module diag_pragma { - header "diag_pragma.h" -} - -module dummy { - header "dummy.h" -} - -module builtin { - header "builtin.h" - explicit module sub { - header "builtin_sub.h" - } -} - -module linkage_merge { - explicit module foo { - header "linkage-merge-foo.h" - } - explicit module bar { - header "linkage-merge-bar.h" - } - -} - -module incomplete_mod { - header "incomplete_mod.h" -} - -module warning { - header "warning.h" -} - -module initializer_list { - header "initializer_list" -} - -module using_decl { - module a { header "using-decl-a.h" export * } - module b { header "using-decl-b.h" export * } -} - -module recursive_visibility_a1 { - module inner { header "recursive_visibility_a1_inner.h" } -} -module recursive_visibility_a2 { - module inner { - module more_inner { - header "recursive_visibility_a2_more_inner.h" - } - } -} -module recursive_visibility_b { - header "recursive_visibility_b.h" - export * -} -module recursive_visibility_c { - header "recursive_visibility_c.h" -} -module recursive1 { - header "recursive1.h" -} -module recursive2 { - header "recursive2.h" -} diff --git a/clang/test/ARCMT/Inputs/test.h b/clang/test/ARCMT/Inputs/test.h deleted file mode 100644 index 756295f27e698..0000000000000 --- a/clang/test/ARCMT/Inputs/test.h +++ /dev/null @@ -1,15 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { - [p release]; -} -#endif - -#ifdef PART2 -static inline void part2(id p) { - [p release]; -} -#endif diff --git a/clang/test/ARCMT/Inputs/test.h.result b/clang/test/ARCMT/Inputs/test.h.result deleted file mode 100644 index 0638a3378c1c0..0000000000000 --- a/clang/test/ARCMT/Inputs/test.h.result +++ /dev/null @@ -1,13 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { -} -#endif - -#ifdef PART2 -static inline void part2(id p) { -} -#endif diff --git a/clang/test/ARCMT/Inputs/test1.m.in b/clang/test/ARCMT/Inputs/test1.m.in deleted file mode 100644 index 44a3c4cf3d93f..0000000000000 --- a/clang/test/ARCMT/Inputs/test1.m.in +++ /dev/null @@ -1,16 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { - [p release]; -} - -@interface Test2 -@property (strong) id prop; -@end - -@implementation Test2 --(id)init { - _prop = 0; -} -@end diff --git a/clang/test/ARCMT/Inputs/test1.m.in.result b/clang/test/ARCMT/Inputs/test1.m.in.result deleted file mode 100644 index 1db9bf7ad65c7..0000000000000 --- a/clang/test/ARCMT/Inputs/test1.m.in.result +++ /dev/null @@ -1,15 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { -} - -@interface Test2 -@property (strong) id prop; -@end - -@implementation Test2 --(id)init { - _prop = 0; -} -@end diff --git a/clang/test/ARCMT/Inputs/test2.m.in b/clang/test/ARCMT/Inputs/test2.m.in deleted file mode 100644 index 99f87b0721716..0000000000000 --- a/clang/test/ARCMT/Inputs/test2.m.in +++ /dev/null @@ -1,6 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/Inputs/test2.m.in.result b/clang/test/ARCMT/Inputs/test2.m.in.result deleted file mode 100644 index f8e918ce2598e..0000000000000 --- a/clang/test/ARCMT/Inputs/test2.m.in.result +++ /dev/null @@ -1,5 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { -} diff --git a/clang/test/ARCMT/Inputs/with space/test.h b/clang/test/ARCMT/Inputs/with space/test.h deleted file mode 100644 index 756295f27e698..0000000000000 --- a/clang/test/ARCMT/Inputs/with space/test.h +++ /dev/null @@ -1,15 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { - [p release]; -} -#endif - -#ifdef PART2 -static inline void part2(id p) { - [p release]; -} -#endif diff --git a/clang/test/ARCMT/Inputs/with space/test.h.result b/clang/test/ARCMT/Inputs/with space/test.h.result deleted file mode 100644 index 0638a3378c1c0..0000000000000 --- a/clang/test/ARCMT/Inputs/with space/test.h.result +++ /dev/null @@ -1,13 +0,0 @@ -@protocol NSObject -- (oneway void)release; -@end - -#ifdef PART1 -static inline void part1(id p) { -} -#endif - -#ifdef PART2 -static inline void part2(id p) { -} -#endif diff --git a/clang/test/ARCMT/Inputs/with space/test1.m.in b/clang/test/ARCMT/Inputs/with space/test1.m.in deleted file mode 100644 index 8416a88965696..0000000000000 --- a/clang/test/ARCMT/Inputs/with space/test1.m.in +++ /dev/null @@ -1,6 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/Inputs/with space/test1.m.in.result b/clang/test/ARCMT/Inputs/with space/test1.m.in.result deleted file mode 100644 index f351fe6c83552..0000000000000 --- a/clang/test/ARCMT/Inputs/with space/test1.m.in.result +++ /dev/null @@ -1,5 +0,0 @@ -#define PART1 -#include "test.h" - -void test1(id p) { -} diff --git a/clang/test/ARCMT/Inputs/with space/test2.m.in b/clang/test/ARCMT/Inputs/with space/test2.m.in deleted file mode 100644 index 99f87b0721716..0000000000000 --- a/clang/test/ARCMT/Inputs/with space/test2.m.in +++ /dev/null @@ -1,6 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/Inputs/with space/test2.m.in.result b/clang/test/ARCMT/Inputs/with space/test2.m.in.result deleted file mode 100644 index f8e918ce2598e..0000000000000 --- a/clang/test/ARCMT/Inputs/with space/test2.m.in.result +++ /dev/null @@ -1,5 +0,0 @@ -#define PART2 -#include "test.h" - -void test2(id p) { -} diff --git a/clang/test/ARCMT/allowlisted/Inputs/header1.h b/clang/test/ARCMT/allowlisted/Inputs/header1.h deleted file mode 100644 index 44430f3b77e32..0000000000000 --- a/clang/test/ARCMT/allowlisted/Inputs/header1.h +++ /dev/null @@ -1 +0,0 @@ -// the contents are not important diff --git a/clang/test/ARCMT/allowlisted/header1.h b/clang/test/ARCMT/allowlisted/header1.h deleted file mode 100644 index 33f77aa5dd152..0000000000000 --- a/clang/test/ARCMT/allowlisted/header1.h +++ /dev/null @@ -1,8 +0,0 @@ - -@interface I1 : NSObject --(int)prop; --(void)setProp:(int)p; -+(id)i1; -@end - -typedef long NSInteger; diff --git a/clang/test/ARCMT/allowlisted/header1.h.result b/clang/test/ARCMT/allowlisted/header1.h.result deleted file mode 100644 index c7cf109a27e92..0000000000000 --- a/clang/test/ARCMT/allowlisted/header1.h.result +++ /dev/null @@ -1,7 +0,0 @@ - -@interface I1 : NSObject -@property (nonatomic) int prop; -+(instancetype)i1; -@end - -typedef long NSInteger; diff --git a/clang/test/ARCMT/allowlisted/header2.h b/clang/test/ARCMT/allowlisted/header2.h deleted file mode 100644 index ac3888ccdf8c1..0000000000000 --- a/clang/test/ARCMT/allowlisted/header2.h +++ /dev/null @@ -1,8 +0,0 @@ - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -typedef enum : NSInteger {five} ApplicableEnum; - -@interface I2 : NSObject --(int)prop; --(void)setProp:(int)p; -@end diff --git a/clang/test/ARCMT/allowlisted/header2.h.result b/clang/test/ARCMT/allowlisted/header2.h.result deleted file mode 100644 index 3226e711b98ac..0000000000000 --- a/clang/test/ARCMT/allowlisted/header2.h.result +++ /dev/null @@ -1,7 +0,0 @@ - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -typedef NS_ENUM(NSInteger, ApplicableEnum) {five}; - -@interface I2 : NSObject -@property (nonatomic) int prop; -@end diff --git a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m b/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m deleted file mode 100644 index 36797eb1c843b..0000000000000 --- a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-allowlist-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result - -@interface NSObject -+ (id)alloc; -@end - -#include "header1.h" -#include "header2.h" - -@interface I2(cat) --(id)initInCat; -@end - -@implementation I1 -+(id)i1 {} -@end diff --git a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m.result b/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m.result deleted file mode 100644 index 69e7b767ef2b7..0000000000000 --- a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist-impl.m.result +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-allowlist-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result - -@interface NSObject -+ (id)alloc; -@end - -#include "header1.h" -#include "header2.h" - -@interface I2(cat) --(id)initInCat; -@end - -@implementation I1 -+(instancetype)i1 {} -@end diff --git a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist.m b/clang/test/ARCMT/allowlisted/objcmt-with-allowlist.m deleted file mode 100644 index c22c02d3bf2e4..0000000000000 --- a/clang/test/ARCMT/allowlisted/objcmt-with-allowlist.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-migrate-ns-macros %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/header2.h.result -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-migrate-ns-macros -objcmt-allowlist-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result - -@interface NSObject -+ (id)alloc; -@end - -#include "header1.h" -#include "header2.h" diff --git a/clang/test/ARCMT/api.m b/clang/test/ARCMT/api.m deleted file mode 100644 index b186ec724745c..0000000000000 --- a/clang/test/ARCMT/api.m +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(NSObject *o) { - NSZone *z = [o zone]; -} diff --git a/clang/test/ARCMT/api.m.result b/clang/test/ARCMT/api.m.result deleted file mode 100644 index e3093751b626b..0000000000000 --- a/clang/test/ARCMT/api.m.result +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(NSObject *o) { - NSZone *z = nil; -} diff --git a/clang/test/ARCMT/assign-prop-no-arc-runtime.m b/clang/test/ARCMT/assign-prop-no-arc-runtime.m deleted file mode 100644 index de1c456b3d19f..0000000000000 --- a/clang/test/ARCMT/assign-prop-no-arc-runtime.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject { - NSObject *x; -} -@property (readonly,assign) id x; -@end - -@implementation Foo -@synthesize x; -@end diff --git a/clang/test/ARCMT/assign-prop-no-arc-runtime.m.result b/clang/test/ARCMT/assign-prop-no-arc-runtime.m.result deleted file mode 100644 index 23848d357268f..0000000000000 --- a/clang/test/ARCMT/assign-prop-no-arc-runtime.m.result +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject { - NSObject *__unsafe_unretained x; -} -@property (readonly,unsafe_unretained) id x; -@end - -@implementation Foo -@synthesize x; -@end diff --git a/clang/test/ARCMT/assign-prop-with-arc-runtime.m b/clang/test/ARCMT/assign-prop-with-arc-runtime.m deleted file mode 100644 index a00538cd6197d..0000000000000 --- a/clang/test/ARCMT/assign-prop-with-arc-runtime.m +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface WeakOptOut -@end - -@class _NSCachedAttributedString; -typedef _NSCachedAttributedString *BadClassForWeak; - -@class Forw; - -@interface Foo : NSObject { - Foo *x, *w, *q1, *q2; - WeakOptOut *oo; - BadClassForWeak bcw; - id not_safe1; - NSObject *not_safe2; - Forw *not_safe3; - Foo *assign_plus1; -} -@property (readonly) Foo *x; -@property (assign) Foo *w; -@property Foo *q1, *q2; -@property (assign) WeakOptOut *oo; -@property (assign) BadClassForWeak bcw; -@property (assign) id not_safe1; -@property () NSObject *not_safe2; -@property Forw *not_safe3; -@property (readonly) Foo *assign_plus1; -@property (readonly) Foo *assign_plus2; -@property (readonly) Foo *assign_plus3; - -@property (assign) Foo *no_user_ivar1; -@property (readonly) Foo *no_user_ivar2; - -@property (retain) id def1; -@property (atomic,retain) id def2; -@property (retain,atomic) id def3; - -@end - -@implementation Foo -@synthesize x,w,q1,q2,oo,bcw,not_safe1,not_safe2,not_safe3; -@synthesize no_user_ivar1, no_user_ivar2; -@synthesize assign_plus1, assign_plus2, assign_plus3; -@synthesize def1, def2, def3; - --(void)test:(Foo *)parm { - assign_plus1 = [[Foo alloc] init]; - assign_plus2 = [Foo new]; - assign_plus3 = [parm retain]; -} -@end - -@interface TestExt -@property (retain,readonly) TestExt *x1; -@property (readonly) TestExt *x2; -@end - -@interface TestExt() -@property (retain,readwrite) TestExt *x1; -@property (readwrite) TestExt *x2; -@property (retain) TestExt *x3; -@end - -@implementation TestExt -@synthesize x1, x2, x3; -@end diff --git a/clang/test/ARCMT/assign-prop-with-arc-runtime.m.result b/clang/test/ARCMT/assign-prop-with-arc-runtime.m.result deleted file mode 100644 index 8bb684f79a339..0000000000000 --- a/clang/test/ARCMT/assign-prop-with-arc-runtime.m.result +++ /dev/null @@ -1,72 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -__attribute__((objc_arc_weak_reference_unavailable)) -@interface WeakOptOut -@end - -@class _NSCachedAttributedString; -typedef _NSCachedAttributedString *BadClassForWeak; - -@class Forw; - -@interface Foo : NSObject { - Foo *__weak x, *__weak w, *__weak q1, *__weak q2; - WeakOptOut *__unsafe_unretained oo; - BadClassForWeak __unsafe_unretained bcw; - id __unsafe_unretained not_safe1; - NSObject *__unsafe_unretained not_safe2; - Forw *__unsafe_unretained not_safe3; - Foo *assign_plus1; -} -@property (weak, readonly) Foo *x; -@property (weak) Foo *w; -@property (weak) Foo *q1, *q2; -@property (unsafe_unretained) WeakOptOut *oo; -@property (unsafe_unretained) BadClassForWeak bcw; -@property (unsafe_unretained) id not_safe1; -@property (unsafe_unretained) NSObject *not_safe2; -@property (unsafe_unretained) Forw *not_safe3; -@property (readonly) Foo *assign_plus1; -@property (readonly) Foo *assign_plus2; -@property (readonly) Foo *assign_plus3; - -@property (weak) Foo *no_user_ivar1; -@property (weak, readonly) Foo *no_user_ivar2; - -@property (strong) id def1; -@property (atomic,strong) id def2; -@property (strong,atomic) id def3; - -@end - -@implementation Foo -@synthesize x,w,q1,q2,oo,bcw,not_safe1,not_safe2,not_safe3; -@synthesize no_user_ivar1, no_user_ivar2; -@synthesize assign_plus1, assign_plus2, assign_plus3; -@synthesize def1, def2, def3; - --(void)test:(Foo *)parm { - assign_plus1 = [[Foo alloc] init]; - assign_plus2 = [Foo new]; - assign_plus3 = parm; -} -@end - -@interface TestExt -@property (strong,readonly) TestExt *x1; -@property (weak, readonly) TestExt *x2; -@end - -@interface TestExt() -@property (strong,readwrite) TestExt *x1; -@property (weak, readwrite) TestExt *x2; -@property (strong) TestExt *x3; -@end - -@implementation TestExt -@synthesize x1, x2, x3; -@end diff --git a/clang/test/ARCMT/atautorelease-2.m b/clang/test/ARCMT/atautorelease-2.m deleted file mode 100644 index b9bc106553259..0000000000000 --- a/clang/test/ARCMT/atautorelease-2.m +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; --release; -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; - - while (argc) { - [chunkPool release]; - return 0; - } - - [chunkPool drain]; - [pool drain]; - - return 0; -} diff --git a/clang/test/ARCMT/atautorelease-2.m.result b/clang/test/ARCMT/atautorelease-2.m.result deleted file mode 100644 index 205473380b739..0000000000000 --- a/clang/test/ARCMT/atautorelease-2.m.result +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; --release; -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - @autoreleasepool { - @autoreleasepool { - - while (argc) { - return 0; - } - - } - } - - return 0; -} diff --git a/clang/test/ARCMT/atautorelease-3.m b/clang/test/ARCMT/atautorelease-3.m deleted file mode 100644 index 87b80af9350eb..0000000000000 --- a/clang/test/ARCMT/atautorelease-3.m +++ /dev/null @@ -1,40 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; -- release; -@end - -void NSLog(id, ...); - -void test1(int x) { - // All this stuff get removed since nothing is happening inside. - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; - while (x) { - chunkPool = [[NSAutoreleasePool alloc] init]; - [chunkPool release]; - } - - [chunkPool drain]; - [pool drain]; -} - -void test2(int x) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; - while (x) { - chunkPool = [[NSAutoreleasePool alloc] init]; - ++x; - [chunkPool release]; - } - - [chunkPool drain]; - [pool drain]; -} diff --git a/clang/test/ARCMT/atautorelease-3.m.result b/clang/test/ARCMT/atautorelease-3.m.result deleted file mode 100644 index 801376a7e82bd..0000000000000 --- a/clang/test/ARCMT/atautorelease-3.m.result +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface NSAutoreleasePool -- drain; -+new; -+alloc; --init; --autorelease; -- release; -@end - -void NSLog(id, ...); - -void test1(int x) { - // All this stuff get removed since nothing is happening inside. -} - -void test2(int x) { - @autoreleasepool { - @autoreleasepool { - while (x) { - @autoreleasepool { - ++x; - } - } - - } - } -} diff --git a/clang/test/ARCMT/atautorelease-check.m b/clang/test/ARCMT/atautorelease-check.m deleted file mode 100644 index 5f8ffa8bc40ee..0000000000000 --- a/clang/test/ARCMT/atautorelease-check.m +++ /dev/null @@ -1,144 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 %s - -#if __has_feature(objc_arr) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -typedef struct _NSZone NSZone; -typedef int BOOL; -typedef unsigned NSUInteger; - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; - -- (NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; -@end - -@protocol NSMutableCopying -- (id)mutableCopyWithZone:(NSZone *)zone; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)allocWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; - -+ (id)copyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -+ (id)mutableCopyWithZone:(NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -extern void NSRecycleZone(NSZone *zone); - -NS_AUTOMATED_REFCOUNT_UNAVAILABLE -@interface NSAutoreleasePool : NSObject { // expected-note 13 {{marked unavailable here}} -@private - void *_token; - void *_reserved3; - void *_reserved2; - void *_reserved; -} - -+ (void)addObject:(id)anObject; - -- (void)addObject:(id)anObject; - -- (void)drain; - -@end - - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSAutoreleasePool *chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} - - while (argc) { - [chunkPool release]; - // the following pool was not released in this scope, don't touch it. - chunkPool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} - } - - [chunkPool drain]; - [pool drain]; - - return 0; -} - -void f(void) { - NSAutoreleasePool * pool; // expected-error {{'NSAutoreleasePool' is unavailable}} - - for (int i=0; i != 10; ++i) { - id x = pool; // We won't touch a NSAutoreleasePool if we can't safely - // remove all the references to it. - } - - pool = [[NSAutoreleasePool alloc] init]; // expected-error {{'NSAutoreleasePool' is unavailable}} - NSLog(@"%s", "YES"); - [pool release]; -} - -void f2(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - // 'x' is declared inside the "pool scope" but used outside it, if we create - // a @autorelease scope it will be undefined outside it so don't touch the pool. - int x = 0; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - ++x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} -} - -void f3(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - struct S { int x; }; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - struct S *var; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} - var->x = 0; -} - -void f4(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - enum { Bar }; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - int x = Bar; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} -} - -void f5(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // expected-error 2 {{'NSAutoreleasePool' is unavailable}} \ - // expected-note {{scope begins here}} - - typedef int Bar; // expected-note {{declared here}} - - [pool release]; // expected-note {{scope ends here}} - - Bar x; // expected-error {{a name is referenced outside the NSAutoreleasePool scope that it was declared in}} -} diff --git a/clang/test/ARCMT/atautorelease.m b/clang/test/ARCMT/atautorelease.m deleted file mode 100644 index a6aed146497b4..0000000000000 --- a/clang/test/ARCMT/atautorelease.m +++ /dev/null @@ -1,61 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - - if (argc) { - NSAutoreleasePool * pool = [NSAutoreleasePool new]; - NSLog(@"%s", "YES"); - [pool drain]; - } - [pool drain]; - - NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init]; - NSLog(@"%s", "YES"); - [pool1 release]; - - return 0; -} - -void f(void) { - NSAutoreleasePool *pool1; - - pool1 = [NSAutoreleasePool new]; - int x = 4; - - NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; - ++x; - [pool2 drain]; - - [pool1 release]; -} - -int UIApplicationMain(int argc, char *argv[]); - -int main2(int argc, char *argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - int result = UIApplicationMain(argc, argv); - [pool release]; - return result; -} - -@interface Foo : NSObject -@property (assign) id myProp; -@end - -@implementation Foo -@synthesize myProp; - --(void)test:(id)p { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - [pool drain]; - self.myProp = p; -} -@end diff --git a/clang/test/ARCMT/atautorelease.m.result b/clang/test/ARCMT/atautorelease.m.result deleted file mode 100644 index e24339a3b9e36..0000000000000 --- a/clang/test/ARCMT/atautorelease.m.result +++ /dev/null @@ -1,60 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - - @autoreleasepool { - - if (argc) { - @autoreleasepool { - NSLog(@"%s", "YES"); - } - } - } - - @autoreleasepool { - NSLog(@"%s", "YES"); - } - - return 0; -} - -void f(void) { - - @autoreleasepool { - int x = 4; - - @autoreleasepool { - ++x; - } - - } -} - -int UIApplicationMain(int argc, char *argv[]); - -int main2(int argc, char *argv[]) { - @autoreleasepool { - int result = UIApplicationMain(argc, argv); - return result; - } -} - -@interface Foo : NSObject -@property (unsafe_unretained) id myProp; -@end - -@implementation Foo -@synthesize myProp; - --(void)test:(id)p { - @autoreleasepool { - } - self.myProp = p; -} -@end diff --git a/clang/test/ARCMT/autoreleases.m b/clang/test/ARCMT/autoreleases.m deleted file mode 100644 index 7c046dc227a06..0000000000000 --- a/clang/test/ARCMT/autoreleases.m +++ /dev/null @@ -1,75 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface A : NSObject { -@package - id object; -} -@end - -@interface B : NSObject { - id _prop; - xpc_object_t _xpc_prop; -} -- (BOOL)containsSelf:(A*)a; -@property (retain) id prop; -@property (retain) xpc_object_t xpc_prop; -@end - -@implementation A -@end - -@implementation B -- (BOOL)containsSelf:(A*)a { - return a->object == self; -} - --(id) prop { - return _prop; -} --(void) setProp:(id) newVal { - [_prop autorelease]; - _prop = [newVal retain]; -} --(void) setProp2:(CFTypeRef) newVal { - [_prop autorelease]; - _prop = (id)CFRetain(newVal); -} - --(id) xpc_prop { - return _xpc_prop; -} --(void) setXpc_prop:(xpc_object_t) newVal { - [_xpc_prop autorelease]; - _xpc_prop = xpc_retain(newVal); -} -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - A *a = [[A new] autorelease]; - B *b = [[B new] autorelease]; - NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); - [pool drain]; - return 0; -} - -void test(A *prevVal, A *newVal) { - [prevVal autorelease]; - prevVal = [newVal retain]; -} - -id test2(A* val) { - [[val retain] autorelease]; - return val; -} - -void test3(void) { - id a = [[A alloc] init]; - [a autorelease]; -} diff --git a/clang/test/ARCMT/autoreleases.m.result b/clang/test/ARCMT/autoreleases.m.result deleted file mode 100644 index 29d00ea60deed..0000000000000 --- a/clang/test/ARCMT/autoreleases.m.result +++ /dev/null @@ -1,69 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface A : NSObject { -@package - id object; -} -@end - -@interface B : NSObject { - id _prop; - xpc_object_t _xpc_prop; -} -- (BOOL)containsSelf:(A*)a; -@property (strong) id prop; -@property (strong) xpc_object_t xpc_prop; -@end - -@implementation A -@end - -@implementation B -- (BOOL)containsSelf:(A*)a { - return a->object == self; -} - --(id) prop { - return _prop; -} --(void) setProp:(id) newVal { - _prop = newVal; -} --(void) setProp2:(CFTypeRef) newVal { - _prop = (id)CFBridgingRelease(CFRetain(newVal)); -} - --(id) xpc_prop { - return _xpc_prop; -} --(void) setXpc_prop:(xpc_object_t) newVal { - _xpc_prop = newVal; -} -@end - -void NSLog(id, ...); - -int main (int argc, const char * argv[]) { - @autoreleasepool { - A *a = [A new]; - B *b = [B new]; - NSLog(@"%s", [b containsSelf:a] ? "YES" : "NO"); - } - return 0; -} - -void test(A *prevVal, A *newVal) { - prevVal = newVal; -} - -id test2(A* val) { - return val; -} - -void test3(void) { - id a = [[A alloc] init]; -} diff --git a/clang/test/ARCMT/block_copy_release.m b/clang/test/ARCMT/block_copy_release.m deleted file mode 100644 index ae3b82660a8e4..0000000000000 --- a/clang/test/ARCMT/block_copy_release.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef void (^blk)(int); - -void func(blk b) { - blk c = Block_copy(b); - Block_release(c); -} - -void func2(id b) { - id c = Block_copy(b); - Block_release(c); -} diff --git a/clang/test/ARCMT/block_copy_release.m.result b/clang/test/ARCMT/block_copy_release.m.result deleted file mode 100644 index b292b64f17d6b..0000000000000 --- a/clang/test/ARCMT/block_copy_release.m.result +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef void (^blk)(int); - -void func(blk b) { - blk c = [b copy]; -} - -void func2(id b) { - id c = [b copy]; -} diff --git a/clang/test/ARCMT/check-api.m b/clang/test/ARCMT/check-api.m deleted file mode 100644 index b395f0b4a4b97..0000000000000 --- a/clang/test/ARCMT/check-api.m +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-macosx10.7 %s - -#include "Common.h" - -@interface NSInvocation : NSObject -- (void)getReturnValue:(void *)retLoc; -- (void)setReturnValue:(void *)retLoc; - -- (void)getArgument:(void *)argumentLocation atIndex:(int)idx; -- (void)setArgument:(void *)argumentLocation atIndex:(int)idx; -@end - -@interface Test -@end - -@implementation Test { - id strong_id; - __weak id weak_id; - __unsafe_unretained id unsafe_id; - int arg; -} -- (void) test:(NSInvocation *)invok { - [invok getReturnValue:&strong_id]; // expected-error {{NSInvocation's getReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getReturnValue:&weak_id]; // expected-error {{NSInvocation's getReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getReturnValue:&unsafe_id]; - [invok getReturnValue:&arg]; - - [invok setReturnValue:&strong_id]; // expected-error {{NSInvocation's setReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setReturnValue:&weak_id]; // expected-error {{NSInvocation's setReturnValue is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setReturnValue:&unsafe_id]; - [invok setReturnValue:&arg]; - - [invok getArgument:&strong_id atIndex:0]; // expected-error {{NSInvocation's getArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getArgument:&weak_id atIndex:0]; // expected-error {{NSInvocation's getArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok getArgument:&unsafe_id atIndex:0]; - [invok getArgument:&arg atIndex:0]; - - [invok setArgument:&strong_id atIndex:0]; // expected-error {{NSInvocation's setArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setArgument:&weak_id atIndex:0]; // expected-error {{NSInvocation's setArgument is not safe to be used with an object with ownership other than __unsafe_unretained}} - [invok setArgument:&unsafe_id atIndex:0]; - [invok setArgument:&arg atIndex:0]; -} -@end diff --git a/clang/test/ARCMT/check-with-pch.m b/clang/test/ARCMT/check-with-pch.m deleted file mode 100644 index c2fda3b52cbc9..0000000000000 --- a/clang/test/ARCMT/check-with-pch.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -include-pch %t.pch -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s -// REQUIRES: x86-registered-target - -@interface I9601437 { - __unsafe_unretained id x; -} --(void)Meth; -@end - -@implementation I9601437 --(void)Meth { - self->x = [NSObject new]; // expected-error {{assigning retained object}} -} -@end diff --git a/clang/test/ARCMT/check-with-serialized-diag.m b/clang/test/ARCMT/check-with-serialized-diag.m deleted file mode 100644 index 6102be037fcc1..0000000000000 --- a/clang/test/ARCMT/check-with-serialized-diag.m +++ /dev/null @@ -1,55 +0,0 @@ - -@protocol NSObject -- (id)retain; -- (unsigned)retainCount; -- (oneway void)release; -- (id)autorelease; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -@interface A : NSObject -@end - -struct UnsafeS { - A *__unsafe_unretained unsafeObj; -}; - -id global_foo; - -void test1(A *a, struct UnsafeS *unsafeS) { - [unsafeS->unsafeObj retain]; - id foo = [unsafeS->unsafeObj retain]; // no warning. - [global_foo retain]; - [a retainCount]; -} - -// RUN: not %clang_cc1 -arcmt-action=check -triple x86_64-apple-darwin10 %s -serialize-diagnostic-file %t.diag -// RUN: c-index-test -read-diagnostics %t.diag > %t 2>&1 -// RUN: FileCheck --input-file=%t %s - -// CHECK: {{.*}}check-with-serialized-diag.m:32:4: error: [rewriter] it is not safe to remove 'retain' message on an __unsafe_unretained type -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:4: error: [rewriter] it is not safe to remove 'retain' message on a global variable -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:32:23: error: ARC forbids explicit message send of 'retain' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:32:4 {{.*}}check-with-serialized-diag.m:32:22 -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:34:15: error: ARC forbids explicit message send of 'retain' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:34:4 {{.*}}check-with-serialized-diag.m:34:14 -// CHECK-NEXT: Number FIXITs = 0 -// CHECK-NEXT: {{.*}}check-with-serialized-diag.m:35:6: error: ARC forbids explicit message send of 'retainCount' -// CHECK-NEXT: Range: {{.*}}check-with-serialized-diag.m:35:4 {{.*}}check-with-serialized-diag.m:35:5 -// CHECK-NEXT: Number FIXITs = 0 - diff --git a/clang/test/ARCMT/checking-in-arc.m b/clang/test/ARCMT/checking-in-arc.m deleted file mode 100644 index 1bf6aca18a342..0000000000000 --- a/clang/test/ARCMT/checking-in-arc.m +++ /dev/null @@ -1,50 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -fobjc-arc -fobjc-runtime=macosx-10.8.0 -triple x86_64-apple-darwin12 -fblocks -Werror %s - -#if __has_feature(objc_arc) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -typedef int BOOL; -typedef unsigned NSUInteger; - -@protocol NSObject -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -@class NSString; - -@interface Test : NSObject -@property (weak) NSString *weakProperty; -@end - -@implementation Test -@end - -#if ! __has_feature(objc_arc) -#error This file must be compiled with ARC (set -fobjc_arc flag on file) -#endif diff --git a/clang/test/ARCMT/checking.m b/clang/test/ARCMT/checking.m deleted file mode 100644 index 5bc456c6301c0..0000000000000 --- a/clang/test/ARCMT/checking.m +++ /dev/null @@ -1,351 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s - -#if __has_feature(objc_arc) -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) -#else -#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE -#endif - -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -typedef int BOOL; -typedef unsigned NSUInteger; - -@protocol NSObject -- (id)retain NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (NSUInteger)retainCount NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (oneway void)release NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -- (id)autorelease NS_AUTOMATED_REFCOUNT_UNAVAILABLE; -@end - -@interface NSObject {} -- (id)init; - -+ (id)new; -+ (id)alloc; -- (void)dealloc; - -- (void)finalize; - -- (id)copy; -- (id)mutableCopy; -@end - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -@class NSString; -@class A; - -struct UnsafeS { - A *__unsafe_unretained unsafeObj; -}; - -@interface A : NSObject -- (id)retain __attribute__((unavailable)); // expected-note {{'retain' has been explicitly marked unavailable here}} -- (id)retainCount __attribute__((unavailable)); // expected-note {{'retainCount' has been explicitly marked unavailable here}} -- (id)autorelease __attribute__((unavailable)); // expected-note 2 {{'autorelease' has been explicitly marked unavailable here}} -- (id)init; -- (oneway void)release; -- (void)dealloc; --(void)test; --(id)delegate; -@end - -@implementation A --(void)test { - [super dealloc]; -} --(void)dealloc { - [super dealloc]; -} - -- (id)retain { return self; } // expected-error {{ARC forbids implementation}} -- (id)retainCount { return self; } // expected-error {{ARC forbids implementation}} -- (id)autorelease { return self; } // expected-error {{ARC forbids implementation}} -- (oneway void)release { } // expected-error {{ARC forbids implementation}} - --(id)delegate { return self; } -@end - -id global_foo; - -void test1(A *a, BOOL b, struct UnsafeS *unsafeS) { - [[a delegate] release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ - // expected-error {{ARC forbids explicit message send}} - [a.delegate release]; // expected-error {{it is not safe to remove 'retain' message on the result of a 'delegate' message; the object that was passed to 'setDelegate:' may not be properly retained}} \ - // expected-error {{ARC forbids explicit message send}} - [unsafeS->unsafeObj retain]; // expected-error {{it is not safe to remove 'retain' message on an __unsafe_unretained type}} \ - // expected-error {{ARC forbids explicit message send}} \ - // expected-error {{'retain' is unavailable}} - id foo = [unsafeS->unsafeObj retain]; // no warning. - [global_foo retain]; // expected-error {{it is not safe to remove 'retain' message on a global variable}} \ - // expected-error {{ARC forbids explicit message send}} - [global_foo release]; // expected-error {{it is not safe to remove 'release' message on a global variable}} \ - // expected-error {{ARC forbids explicit message send}} - [a dealloc]; - [a retain]; - [a retainCount]; // expected-error {{ARC forbids explicit message send of 'retainCount'}} \ - // expected-error {{'retainCount' is unavailable}} - [a release]; - [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ - // expected-error {{ARC forbids explicit message send}} \ - // expected-error {{'autorelease' is unavailable}} - [a autorelease]; // expected-error {{it is not safe to remove an unused 'autorelease' message; its receiver may be destroyed immediately}} \ - // expected-error {{ARC forbids explicit message send}} \ - // expected-error {{'autorelease' is unavailable}} - a = 0; - - CFStringRef cfstr; - NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} \ - str = (NSString *)kUTTypePlainText; - str = b ? kUTTypeRTF : kUTTypePlainText; - str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); - str = (NSString *)a; // no change. - - SEL s = @selector(retain); // expected-error {{ARC forbids use of 'retain' in a @selector}} - s = @selector(release); // expected-error {{ARC forbids use of 'release' in a @selector}} - s = @selector(autorelease); // expected-error {{ARC forbids use of 'autorelease' in a @selector}} - s = @selector(dealloc); // expected-error {{ARC forbids use of 'dealloc' in a @selector}} - - static id __autoreleasing X1; // expected-error {{global variables cannot have __autoreleasing ownership}} -} - -struct S { - A* a; -}; - -@interface B --(id)alloc; -- (id)initWithInt: (int) i; -@end - -void rdar8861761(void) { - B *o1 = [[B alloc] initWithInt:0]; - B *o2 = [B alloc]; - [o2 initWithInt:0]; -} - -@interface Test13 -- (id) init0; -- (void) noninit; -@end -@implementation Test13 -- (id) init0 { - self = 0; -} -- (void) noninit { - self = 0; // expected-error {{cannot assign to 'self' outside of a method in the init family}} - - for (__strong id x in collection) { // expected-error {{use of undeclared identifier 'collection'}} - x = 0; - } -} -@end - -void * cvt(id arg) -{ - void* voidp_val; - (void)(int*)arg; // expected-error {{disallowed}} - (void)(id)arg; - (void)(__autoreleasing id*)arg; // expected-error {{disallowed}} - (void)(id*)arg; // expected-error {{disallowed}} - - (void)(__autoreleasing id**)voidp_val; - (void)(void*)voidp_val; - (void)(void**)arg; // expected-error {{disallowed}} - cvt((void*)arg); // expected-error 2 {{requires a bridged cast}} \ - // expected-note 2 {{use __bridge to}} expected-note {{use CFBridgingRelease call}} expected-note {{use CFBridgingRetain call}} - cvt(0); - (void)(__strong id**)(0); - return arg; // expected-error {{requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}} -} - - -void test12(id collection) { - for (id x in collection) { - x = 0; - } - - for (__strong id x in collection) { - x = 0; - } -} - -void test6(unsigned cond) { - switch (cond) { - case 0: - ; - id x; // expected-note {{jump bypasses initialization of __strong variable}} - - case 1: // expected-error {{cannot jump}} - x = 0; - break; - } -} - -@class Test8_incomplete; -@interface Test8_complete @end; -@interface Test8_super @end; -@interface Test8 : Test8_super -- (id) init00; -- (id) init01; // expected-note {{declaration in interface}} -- (id) init02; -- (id) init03; // covariance -- (id) init04; // covariance -- (id) init05; - -- (void) init10; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} -- (void) init11; -- (void) init12; -- (void) init13; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} -- (void) init14; // expected-note {{declaration in interface is not in the 'init' family because its result type is not an object pointer}} -- (void) init15; - -// These should be invalid to actually call. -- (Test8_incomplete*) init20; -- (Test8_incomplete*) init21; // expected-note {{declaration in interface}} -- (Test8_incomplete*) init22; -- (Test8_incomplete*) init23; -- (Test8_incomplete*) init24; -- (Test8_incomplete*) init25; - -- (Test8_super*) init30; // id exception to covariance -- (Test8_super*) init31; // expected-note {{declaration in interface}} -- (Test8_super*) init32; -- (Test8_super*) init33; -- (Test8_super*) init34; // covariance -- (Test8_super*) init35; - -- (Test8*) init40; // id exception to covariance -- (Test8*) init41; // expected-note {{declaration in interface}} -- (Test8*) init42; -- (Test8*) init43; // this should be a warning, but that's a general language thing, not an ARC thing -- (Test8*) init44; -- (Test8*) init45; - -- (Test8_complete*) init50; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init51; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init52; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init53; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init54; // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init55; // expected-error {{init methods must return a type related to the receiver type}} -@end -@implementation Test8 -- (id) init00 { return 0; } -- (id) init10 { return 0; } // expected-error {{method implementation does not match its declaration}} -- (id) init20 { return 0; } -- (id) init30 { return 0; } -- (id) init40 { return 0; } -- (id) init50 { return 0; } - -- (void) init01 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init11 {} -- (void) init21 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init31 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init41 {} // expected-error {{method was declared as an 'init' method, but its implementation doesn't match because its result type is not an object pointer}} -- (void) init51 {} - -- (Test8_incomplete*) init02 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init12 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init22 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init32 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init42 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_incomplete*) init52 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} - -- (Test8_super*) init03 { return 0; } -- (Test8_super*) init13 { return 0; } // expected-error {{method implementation does not match its declaration}} -- (Test8_super*) init23 { return 0; } -- (Test8_super*) init33 { return 0; } -- (Test8_super*) init43 { return 0; } -- (Test8_super*) init53 { return 0; } - -- (Test8*) init04 { return 0; } -- (Test8*) init14 { return 0; } // expected-error {{method implementation does not match its declaration}} -- (Test8*) init24 { return 0; } -- (Test8*) init34 { return 0; } -- (Test8*) init44 { return 0; } -- (Test8*) init54 { return 0; } - -- (Test8_complete*) init05 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init15 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init25 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init35 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init45 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -- (Test8_complete*) init55 { return 0; } // expected-error {{init methods must return a type related to the receiver type}} -@end - -@class Test9_incomplete; -@interface Test9 -- (Test9_incomplete*) init1; // expected-error {{init methods must return a type related to the receiver type}} -- (Test9_incomplete*) init2; -@end -id test9(Test9 *v) { - return [v init1]; -} - -void rdar9491791(int p) { - switch (p) { - case 3:; - NSObject *o = [[NSObject alloc] init]; - [o release]; - break; - default: - break; - } -} - -#define RELEASE_MACRO(x) do { [x release]; } while(1) - -void rdar9504750(id p) { - RELEASE_MACRO(p); // expected-error {{ARC forbids explicit message send of 'release'}} -} - -@interface TestReadonlyProperty : NSObject -@property(assign,readonly) NSObject *value; -@end - -@implementation TestReadonlyProperty -@synthesize value; -- (void)viewDidLoad { - value = [NSObject new]; // expected-error {{assigning retained object}} -} -@end - -@interface I9601437 { - __unsafe_unretained id x; -} --(void)Meth; -@end - -@implementation I9601437 --(void)Meth { - self->x = [NSObject new]; // expected-error {{assigning retained object}} -} -@end - -@interface Test10 : NSObject { - CFStringRef cfstr; -} -@property (retain) id prop; --(void)foo; -@end - -void test(Test10 *x) { - x.prop = ^{ [x foo]; }; // expected-warning {{likely to lead to a retain cycle}} \ - // expected-note {{retained by the captured object}} -} - -@implementation Test10 --(void)foo { - ^{ - NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} - }; -} -@end diff --git a/clang/test/ARCMT/cxx-checking.mm b/clang/test/ARCMT/cxx-checking.mm deleted file mode 100644 index f8836d9d7cd8d..0000000000000 --- a/clang/test/ARCMT/cxx-checking.mm +++ /dev/null @@ -1,100 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 -fsyntax-only -fblocks %s - -// Classes that have an Objective-C object pointer. -struct HasObjectMember0 { - id x; -}; - -struct HasObjectMember1 { - id x[3]; -}; - -struct HasObjectMember2 { - id x[3][2]; -}; - -// Don't complain if the type has non-external linkage -namespace { - struct HasObjectMember3 { - id x[3][2]; - }; -} - -// Don't complain if the Objective-C pointer type was explicitly given -// no lifetime. -struct HasObjectMember3 { - __unsafe_unretained id x[3][2]; -}; - -struct HasBlockPointerMember0 { - int (^bp)(int); -}; - -struct HasBlockPointerMember1 { - int (^bp[2][3])(int); -}; - -struct NonPOD { - NonPOD(const NonPOD&); -}; - -struct HasObjectMemberAndNonPOD0 { - id x; - NonPOD np; -}; - -struct HasObjectMemberAndNonPOD1 { - NonPOD np; - id x[3]; -}; - -struct HasObjectMemberAndNonPOD2 { - NonPOD np; - id x[3][2]; -}; - -struct HasObjectMemberAndNonPOD3 { - HasObjectMemberAndNonPOD3 &operator=(const HasObjectMemberAndNonPOD3&); - ~HasObjectMemberAndNonPOD3(); - NonPOD np; - id x[3][2]; -}; - -struct HasBlockPointerMemberAndNonPOD0 { - NonPOD np; - int (^bp)(int); -}; - -struct HasBlockPointerMemberAndNonPOD1 { - NonPOD np; - int (^bp[2][3])(int); -}; - -int check_non_pod_objc_pointer0[__is_pod(id)? 1 : -1]; -int check_non_pod_objc_pointer1[__is_pod(__strong id)? -1 : 1]; -int check_non_pod_objc_pointer2[__is_pod(__unsafe_unretained id)? 1 : -1]; -int check_non_pod_objc_pointer3[__is_pod(id[2][3])? 1 : -1]; -int check_non_pod_objc_pointer4[__is_pod(__unsafe_unretained id[2][3])? 1 : -1]; -int check_non_pod_block0[__is_pod(int (^)(int))? 1 : -1]; -int check_non_pod_block1[__is_pod(int (^ __unsafe_unretained)(int))? 1 : -1]; - -struct FlexibleArrayMember0 { - int length; - id array[]; // expected-error{{flexible array member 'array' of type '__strong id[]' with non-trivial destruction}} -}; - -struct FlexibleArrayMember1 { - int length; - __unsafe_unretained id array[]; -}; - -// It's okay to pass a retainable type through an ellipsis. -void variadic(...); -void test_variadic() { - variadic(1, 17, @"Foo"); -} - -// It's okay to create a VLA of retainable types. -void vla(int n) { - id vla[n]; -} diff --git a/clang/test/ARCMT/cxx-rewrite.mm b/clang/test/ARCMT/cxx-rewrite.mm deleted file mode 100644 index 4a9c50c92426e..0000000000000 --- a/clang/test/ARCMT/cxx-rewrite.mm +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c++ %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface NSString : NSObject -+(id)string; -@end - -struct foo { - NSString *s; - foo(NSString *s): s([s retain]){ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [[[NSString string] retain] release]; - [pool drain]; - if (s) - [s release]; - } - ~foo(){ [s release]; } -private: - foo(foo const &); - foo &operator=(foo const &); -}; - -int main(){ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - - foo f([[NSString string] autorelease]); - - [pool drain]; - return 0; -} diff --git a/clang/test/ARCMT/cxx-rewrite.mm.result b/clang/test/ARCMT/cxx-rewrite.mm.result deleted file mode 100644 index a96d254bf4633..0000000000000 --- a/clang/test/ARCMT/cxx-rewrite.mm.result +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c++ %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface NSString : NSObject -+(id)string; -@end - -struct foo { - NSString *s; - foo(NSString *s): s(s){ - @autoreleasepool { - [NSString string]; - } - } - ~foo(){ } -private: - foo(foo const &); - foo &operator=(foo const &); -}; - -int main(){ - @autoreleasepool { - - foo f([NSString string]); - - } - return 0; -} diff --git a/clang/test/ARCMT/dealloc.m b/clang/test/ARCMT/dealloc.m deleted file mode 100644 index d7a72af4f726f..0000000000000 --- a/clang/test/ARCMT/dealloc.m +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface A -- (id)retain; -- (id)autorelease; -- (oneway void)release; -- (void)dealloc; -@end - -void test1(A *a) { - [a dealloc]; -} - -@interface Test2 : A -- (void) dealloc; -@end - -@implementation Test2 -- (void) dealloc { - [super dealloc]; -} -@end diff --git a/clang/test/ARCMT/dealloc.m.result b/clang/test/ARCMT/dealloc.m.result deleted file mode 100644 index fbd9e445d2751..0000000000000 --- a/clang/test/ARCMT/dealloc.m.result +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface A -- (id)retain; -- (id)autorelease; -- (oneway void)release; -- (void)dealloc; -@end - -void test1(A *a) { -} - -@interface Test2 : A -- (void) dealloc; -@end - -@implementation Test2 -@end diff --git a/clang/test/ARCMT/designated-init-in-header/designated-init-in-header.m b/clang/test/ARCMT/designated-init-in-header/designated-init-in-header.m deleted file mode 100644 index 8286583b3c898..0000000000000 --- a/clang/test/ARCMT/designated-init-in-header/designated-init-in-header.m +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %clang_cc1 -objcmt-migrate-designated-init -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -x objective-c %S/file1.m.in -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t1.remap -// RUN: %clang_cc1 -objcmt-migrate-designated-init -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -x objective-c %S/file2.m.in -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t2.remap -// RUN: c-arcmt-test %t1.remap %t2.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/file2.m.in.result diff --git a/clang/test/ARCMT/designated-init-in-header/file1.m.in b/clang/test/ARCMT/designated-init-in-header/file1.m.in deleted file mode 100644 index 0201b32abd323..0000000000000 --- a/clang/test/ARCMT/designated-init-in-header/file1.m.in +++ /dev/null @@ -1,2 +0,0 @@ -#include "header1.h" - diff --git a/clang/test/ARCMT/designated-init-in-header/file2.m.in b/clang/test/ARCMT/designated-init-in-header/file2.m.in deleted file mode 100644 index 258159735a77f..0000000000000 --- a/clang/test/ARCMT/designated-init-in-header/file2.m.in +++ /dev/null @@ -1,14 +0,0 @@ -#include "header1.h" - -@implementation S1 --(int)prop { return 0; } --(void)setProp:(int)p {} -+(id)s1 { return 0; } --(id)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/designated-init-in-header/file2.m.in.result b/clang/test/ARCMT/designated-init-in-header/file2.m.in.result deleted file mode 100644 index 7465ed576f5ff..0000000000000 --- a/clang/test/ARCMT/designated-init-in-header/file2.m.in.result +++ /dev/null @@ -1,14 +0,0 @@ -#include "header1.h" - -@implementation S1 --(int)prop { return 0; } --(void)setProp:(int)p {} -+(instancetype)s1 { return 0; } --(instancetype)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/designated-init-in-header/header1.h b/clang/test/ARCMT/designated-init-in-header/header1.h deleted file mode 100644 index c5668cc460869..0000000000000 --- a/clang/test/ARCMT/designated-init-in-header/header1.h +++ /dev/null @@ -1,14 +0,0 @@ -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(id)init; -@end - -@interface S1 : B1 --(int)prop; --(void)setProp:(int)p; -+(id)s1; --(id)initWithFoo:(NSString*)foo; -@end diff --git a/clang/test/ARCMT/designated-init-in-header/header1.h.result b/clang/test/ARCMT/designated-init-in-header/header1.h.result deleted file mode 100644 index 974175b1c3e63..0000000000000 --- a/clang/test/ARCMT/designated-init-in-header/header1.h.result +++ /dev/null @@ -1,13 +0,0 @@ -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(instancetype)init; -@end - -@interface S1 : B1 -@property (nonatomic) int prop; -+(instancetype)s1; --(instancetype)initWithFoo:(NSString*)foo NS_DESIGNATED_INITIALIZER; -@end diff --git a/clang/test/ARCMT/dispatch.m b/clang/test/ARCMT/dispatch.m deleted file mode 100644 index 58c7769638cbe..0000000000000 --- a/clang/test/ARCMT/dispatch.m +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -dispatch_object_t getme(void); - -void func(dispatch_object_t o) { - dispatch_retain(o); - dispatch_release(o); - dispatch_retain(getme()); -} - -void func2(xpc_object_t o) { - xpc_retain(o); - xpc_release(o); -} diff --git a/clang/test/ARCMT/dispatch.m.result b/clang/test/ARCMT/dispatch.m.result deleted file mode 100644 index 55b65585e4f6c..0000000000000 --- a/clang/test/ARCMT/dispatch.m.result +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -dispatch_object_t getme(void); - -void func(dispatch_object_t o) { - getme(); -} - -void func2(xpc_object_t o) { -} diff --git a/clang/test/ARCMT/driver-migrate.m b/clang/test/ARCMT/driver-migrate.m deleted file mode 100644 index ec3f4cc8c4a31..0000000000000 --- a/clang/test/ARCMT/driver-migrate.m +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %clang -### -ccc-arcmt-migrate /foo/bar -fsyntax-only %s 2>&1 | FileCheck %s - -// CHECK: "-arcmt-action=migrate" "-mt-migrate-directory" "{{[^"]*}}/foo/bar" - -// RUN: touch %t.o -// RUN: %clang -ccc-arcmt-check -target i386-apple-darwin9 -### %t.o 2> %t.log -// RUN: FileCheck -check-prefix=LINK %s < %t.log -// RUN: %clang -ccc-arcmt-migrate /foo/bar -target i386-apple-darwin9 -### %t.o 2> %t.log -// RUN: FileCheck -check-prefix=LINK %s < %t.log - -// LINK-NOT: {{ld(.exe)?"}} -// LINK: {{touch(.exe)?"}} - -// RUN: %clang -### -ccc-arcmt-migrate /foo/bar -fsyntax-only -fno-objc-arc %s 2>&1 | FileCheck -check-prefix=CHECK-NOARC %s -// CHECK-NOARC-NOT: argument unused during compilation diff --git a/clang/test/ARCMT/init.m b/clang/test/ARCMT/init.m deleted file mode 100644 index b1f127e54fd1b..0000000000000 --- a/clang/test/ARCMT/init.m +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil (void *)0 - -@interface NSObject --init; -@end - -@interface A : NSObject --init; --init2; --foo; -+alloc; -@end - -@implementation A --(id) init { - [self init]; - id a; - [a init]; - a = [[A alloc] init]; - - return self; -} - --(id) init2 { - [super init]; - return self; -} - --(id) foo { - [self init]; - [super init]; - - return self; -} -@end diff --git a/clang/test/ARCMT/init.m.result b/clang/test/ARCMT/init.m.result deleted file mode 100644 index d550dedb1dc19..0000000000000 --- a/clang/test/ARCMT/init.m.result +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil (void *)0 - -@interface NSObject --init; -@end - -@interface A : NSObject --init; --init2; --foo; -+alloc; -@end - -@implementation A --(id) init { - if (!(self = [self init])) return nil; - id a; - [a init]; - a = [[A alloc] init]; - - return self; -} - --(id) init2 { - if (!(self = [super init])) return nil; - return self; -} - --(id) foo { - [self init]; - [super init]; - - return self; -} -@end diff --git a/clang/test/ARCMT/lit.local.cfg b/clang/test/ARCMT/lit.local.cfg deleted file mode 100644 index e9b04164d69df..0000000000000 --- a/clang/test/ARCMT/lit.local.cfg +++ /dev/null @@ -1,2 +0,0 @@ -if not config.root.clang_arcmt: - config.unsupported = True diff --git a/clang/test/ARCMT/migrate-emit-errors.m b/clang/test/ARCMT/migrate-emit-errors.m deleted file mode 100644 index 3e33acf75a591..0000000000000 --- a/clang/test/ARCMT/migrate-emit-errors.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t -arcmt-migrate-emit-errors %s 2>&1 | FileCheck %s -// RUN: rm -rf %t - -@protocol NSObject -- (oneway void)release; -@end - -void test(id p) { - [p release]; -} - -// CHECK: error: ARC forbids explicit message send of 'release' diff --git a/clang/test/ARCMT/migrate-on-pch-and-module.m b/clang/test/ARCMT/migrate-on-pch-and-module.m deleted file mode 100644 index 42e01ea91a9c7..0000000000000 --- a/clang/test/ARCMT/migrate-on-pch-and-module.m +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: rm -rf %t-mcp -// RUN: %clang_cc1 -objcmt-migrate-subscripting -emit-pch -o %t.pch %s -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -F %S/Inputs -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp -w -// RUN: %clang_cc1 -objcmt-migrate-subscripting -include-pch %t.pch %s -migrate -o %t.remap -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -F %S/Inputs -fmodules -fimplicit-module-maps -fmodules-cache-path=%t-mcp -// REQUIRES: x86-registered-target -#ifndef HEADER -#define HEADER - -@import Module; - -#else - -#endif diff --git a/clang/test/ARCMT/migrate-plist-output.m b/clang/test/ARCMT/migrate-plist-output.m deleted file mode 100644 index e5710d818eccc..0000000000000 --- a/clang/test/ARCMT/migrate-plist-output.m +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t.dir -arcmt-migrate-report-output %t.plist %s -// RUN: FileCheck %s -input-file=%t.plist -// RUN: rm -rf %t.dir - -@protocol NSObject -- (oneway void)release; -@end - -void test(id p) { - [p release]; -} - -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: files -// CHECK: -// CHECK: -// CHECK: diagnostics -// CHECK: -// CHECK: -// CHECK: descriptionARC forbids explicit message send of 'release' -// CHECK: categoryARC Restrictions -// CHECK: typeerror -// CHECK: location -// CHECK: -// CHECK: line10 -// CHECK: col6 -// CHECK: file0 -// CHECK: -// CHECK: ranges -// CHECK: -// CHECK: -// CHECK: -// CHECK: line10 -// CHECK: col4 -// CHECK: file0 -// CHECK: -// CHECK: -// CHECK: line10 -// CHECK: col4 -// CHECK: file0 -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: -// CHECK: - diff --git a/clang/test/ARCMT/migrate-space-in-path.m b/clang/test/ARCMT/migrate-space-in-path.m deleted file mode 100644 index 14a464d438f40..0000000000000 --- a/clang/test/ARCMT/migrate-space-in-path.m +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: rm -rf %t.migrate -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t.migrate %S/Inputs/"with space"/test1.m.in -x objective-c -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t.migrate %S/Inputs/"with space"/test2.m.in -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t.migrate | arcmt-test -verify-transformed-files %S/Inputs/"with space"/test1.m.in.result %S/Inputs/"with space"/test2.m.in.result %S/Inputs/"with space"/test.h.result -// RUN: rm -rf %t.migrate diff --git a/clang/test/ARCMT/migrate-with-pch.m b/clang/test/ARCMT/migrate-with-pch.m deleted file mode 100644 index d8e261be13d85..0000000000000 --- a/clang/test/ARCMT/migrate-with-pch.m +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c -include-pch %t.pch -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c -include-pch %t.pch -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result -// RUN: rm -rf %t diff --git a/clang/test/ARCMT/migrate.m b/clang/test/ARCMT/migrate.m deleted file mode 100644 index bc819df1c8a11..0000000000000 --- a/clang/test/ARCMT/migrate.m +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c -// RUN: %clang_cc1 -arcmt-action=migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result -// RUN: rm -rf %t diff --git a/clang/test/ARCMT/no-canceling-bridge-to-bridge-cast.m b/clang/test/ARCMT/no-canceling-bridge-to-bridge-cast.m deleted file mode 100644 index be49394951523..0000000000000 --- a/clang/test/ARCMT/no-canceling-bridge-to-bridge-cast.m +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -verify %s -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -extern -CFTypeRef CFRetain(CFTypeRef cf); - -@interface INTF -{ - void *cf_format; - id objc_format; -} -@end - -@interface NSString -+ (id)stringWithFormat:(NSString *)format; -@end - -@implementation INTF -- (void) Meth { - NSString *result; - - result = (id) CFRetain([NSString stringWithFormat:@"PBXLoopMode"]); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} - - result = (id) CFRetain((id)((objc_format))); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} - - result = (id) CFRetain((id)((cf_format))); // expected-error {{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note {{use __bridge to convert directly (no change in ownership)}} \ - // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}} - - result = (id) CFRetain((CFTypeRef)((objc_format))); - - result = (id) CFRetain(cf_format); // OK -} -@end - diff --git a/clang/test/ARCMT/nonobjc-to-objc-cast-2.m b/clang/test/ARCMT/nonobjc-to-objc-cast-2.m deleted file mode 100644 index 391c636906d53..0000000000000 --- a/clang/test/ARCMT/nonobjc-to-objc-cast-2.m +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify -triple x86_64-apple-darwin10 %s - -#include "Common.h" - -typedef const struct __CFString * CFStringRef; -typedef const void * CFTypeRef; -CFTypeRef CFBridgingRetain(id X); -id CFBridgingRelease(CFTypeRef); - -struct StrS { - CFStringRef sref_member; -}; - -@interface NSString : NSObject { - CFStringRef sref; - struct StrS *strS; -} --(id)string; --(id)newString; -@end - -@implementation NSString --(id)string { - if (0) - return sref; - else - return strS->sref_member; -} --(id)newString { - return sref; // expected-error {{implicit conversion of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'id' requires a bridged cast}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} -} -@end - -void f(BOOL b) { - CFStringRef cfstr; - NSString *str = (NSString *)cfstr; // expected-error {{cast of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}} - void *vp = str; // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRetain call}} expected-note {{use __bridge}} -} - -void f2(NSString *s) { - CFStringRef ref; - ref = [(CFStringRef)[s string] retain]; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFStringRef' (aka 'const struct __CFString *') requires a bridged cast}} \ - // expected-error {{bad receiver type 'CFStringRef' (aka 'const struct __CFString *')}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFStringRef' (aka 'const struct __CFString *')}} -} - -CFStringRef f3(void) { - return (CFStringRef)[[[NSString alloc] init] autorelease]; // expected-error {{it is not safe to cast to 'CFStringRef' the result of 'autorelease' message; a __bridge cast may result in a pointer to a destroyed object and a __bridge_retained may leak the object}} \ - // expected-note {{remove the cast and change return type of function to 'NSString *' to have the object automatically autoreleased}} -} - -extern void NSLog(NSString *format, ...); - -void f4(NSString *s) { - NSLog(@"%@", (CFStringRef)s); // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFStringRef' (aka 'const struct __CFString *') requires a bridged cast}} \ - // expected-note{{use __bridge to convert directly (no change in ownership)}} \ - // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFStringRef' (aka 'const struct __CFString *')}} -} diff --git a/clang/test/ARCMT/nonobjc-to-objc-cast.m b/clang/test/ARCMT/nonobjc-to-objc-cast.m deleted file mode 100644 index 7913661787e50..0000000000000 --- a/clang/test/ARCMT/nonobjc-to-objc-cast.m +++ /dev/null @@ -1,83 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -extern CFStringRef kNonConst; - -typedef const struct __CFAllocator * CFAllocatorRef; -typedef const struct __CFUUID * CFUUIDRef; - -extern const CFAllocatorRef kCFAllocatorDefault; - -extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); - -struct StrS { - CFStringRef sref_member; -}; - -@interface NSString : NSObject { - CFStringRef sref; - struct StrS *strS; -} --(id)string; --(id)newString; -@end - -void f(BOOL b, id p) { - NSString *str = (NSString *)kUTTypePlainText; // no change - str = b ? kUTTypeRTF : kUTTypePlainText; // no change - str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); // no change - str = (NSString *)p; // no change. - - str = (NSString *)kNonConst; - str = b ? kUTTypeRTF : kNonConst; - str = (NSString *)(b ? kUTTypeRTF : kNonConst); - - CFUUIDRef _uuid; - NSString *_uuidString = (NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid); - _uuidString = [(NSString *)CFUUIDCreateString(kCFAllocatorDefault, _uuid) autorelease]; - _uuidString = CFRetain(_uuid); -} - -@implementation NSString (StrExt) -- (NSString *)stringEscapedAsURI { - CFStringRef str = (CFStringRef)self; - CFStringRef str2 = self; - return self; -} -@end - -@implementation NSString --(id)string { - if (0) - return sref; - else - return strS->sref_member; -} --(id)newString { return 0; } -@end - -extern void consumeParam(CFStringRef CF_CONSUMED p); - -void f2(NSString *s) { - CFStringRef ref = [s string]; - ref = (CFStringRef)[s string]; - ref = s.string; - ref = [NSString new]; - ref = [s newString]; - ref = (CFStringRef)[NSString new]; - ref = [[NSString alloc] init]; - ref = [[s string] retain]; - ref = CFRetain((CFStringRef)[s string]); - ref = CFRetain([s string]); - ref = CFRetain(s); - ref = [s retain]; - - consumeParam((CFStringRef)s); - consumeParam(s); -} diff --git a/clang/test/ARCMT/nonobjc-to-objc-cast.m.result b/clang/test/ARCMT/nonobjc-to-objc-cast.m.result deleted file mode 100644 index 8f3092f8786d8..0000000000000 --- a/clang/test/ARCMT/nonobjc-to-objc-cast.m.result +++ /dev/null @@ -1,83 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -typedef const struct __CFString * CFStringRef; -extern const CFStringRef kUTTypePlainText; -extern const CFStringRef kUTTypeRTF; -extern CFStringRef kNonConst; - -typedef const struct __CFAllocator * CFAllocatorRef; -typedef const struct __CFUUID * CFUUIDRef; - -extern const CFAllocatorRef kCFAllocatorDefault; - -extern CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid); - -struct StrS { - CFStringRef sref_member; -}; - -@interface NSString : NSObject { - CFStringRef sref; - struct StrS *strS; -} --(id)string; --(id)newString; -@end - -void f(BOOL b, id p) { - NSString *str = (NSString *)kUTTypePlainText; // no change - str = b ? kUTTypeRTF : kUTTypePlainText; // no change - str = (NSString *)(b ? kUTTypeRTF : kUTTypePlainText); // no change - str = (NSString *)p; // no change. - - str = (__bridge NSString *)kNonConst; - str = (__bridge NSString *)(b ? kUTTypeRTF : kNonConst); - str = (__bridge NSString *)(b ? kUTTypeRTF : kNonConst); - - CFUUIDRef _uuid; - NSString *_uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid)); - _uuidString = (NSString *)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, _uuid)); - _uuidString = CFBridgingRelease(CFRetain(_uuid)); -} - -@implementation NSString (StrExt) -- (NSString *)stringEscapedAsURI { - CFStringRef str = (__bridge CFStringRef)self; - CFStringRef str2 = (__bridge CFStringRef)(self); - return self; -} -@end - -@implementation NSString --(id)string { - if (0) - return (__bridge id)(sref); - else - return (__bridge id)(strS->sref_member); -} --(id)newString { return 0; } -@end - -extern void consumeParam(CFStringRef CF_CONSUMED p); - -void f2(NSString *s) { - CFStringRef ref = (__bridge CFStringRef)([s string]); - ref = (__bridge CFStringRef)[s string]; - ref = (__bridge CFStringRef)(s.string); - ref = CFBridgingRetain([NSString new]); - ref = CFBridgingRetain([s newString]); - ref = (CFStringRef)CFBridgingRetain([NSString new]); - ref = CFBridgingRetain([[NSString alloc] init]); - ref = CFBridgingRetain([s string]); - ref = (CFStringRef)CFBridgingRetain([s string]); - ref = CFBridgingRetain([s string]); - ref = CFBridgingRetain(s); - ref = CFBridgingRetain(s); - - consumeParam((CFStringRef)CFBridgingRetain(s)); - consumeParam(CFBridgingRetain(s)); -} diff --git a/clang/test/ARCMT/objcmt-arc-cf-annotations.m b/clang/test/ARCMT/objcmt-arc-cf-annotations.m deleted file mode 100644 index 47c83ac9e3dd5..0000000000000 --- a/clang/test/ARCMT/objcmt-arc-cf-annotations.m +++ /dev/null @@ -1,2017 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-annotation -objcmt-migrate-instancetype -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -#ifndef CF_IMPLICIT_BRIDGING_ENABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") -#else -#define CF_IMPLICIT_BRIDGING_ENABLED -#endif -#endif - -#ifndef CF_IMPLICIT_BRIDGING_DISABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") -#else -#define CF_IMPLICIT_BRIDGING_DISABLED -#endif -#endif - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -//===----------------------------------------------------------------------===// -// The following code is reduced using delta-debugging from Mac OS X headers: -// -// #include -// #include -// #include -// #include -// #include -// #include -// -// It includes the basic definitions for the test cases below. -//===----------------------------------------------------------------------===// - -typedef unsigned int __darwin_natural_t; -typedef unsigned long uintptr_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef unsigned int UInt32; -typedef signed long CFIndex; -typedef CFIndex CFByteOrder; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; -static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { - CFRange range; - range.location = loc; - range.length = len; - return range; -} -typedef const void * CFTypeRef; -typedef const struct __CFString * CFStringRef; -typedef const struct __CFAllocator * CFAllocatorRef; -extern const CFAllocatorRef kCFAllocatorDefault; -extern CFTypeRef CFRetain(CFTypeRef cf); -extern void CFRelease(CFTypeRef cf); -extern CFTypeRef CFAutorelease(CFTypeRef cf); -extern CFTypeRef CFMakeCollectable(CFTypeRef cf); -typedef struct { -} -CFArrayCallBacks; -extern const CFArrayCallBacks kCFTypeArrayCallBacks; -typedef const struct __CFArray * CFArrayRef; -typedef struct __CFArray * CFMutableArrayRef; -extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks); -extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx); -extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); -typedef struct { -} -CFDictionaryKeyCallBacks; -extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; -typedef struct { -} -CFDictionaryValueCallBacks; -extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; -extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks); -typedef UInt32 CFStringEncoding; -enum { -kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; -extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding); -typedef double CFTimeInterval; -typedef CFTimeInterval CFAbsoluteTime; -extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); -typedef const struct __CFDate * CFDateRef; -extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at); -extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); -typedef __darwin_natural_t natural_t; -typedef natural_t mach_port_name_t; -typedef mach_port_name_t mach_port_t; -typedef int kern_return_t; -typedef kern_return_t mach_error_t; -enum { -kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 }; -typedef CFIndex CFNumberType; -typedef const struct __CFNumber * CFNumberRef; -extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr); -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; -extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) ; -extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) ; -extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; -typedef signed char BOOL; -typedef unsigned long NSUInteger; -@class NSString, Protocol; -extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); -typedef struct _NSZone NSZone; -@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -- (id)autorelease; -- (NSString *)description; -- (id)init; -@end -@protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; -@end -@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; -@end -@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; -@end -@interface NSObject {} -+ (id)allocWithZone:(NSZone *)zone; -+ (id)alloc; -+ (id)new; -- (void)dealloc; -@end -@interface NSObject (NSCoderMethods) -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; -@end -extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); -typedef struct { -} -NSFastEnumerationState; -@protocol NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; -@end -@class NSString, NSDictionary; -@interface NSValue : NSObject - (void)getValue:(void *)value; -@end -@interface NSNumber : NSValue -- (char)charValue; -- (id)initWithInt:(int)value; -+ (NSNumber *)numberWithInt:(int)value; -@end -@class NSString; -@interface NSArray : NSObject -- (NSUInteger)count; -- (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (id)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (id)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (id)initWithArray:(NSArray *)array; -@end @interface NSArray (NSArrayCreation) + (id)array; -@end @interface NSAutoreleasePool : NSObject { -} -- (void)drain; -@end extern NSString * const NSBundleDidLoadNotification; -typedef double NSTimeInterval; -@interface NSDate : NSObject - (NSTimeInterval)timeIntervalSinceReferenceDate; -@end typedef unsigned short unichar; -@interface NSString : NSObject -- (NSUInteger)length; -- (NSString *)stringByAppendingString:(NSString *)aString; -- ( const char *)UTF8String; -- (id)initWithUTF8String:(const char *)nullTerminatedCString; -+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; -@end @class NSString, NSURL, NSError; -@interface NSData : NSObject - (NSUInteger)length; -+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; -+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; -@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; -@interface NSDictionary : NSObject -- (NSUInteger)count; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; -@end -@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; -- (void)setObject:(id)anObject forKey:(id)aKey; -@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (id)dictionaryWithCapacity:(NSUInteger)numItems; -@end typedef double CGFloat; -struct CGSize { -}; -typedef struct CGSize CGSize; -struct CGRect { -}; -typedef struct CGRect CGRect; -typedef mach_port_t io_object_t; -typedef char io_name_t[128]; -typedef io_object_t io_iterator_t; -typedef io_object_t io_service_t; -typedef struct IONotificationPort * IONotificationPortRef; -typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); -io_service_t IOServiceGetMatchingService( mach_port_t mainPort, CFDictionaryRef matching ); -kern_return_t IOServiceGetMatchingServices( mach_port_t mainPort, CFDictionaryRef matching, io_iterator_t * existing ); -kern_return_t IOServiceAddNotification( mach_port_t mainPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}} -kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); -CFMutableDictionaryRef IOServiceMatching( const char * name ); -CFMutableDictionaryRef IOServiceNameMatching( const char * name ); -CFMutableDictionaryRef IOBSDNameMatching( mach_port_t mainPort, uint32_t options, const char * bsdName ); -CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t mainPort, uint32_t options, const char * path ); -CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); -typedef struct __DASession * DASessionRef; -extern DASessionRef DASessionCreate( CFAllocatorRef allocator ); -typedef struct __DADisk * DADiskRef; -extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ); -extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ); -extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ); -extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ); -@interface NSTask : NSObject - (id)init; -@end typedef struct CGColorSpace *CGColorSpaceRef; -typedef struct CGImage *CGImageRef; -typedef struct CGLayer *CGLayerRef; -@interface NSResponder : NSObject { -} -@end @protocol NSAnimatablePropertyContainer - (id)animator; -@end extern NSString *NSAnimationTriggerOrderIn ; -@interface NSView : NSResponder { -} -@end @protocol NSValidatedUserInterfaceItem - (SEL)action; -@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id )anItem; -@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; -@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; -@interface NSApplication : NSResponder { -} -- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; -@end enum { -NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; -typedef NSUInteger NSApplicationTerminateReply; -@protocol NSApplicationDelegate @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; -@interface NSCell : NSObject { -} -@end -typedef struct { -} -CVTimeStamp; -@interface CIImage : NSObject { -} -typedef int CIFormat; -@end enum { -kDAReturnSuccess = 0, kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C }; -typedef mach_error_t DAReturn; -typedef const struct __DADissenter * DADissenterRef; -extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ); -@interface CIContext: NSObject { -} -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r; -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs; -- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d; -@end extern NSString* const QCRendererEventKey; -@protocol QCCompositionRenderer - (NSDictionary*) attributes; -@end @interface QCRenderer : NSObject { -} -- (id) createSnapshotImageOfType:(NSString*)type; -@end extern NSString* const QCViewDidStartRenderingNotification; -@interface QCView : NSView { -} -- (id) createSnapshotImageOfType:(NSString*)type; -@end enum { -ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; -@class ICDevice; -@protocol ICDeviceDelegate @required - (void)didRemoveDevice:(ICDevice*)device; -@end extern NSString *const ICScannerStatusWarmingUp; -@class ICScannerDevice; -@protocol ICScannerDeviceDelegate @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; -@end - -typedef long unsigned int __darwin_size_t; -typedef __darwin_size_t size_t; -typedef unsigned long CFTypeID; -struct CGPoint { - CGFloat x; - CGFloat y; -}; -typedef struct CGPoint CGPoint; -typedef struct CGGradient *CGGradientRef; -typedef uint32_t CGGradientDrawingOptions; -extern CFTypeID CGGradientGetTypeID(void); -extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef - space, const CGFloat components[], const CGFloat locations[], size_t count); -extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, - CFArrayRef colors, const CGFloat locations[]); -extern CGGradientRef CGGradientRetain(CGGradientRef gradient); -extern void CGGradientRelease(CGGradientRef gradient); -typedef struct CGContext *CGContextRef; -extern void CGContextDrawLinearGradient(CGContextRef context, - CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, - CGGradientDrawingOptions options); -extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); - -@interface NSMutableArray : NSObject -- (void)addObject:(id)object; -+ (id)array; -@end - -// This is how NSMakeCollectable is declared in the OS X 10.8 headers. -id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained)); - -typedef const struct __CFUUID * CFUUIDRef; - -extern -void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID); - -//===----------------------------------------------------------------------===// -// Test cases. -//===----------------------------------------------------------------------===// - -CFAbsoluteTime f1(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - CFRetain(date); - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - CFRelease(date); - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - -CFAbsoluteTime f2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - - -NSDate* global_x; - -// Test to see if we suppress an error when we store the pointer -// to a global. - -CFAbsoluteTime f3(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - global_x = (NSDate*) date; - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // no-warning - return t; -} - -//--------------------------------------------------------------------------- -// Test case 'f4' differs for region store and basic store. See -// retain-release-region-store.m and retain-release-basic-store.m. -//--------------------------------------------------------------------------- - -// Test a leak. - -CFAbsoluteTime f5(int x) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} - - if (x) - CFRelease(date); - - return t; -} - -// Test a leak involving the return. - -CFDateRef f6(int x) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -// Test a leak involving an overwrite. - -CFDateRef f7(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} - CFRetain(date); - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} - return date; -} - -// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and -// has the word create. -CFDateRef MyDateCreate(void); - -CFDateRef f8(void) { - CFDateRef date = MyDateCreate(); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -__attribute__((cf_returns_retained)) CFDateRef f9(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning - int *p = 0; - // When allocations fail, CFDateCreate can return null. - if (!date) *p = 1; // expected-warning{{null}} - return date; -} - -// Handle DiskArbitration API: -// -// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ -// -void f10(io_service_t media, DADiskRef d, CFStringRef s) { - DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} - if (dict) NSLog(@"ok"); - - disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} - kDAReturnSuccess, s); - if (dissenter) NSLog(@"ok"); - - DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} - if (session) NSLog(@"ok"); -} - -// Test retain/release checker with CFString and CFMutableArray. -void f11(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - - // Create a string. - CFStringRef s1 = CFStringCreateWithCString(0, "hello world", - kCFStringEncodingUTF8); - - // Add the string to the array. - CFArrayAppendValue(A, s1); - - // Decrement the reference count. - CFRelease(s1); // no-warning - - // Get the string. We don't own it. - s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); - - // Release the array. - CFRelease(A); // no-warning - - // Release the string. This is a bug. - CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3337: Handle functions declared using typedefs. -typedef CFTypeRef CREATEFUN(void); -CFTypeRef MyCreateFun(void); - -void f12(void) { - CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} -} - -void f13_autorelease(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning - [(id) A autorelease]; // no-warning -} - -void f13_autorelease_b(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; -} // expected-warning{{Object autoreleased too many times}} - -CFMutableArrayRef f13_autorelease_c(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - return A; // expected-warning{{Object autoreleased too many times}} -} - -CFMutableArrayRef f13_autorelease_d(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} - CFRelease(B); // no-warning - while (1) {} -} - - -// This case exercises the logic where the leak site is the same as the allocation site. -void f14_leakimmediately(void) { - CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} -} - -// Test that we track an allocated object beyond the point where the *name* -// of the variable storing the reference is no longer live. -void f15(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - CFMutableArrayRef *B = &A; - // At this point, the name 'A' is no longer live. - CFRelease(*B); // no-warning -} - -// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f16(int x, CFTypeRef p) { - if (p) - return; - - switch (x) { - case 0: - CFRelease(p); - break; - case 1: - CFRetain(p); - break; - case 2: - CFMakeCollectable(p); - break; - case 3: - CFAutorelease(p); - break; - default: - break; - } -} - -// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f17(int x, CFTypeRef p) { - switch (x) { - case 0: - CFRelease(p); - if (!p) - CFRelease(0); // no-warning - break; - case 1: - CFRetain(p); - if (!p) - CFRetain(0); // no-warning - break; - case 2: - CFMakeCollectable(p); - if (!p) - CFMakeCollectable(0); // no-warning - break; - case 3: - CFAutorelease(p); - if (!p) - CFAutorelease(0); // no-warning - break; - default: - break; - } -} - -// Test basic tracking of ivars associated with 'self'. For the retain/release -// checker we currently do not want to flag leaks associated with stores -// of tracked objects to ivars. -@interface SelfIvarTest : NSObject { - id myObj; -} -- (void)test_self_tracking; -@end - -@implementation SelfIvarTest -- (void)test_self_tracking { - myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} -@end - -// Test return of non-owned objects in contexts where an owned object -// is expected. -@interface TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString; -@end - -@implementation TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString { - NSString *s = [NSString stringWithUTF8String:"hello"]; - return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} -@end - -int isFoo(char c); - -static void rdar_6659160(char *inkind, char *inname) -{ - // We currently expect that [NSObject alloc] cannot fail. This - // will be a toggled flag in the future. It can indeed return null, but - // Cocoa programmers generally aren't expected to reason about out-of-memory - // conditions. - NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} - - // We do allow stringWithUTF8String to fail. This isn't really correct, as - // far as returning 0. In most error conditions it will throw an exception. - // If allocation fails it could return 0, but again this - // isn't expected. - NSString *name = [NSString stringWithUTF8String:inname]; - if(!name) - return; - - const char *kindC = 0; - const char *nameC = 0; - - // In both cases, we cannot reach a point down below where we - // dereference kindC or nameC with either being null. This is because - // we assume that [NSObject alloc] doesn't fail and that we have the guard - // up above. - - if(kind) - kindC = [kind UTF8String]; - if(name) - nameC = [name UTF8String]; - if(!isFoo(kindC[0])) // expected-warning{{null}} - return; - if(!isFoo(nameC[0])) // no-warning - return; - - [kind release]; - [name release]; // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming -// conventions with respect to 'return'ing ownership. -@interface PR3677: NSObject @end -@implementation PR3677 -+ (id)allocWithZone:(NSZone *)inZone { - return [super allocWithZone:inZone]; // no-warning -} -@end - -// PR 3820 - Reason about calls to -dealloc -void pr3820_DeallocInsteadOfRelease(void) -{ - id foo = [[NSString alloc] init]; // no-warning - [foo dealloc]; - // foo is not leaked, since it has been deallocated. -} - -void pr3820_ReleaseAfterDealloc(void) -{ - id foo = [[NSString alloc] init]; - [foo dealloc]; - [foo release]; // expected-warning{{used after it is release}} - // NSInternalInconsistencyException: message sent to deallocated object -} - -void pr3820_DeallocAfterRelease(void) -{ - NSLog(@"\n\n[%s]", __FUNCTION__); - id foo = [[NSString alloc] init]; - [foo release]; - [foo dealloc]; // expected-warning{{used after it is released}} - // message sent to released object -} - -// The problem here is that 'length' binds to '($0 - 1)' after '--length', but -// SimpleConstraintManager doesn't know how to reason about -// '($0 - 1) > constant'. As a temporary hack, we drop the value of '($0 - 1)' -// and conjure a new symbol. -void rdar6704930(unsigned char *s, unsigned int length) { - NSString* name = 0; - if (s != 0) { - if (length > 0) { - while (length > 0) { - if (*s == ':') { - ++s; - --length; - name = [[NSString alloc] init]; // no-warning - break; - } - ++s; - --length; - } - if ((length == 0) && (name != 0)) { - [name release]; - name = 0; - } - if (length == 0) { // no ':' found -> use it all as name - name = [[NSString alloc] init]; // no-warning - } - } - } - - if (name != 0) { - [name release]; - } -} - -//===----------------------------------------------------------------------===// -// One build of the analyzer accidentally stopped tracking the allocated -// object after the 'retain'. -//===----------------------------------------------------------------------===// - -@interface rdar_6833332 : NSObject { - NSWindow *window; -} -@property (nonatomic, retain) NSWindow *window; -@end - -@implementation rdar_6833332 -@synthesize window; -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - - [dict setObject:@"foo" forKey:@"bar"]; - - NSLog(@"%@", dict); -} -- (void)dealloc { - [window release]; - [super dealloc]; -} - -- (void)radar10102244 { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - if (window) - NSLog(@"%@", window); -} -@end - -//===----------------------------------------------------------------------===// -// clang checker fails to catch use-after-release -//===----------------------------------------------------------------------===// -int rdar_6257780_Case1(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSArray *array = [NSArray array]; - [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} - [pool drain]; - return 0; -} - -//===----------------------------------------------------------------------===// -// Analyzer is confused about NSAutoreleasePool -allocWithZone:. -//===----------------------------------------------------------------------===// -void rdar_10640253_autorelease_allocWithZone(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init]; - (void) pool; -} - -//===----------------------------------------------------------------------===// -// Checker should understand new/setObject:/release constructs -//===----------------------------------------------------------------------===// -void rdar_6866843(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; - NSArray* array = [[NSArray alloc] init]; - [dictionary setObject:array forKey:@"key"]; - [array release]; - // Using 'array' here should be fine - NSLog(@"array = %@\n", array); // no-warning - // Now the array is released - [dictionary release]; - [pool drain]; -} - - -//===----------------------------------------------------------------------===// -// Classes typedef-ed to CF objects should get the same treatment as CF objects -//===----------------------------------------------------------------------===// -typedef CFTypeRef OtherRef; - -@interface RDar6877235 : NSObject {} -- (CFTypeRef)_copyCFTypeRef; -- (OtherRef)_copyOtherRef; -@end - -@implementation RDar6877235 -- (CFTypeRef)_copyCFTypeRef { - return [[NSString alloc] init]; // no-warning -} -- (OtherRef)_copyOtherRef { - return [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// false positive - init method returns an object owned by caller -//===----------------------------------------------------------------------===// -@interface RDar6320065 : NSObject { - NSString *_foo; -} -- (id)initReturningNewClass; -- (id)_initReturningNewClassBad; -- (id)initReturningNewClassBad2; -@end - -@interface RDar6320065Subclass : RDar6320065 -@end - -@implementation RDar6320065 -- (id)initReturningNewClass { - [self release]; - self = [[RDar6320065Subclass alloc] init]; // no-warning - return self; -} -- (id)_initReturningNewClassBad { - [self release]; - [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} - return self; -} -- (id)initReturningNewClassBad2 { - [self release]; - self = [[RDar6320065Subclass alloc] init]; - return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -@end - -@implementation RDar6320065Subclass -@end - -int RDar6320065_test(void) { - RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning - [test release]; - return 0; -} - -//===----------------------------------------------------------------------===// -// -awakeAfterUsingCoder: returns an owned object and claims the receiver -//===----------------------------------------------------------------------===// -@interface RDar7129086 : NSObject {} @end -@implementation RDar7129086 -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { - [self release]; // no-warning - return [NSString alloc]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// [NSData dataWithBytesNoCopy] does not return a retained object -//===----------------------------------------------------------------------===// -@interface RDar6859457 : NSObject {} -- (NSString*) NoCopyString; -- (NSString*) noCopyString; -@end - -@implementation RDar6859457 -- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -@end - -void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { - [x NoCopyString]; // expected-warning{{leak}} - [x noCopyString]; // expected-warning{{leak}} - [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning - [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning -} - -//===----------------------------------------------------------------------===// -// PR 4230 - an autorelease pool is not necessarily leaked during a premature -// return -//===----------------------------------------------------------------------===// - -static void PR4230(void) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -static void PR4230_new(void) -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return [[NSString alloc] init]; // expected-warning{{leak}} -} -@end - -//===----------------------------------------------------------------------===// -// don't flag leaks for return types that cannot be determined to be CF types -//===----------------------------------------------------------------------===// - -// We don't know if 'struct s6893565' represents a Core Foundation type, so -// we shouldn't emit an error here. -typedef struct s6893565* TD6893565; - -@interface RDar6893565 {} --(TD6893565)newThing; -@end - -@implementation RDar6893565 --(TD6893565)newThing { - return (TD6893565) [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// clang: false positives w/QC and CoreImage methods -//===----------------------------------------------------------------------===// -void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, - NSString *str, CIImage *img, CGRect rect, - CIFormat form, CGColorSpaceRef cs) { - [view createSnapshotImageOfType:str]; // expected-warning{{leak}} - [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// -[CIContext createCGLayerWithSize:info:] misinterpreted by clang scan-build -//===----------------------------------------------------------------------===// -void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { - [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Add knowledge of IOKit functions to retain/release checker. -//===----------------------------------------------------------------------===// -void IOBSDNameMatching_wrapper(mach_port_t mainPort, uint32_t options, const char * bsdName) { - IOBSDNameMatching(mainPort, options, bsdName); // expected-warning{{leak}} -} - -void IOServiceMatching_wrapper(const char * name) { - IOServiceMatching(name); // expected-warning{{leak}} -} - -void IOServiceNameMatching_wrapper(const char * name) { - IOServiceNameMatching(name); // expected-warning{{leak}} -} - -CF_RETURNS_RETAINED CFDictionaryRef CreateDict(void); - -void IOServiceAddNotification_wrapper(mach_port_t mainPort, const io_name_t notificationType, - mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { - - CFDictionaryRef matching = CreateDict(); - CFRelease(matching); - IOServiceAddNotification(mainPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} - wakePort, reference, notification); -} - -void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { - IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} -} - -void IOOpenFirmwarePathMatching_wrapper(mach_port_t mainPort, uint32_t options, - const char * path) { - IOOpenFirmwarePathMatching(mainPort, options, path); // expected-warning{{leak}} -} - -void IOServiceGetMatchingService_wrapper(mach_port_t mainPort) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingService(mainPort, matching); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceGetMatchingServices_wrapper(mach_port_t mainPort, io_iterator_t *existing) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingServices(mainPort, matching, existing); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, - IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { - - CFDictionaryRef matching = CreateDict(); - IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -//===----------------------------------------------------------------------===// -// Test of handling objects whose references "escape" to containers. -//===----------------------------------------------------------------------===// -void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); - -void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { - CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(y, key, x); - CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - if (value) { - CFDictionaryAddValue(x, val_key, (void*)value); // no-warning - CFRelease(value); - CFDictionaryAddValue(y, val_key, (void*)value); // no-warning - } -} - -// Same issue, except with "AppendValue" functions. -void rdar_6560661(CFMutableArrayRef x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - // CFArrayAppendValue keeps a reference to value. - CFArrayAppendValue(x, value); - CFRelease(value); - CFRetain(value); - CFRelease(value); // no-warning -} - -// Same issue, excwept with "CFAttributeStringSetAttribute". -void rdar_7152619(CFStringRef str) { - CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); - CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); - CFRelease(string); - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); - [number release]; - [number retain]; - CFRelease(attrString); -} - -//===----------------------------------------------------------------------===// -// Test of handling CGGradientXXX functions. -//===----------------------------------------------------------------------===// - -void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} - components, locations, num_locations); - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); - CGGradientRelease(myGradient); -} - -void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); -} - -//===----------------------------------------------------------------------===// -// clang false positive: retained instance passed to thread in pthread_create -// marked as leak -// -// Until we have full IPA, the analyzer should stop tracking the reference -// count of objects passed to pthread_create. -// -//===----------------------------------------------------------------------===// -struct _opaque_pthread_t {}; -struct _opaque_pthread_attr_t {}; -typedef struct _opaque_pthread_t *__darwin_pthread_t; -typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; -typedef __darwin_pthread_t pthread_t; -typedef __darwin_pthread_attr_t pthread_attr_t; -typedef unsigned long __darwin_pthread_key_t; -typedef __darwin_pthread_key_t pthread_key_t; - -int pthread_create(pthread_t *, const pthread_attr_t *, - void *(*)(void *), void *); - -int pthread_setspecific(pthread_key_t key, const void *value); - -void *rdar_7299394_start_routine(void *p) { - [((id) p) release]; - return 0; -} -void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_create(thread, attr, rdar_7299394_start_routine, number); -} -void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// false positive with not understanding thread local storage -//===----------------------------------------------------------------------===// -void rdar11282706(pthread_key_t key) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_setspecific(key, (void*) number); -} - -//===----------------------------------------------------------------------===// -// False leak associated with call to CVPixelBufferCreateWithBytes () -// -// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and -// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the -// pixel buffer object. These test cases show how the analyzer stops tracking -// the reference count for the objects passed for this argument. This -// could be made smarter. -//===----------------------------------------------------------------------===// -typedef int int32_t; -typedef UInt32 FourCharCode; -typedef FourCharCode OSType; -typedef uint64_t CVOptionFlags; -typedef int32_t CVReturn; -typedef struct __CVBuffer *CVBufferRef; -typedef CVBufferRef CVImageBufferRef; -typedef CVImageBufferRef CVPixelBufferRef; -typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); - -extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *dataPtr, - size_t dataSize, - size_t numberOfPlanes, - void *planeBaseAddress[], - size_t planeWidth[], - size_t planeHeight[], - size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, - baseAddress, bytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *dataPtr, size_t dataSize, - size_t numberOfPlanes, void *planeBaseAddress[], - size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithPlanarBytes(allocator, - width, height, pixelFormatType, dataPtr, dataSize, - numberOfPlanes, planeBaseAddress, planeWidth, - planeHeight, planeBytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -//===----------------------------------------------------------------------===// -// False leak associated with CGBitmapContextCreateWithData -//===----------------------------------------------------------------------===// -typedef uint32_t CGBitmapInfo; -typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); - -CGContextRef CGBitmapContextCreateWithData(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo); - -void rdar_7358899(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} - bytesPerRow, space, bitmapInfo, releaseCallback, number); -} - -//===----------------------------------------------------------------------===// -// Allow 'new', 'copy', 'alloc', 'init' prefix to start before '_' when -// determining Cocoa fundamental rule. -// -// Previously the retain/release checker just skipped prefixes before the -// first '_' entirely. Now the checker honors the prefix if it results in a -// recognizable naming convention (e.g., 'new', 'init'). -//===----------------------------------------------------------------------===// -@interface RDar7265711 {} -- (id) new_stuff; -@end - -void rdar7265711_a(RDar7265711 *x) { - id y = [x new_stuff]; // expected-warning{{leak}} -} - -void rdar7265711_b(RDar7265711 *x) { - id y = [x new_stuff]; // no-warning - [y release]; -} - -//===----------------------------------------------------------------------===// -// clang thinks [NSCursor dragCopyCursor] returns a retained reference -//===----------------------------------------------------------------------===// -@interface NSCursor : NSObject -+ (NSCursor *)dragCopyCursor; -@end - -void rdar7306898(void) { - // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence - // implying a 'copy' of something. - NSCursor *c = [NSCursor dragCopyCursor]; // no-warning - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Sending 'release', 'retain', etc. to a Class directly is not likely what the -// user intended. -//===----------------------------------------------------------------------===// -@interface RDar7252064 : NSObject @end -void rdar7252064(void) { - [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}} -} - -//===----------------------------------------------------------------------===// -// Tests of ownership attributes. -//===----------------------------------------------------------------------===// - -typedef NSString* MyStringTy; - -@protocol FooP; - -@interface TestOwnershipAttr : NSObject -- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning -- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning -- (NSString*) newStringNoAttr; -- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} -- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; -+ (void) consume:(id) NS_CONSUMED x; -+ (void) consume2:(id) CF_CONSUMED x; -@end - -static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}} - -void test_attr_1(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} -} - -void test_attr_1b(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} -} - -void test_attr1c(TestOwnershipAttr *X) { - NSString *str = [X newString]; // no-warning - NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} - NSString *str3 = [X newString_auto]; // no-warning - NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}} -} - -void testattr2_a(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} -} - -void testattr2_b(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} -} - -void testattr2_b_11358224_self_assign_looses_the_leak(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}} - x = x; -} - -void testattr2_c(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning - [x release]; -} - -void testattr3(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume:x]; - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume2:y]; -} - -void consume_ns(id NS_CONSUMED x); -void consume_cf(id CF_CONSUMED x); - -void testattr4(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - consume_ns(x); - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - consume_cf(y); -} - -@interface TestOwnershipAttr2 : NSObject -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -@end - -@implementation TestOwnershipAttr2 -- (NSString*) newString { - return [NSString alloc]; // expected-warning {{Potential leak of an object}} -} -@end - -@interface MyClassTestCFAttr : NSObject {} -- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; -- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; -- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; -- (CFDateRef) newCFRetainedAsCFNoAttr; -- (NSDate*) alsoReturnsRetained; -- (CFDateRef) alsoReturnsRetainedAsCF; -- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; -@end - -CF_RETURNS_RETAINED -CFDateRef returnsRetainedCFDate(void) { - return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); -} - -@implementation MyClassTestCFAttr -- (NSDate*) returnsCFRetained { - return (NSDate*) returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) returnsCFRetainedAsCF { - return returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) newCFRetainedAsCF { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; -} - -- (CFDateRef) newCFRetainedAsCFNoAttr { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -- (NSDate*) alsoReturnsRetained { - return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} -} - -- (CFDateRef) alsoReturnsRetainedAsCF { - return returnsRetainedCFDate(); // expected-warning{{leak}} -} - - -- (NSDate*) returnsNSRetained { - return (NSDate*) returnsRetainedCFDate(); // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// Test that leaks post-dominated by "panic" functions are not reported. -// -// Do not report a leak when post-dominated by a call to a noreturn or panic -// function. -//===----------------------------------------------------------------------===// -void panic(void) __attribute__((noreturn)); -void panic_not_in_hardcoded_list(void) __attribute__((noreturn)); - -void test_panic_negative(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} -} - -void test_panic_positive(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - panic(); -} - -void test_panic_neg_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} - if (x) - panic(); -} - -void test_panic_pos_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - if (x) - panic(); - if (!x) { - // This showed up previously where we silently missed checking the function - // type for noreturn. "panic()" is a hard-coded known panic function that - // isn't always noreturn. - panic_not_in_hardcoded_list(); - } -} - -//===----------------------------------------------------------------------===// -// Test uses of blocks (closures) -//===----------------------------------------------------------------------===// - -void test_blocks_1_pos(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - ^{}(); -} - -void test_blocks_1_indirect_release(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number release]; }(); -} - -void test_blocks_1_indirect_retain(void) { - // Eventually this should be reported as a leak. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number retain]; }(); -} - -void test_blocks_1_indirect_release_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^(NSObject *o){ [o release]; }(number); -} - -void test_blocks_1_indirect_retain_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} - ^(NSObject *o){ [o retain]; }(number); -} - -//===--------------------------------------------------------------------===// -// Test sending message to super that returns an object alias. Previously -// this caused a crash in the analyzer. -//===--------------------------------------------------------------------===// - -@interface Rdar8015556 : NSObject {} @end -@implementation Rdar8015556 -- (id)retain { - return [super retain]; -} -@end - -// Correcly handle Class<...> in Cocoa Conventions detector. -@protocol Prot_R8272168 @end -Class GetAClassThatImplementsProt_R8272168(void); -void r8272168(void) { - GetAClassThatImplementsProt_R8272168(); -} - -// Test case which in the past triggered a false positive. -@interface RDar8356342 -- (NSDate*) rdar8356342:(NSDate *)inValue; -@end - -@implementation RDar8356342 -- (NSDate*) rdar8356342:(NSDate*)inValue { - NSDate *outValue = inValue; - if (outValue == 0) - outValue = [[NSDate alloc] init]; // no-warning - - if (outValue != inValue) - [outValue autorelease]; - - return outValue; -} -@end - -// This test case previously crashed because of a bug in BugReporter. -extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); -typedef struct __CFError * CFErrorRef; -extern const CFStringRef kCFErrorUnderlyingErrorKey; -extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err); -static void rdar_8724287(CFErrorRef error) -{ - CFErrorRef error_to_dump; - - error_to_dump = error; - while (error_to_dump != ((void*)0)) { - CFDictionaryRef info; - - info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}} - - if (info != ((void*)0)) { - } - - error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); - } -} - -// Make sure the model applies cf_consumed correctly in argument positions -// besides the first. -extern void *CFStringCreate(void); -extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); -void rdar_9234108(void) { - rdar_9234108_helper(0, CFStringCreate()); -} - -// Make sure that objc_method_family works to override naming conventions. -struct TwoDoubles { - double one; - double two; -}; -typedef struct TwoDoubles TwoDoubles; - -@interface NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); -@end - -@implementation NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles -{ - return [self init]; -} -@end - -void rdar9726279(void) { - TwoDoubles twoDoubles = { 0.0, 0.0 }; - NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; - [value release]; -} - -// Test camelcase support for CF conventions. While Core Foundation APIs -// don't use camel casing, other code is allowed to use it. -CFArrayRef camelcase_create_1(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_createno(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camelcase_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_copying(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __createCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_create(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - - -CFArrayRef camel_creat(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camel_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copyMachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copymachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -@protocol F18P -- (id) clone; -@end -@interface F18 : NSObject @end -@interface F18(Cat) -- (id) clone NS_RETURNS_RETAINED; -@end - -@implementation F18 -- (id) clone { - return [F18 alloc]; -} -@end - -void rdar6582778(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFTypeRef vals[] = { CFDateCreate(0, t) }; // expected-warning {{leak}} -} - -CFTypeRef global; - -void rdar6582778_2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - global = CFDateCreate(0, t); // no-warning -} - -// Test that objects passed to containers are marked "escaped". -void rdar10232019(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [array addObject:string]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // no-warning - NSLog(@"%@", otherString); -} - -void rdar10232019_positive(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // expected-warning {{Reference-counted object is used after it is release}} - NSLog(@"%@", otherString); -} - -// RetainCountChecker support for XPC. -typedef void * xpc_object_t; -xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf); -void xpc_release(xpc_object_t object); - -void rdar9658496(void) { - CFStringRef cf; - xpc_object_t xpc; - cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - xpc = _CFXPCCreateXPCObjectFromCFObject( cf ); - CFRelease(cf); - xpc_release(xpc); -} - -// Support annotations with method families. -@interface RDar10824732 : NSObject -- (id)initWithObj:(id CF_CONSUMED)obj; -@end - -@implementation RDar10824732 -- (id)initWithObj:(id)obj { - [obj release]; - return [super init]; -} -@end - -void rdar_10824732(void) { - @autoreleasepool { - NSString *obj = @"test"; - RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning - [foo release]; - } -} - -// Stop tracking objects passed to functions, which take callbacks as parameters. -typedef int (*CloseCallback) (void *); -void ReaderForIO(CloseCallback ioclose, void *ioctx); -int IOClose(void *context); - -@protocol SInS -@end - -@interface radar10973977 : NSObject -- (id)inputS; -- (void)reader; -@end - -@implementation radar10973977 -- (void)reader -{ - id inputS = [[self inputS] retain]; - ReaderForIO(IOClose, inputS); -} -- (id)inputS -{ - return 0; -} -@end - -// Object escapes through a selector callback -extern id NSApp; -@interface MySheetController -- (id)inputS; -- (void)showDoSomethingSheetAction:(id)action; -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; -@end - -@implementation MySheetController -- (id)inputS { - return 0; -} -- (void)showDoSomethingSheetAction:(id)action { - id inputS = [[self inputS] retain]; - [NSApp beginSheet:0 - modalForWindow:0 - modalDelegate:0 - didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:(void *)inputS]; // no - warning -} -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { - - id contextObject = (id)contextInfo; - [contextObject release]; -} - -- (id)copyAutoreleaseRadar13081402 { - id x = [[[NSString alloc] initWithUTF8String:"foo"] autorelease]; - [x retain]; - return x; // no warning -} - -@end -//===----------------------------------------------------------------------===// -// Test returning allocated memory in a struct. -// -// We currently don't have a general way to track pointers that "escape". -// Here we test that RetainCountChecker doesn't get excited about returning -// allocated CF objects in struct fields. -//===----------------------------------------------------------------------===// -void *malloc(size_t); -struct rdar11104566 { CFStringRef myStr; }; -struct rdar11104566 test_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 V; - V.myStr = cf; - return V; // no-warning -} - -struct rdar11104566 *test_2_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V)); - V->myStr = cf; - return V; // no-warning -} - -//===----------------------------------------------------------------------===// -// ObjC literals support. -//===----------------------------------------------------------------------===// - -void test_objc_arrays(void) { - { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}} - [o release]; - [a description]; - [o description]; - } - - { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY - NSObject *o = [[NSObject alloc] init]; - NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; - NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}} - [o release]; - [a2 description]; - [o description]; - } - - { // CASE THREE -- OBJECT IN RETAINED @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a3 = [@[o] retain]; // expected-warning {{leak}} - [o release]; - [a3 description]; - [o description]; - } - - { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } - - { // CASE FIVE -- OBJECT IN RETAINED @{} - NSValue *o = [[NSValue alloc] init]; - NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } -} - -void test_objc_integer_literals(void) { - id value = [@1 retain]; // expected-warning {{leak}} - [value description]; -} - -void test_objc_boxed_expressions(int x, const char *y) { - id value = [@(x) retain]; // expected-warning {{leak}} - [value description]; - - value = [@(y) retain]; // expected-warning {{leak}} - [value description]; -} - -// Test NSLog doesn't escape tracked objects. -void rdar11400885(int y) -{ - @autoreleasepool { - NSString *printString; - if(y > 2) - printString = [[NSString alloc] init]; - else - printString = [[NSString alloc] init]; - NSLog(@"Once %@", printString); - [printString release]; - NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}} - } -} - -id makeCollectableNonLeak(void) { - extern CFTypeRef CFCreateSomething(void); - - CFTypeRef object = CFCreateSomething(); // +1 - CFRetain(object); // +2 - id objCObject = NSMakeCollectable(object); // +2 - [objCObject release]; // +1 - return [objCObject autorelease]; // +0 -} - - -void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void)); -void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void)); - -void testConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - consumeAndStopTracking(retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - consumeAndStopTracking(doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -void testCFConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} -//===----------------------------------------------------------------------===// -// Test 'pragma clang arc_cf_code_audited' support. -//===----------------------------------------------------------------------===// - -typedef void *MyCFType; -#pragma clang arc_cf_code_audited begin -MyCFType CreateMyCFType(void); -#pragma clang arc_cf_code_audited end - -void test_custom_cf(void) { - MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}} -} - -//===----------------------------------------------------------------------===// -// Test calling CFPlugInInstanceCreate, which appears in CF but doesn't -// return a CF object. -//===----------------------------------------------------------------------===// - -void test_CFPlugInInstanceCreate(CFUUIDRef factoryUUID, CFUUIDRef typeUUID) { - CFPlugInInstanceCreate(kCFAllocatorDefault, factoryUUID, typeUUID); // no-warning -} - -//===----------------------------------------------------------------------===// -// PR14927: -drain only has retain-count semantics on NSAutoreleasePool. -//===----------------------------------------------------------------------===// - -@interface PR14927 : NSObject -- (void)drain; -@end - -void test_drain(void) { - PR14927 *obj = [[PR14927 alloc] init]; - [obj drain]; - [obj release]; // no-warning -} - -//===----------------------------------------------------------------------===// -// Allow cf_returns_retained and cf_returns_not_retained to mark a return -// value as tracked, even if the object isn't a known CF type. -//===----------------------------------------------------------------------===// - -MyCFType getCustom(void) __attribute__((cf_returns_not_retained)); -MyCFType makeCustom(void) __attribute__((cf_returns_retained)); - -void testCustomReturnsRetained(void) { - MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} -} - -void testCustomReturnsNotRetained(void) { - CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -//===----------------------------------------------------------------------===// -// Don't print variables which are out of the current scope. -//===----------------------------------------------------------------------===// -@interface MyObj12706177 : NSObject --(id)initX; -+(void)test12706177; -@end -static int Cond; -@implementation MyObj12706177 --(id)initX { - if (Cond) - return 0; - self = [super init]; - return self; -} -+(void)test12706177 { - id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} - [x release]; -} -@end - -//===----------------------------------------------------------------------===// -// xpc_connection_set_finalizer_f -//===----------------------------------------------------------------------===// -typedef xpc_object_t xpc_connection_t; -typedef void (*xpc_finalizer_t)(void *value); -void xpc_connection_set_context(xpc_connection_t connection, void *ctx); -void xpc_connection_set_finalizer_f(xpc_connection_t connection, - xpc_finalizer_t finalizer); -void releaseAfterXPC(void *context) { - [(NSArray *)context release]; -} - -void rdar13783514(xpc_connection_t connection) { - xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); - xpc_connection_set_finalizer_f(connection, releaseAfterXPC); -} // no-warning - -CFAttributedStringRef CFAttributedCreate(void *CFObj CF_CONSUMED) CF_RETURNS_RETAINED; - -@interface Action -- (SEL)action; -- (void)setAction:(SEL)aSelector; -- (id) target; -- (void)setTarget:(id)aTarget; -@end diff --git a/clang/test/ARCMT/objcmt-arc-cf-annotations.m.result b/clang/test/ARCMT/objcmt-arc-cf-annotations.m.result deleted file mode 100644 index 1e94129784880..0000000000000 --- a/clang/test/ARCMT/objcmt-arc-cf-annotations.m.result +++ /dev/null @@ -1,2063 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-annotation -objcmt-migrate-instancetype -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -#ifndef CF_IMPLICIT_BRIDGING_ENABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") -#else -#define CF_IMPLICIT_BRIDGING_ENABLED -#endif -#endif - -#ifndef CF_IMPLICIT_BRIDGING_DISABLED -#if __has_feature(arc_cf_code_audited) -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") -#else -#define CF_IMPLICIT_BRIDGING_DISABLED -#endif -#endif - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -//===----------------------------------------------------------------------===// -// The following code is reduced using delta-debugging from Mac OS X headers: -// -// #include -// #include -// #include -// #include -// #include -// #include -// -// It includes the basic definitions for the test cases below. -//===----------------------------------------------------------------------===// - -typedef unsigned int __darwin_natural_t; -typedef unsigned long uintptr_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -typedef unsigned int UInt32; -typedef signed long CFIndex; -typedef CFIndex CFByteOrder; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; -static __inline__ __attribute__((always_inline)) CFRange CFRangeMake(CFIndex loc, CFIndex len) { - CFRange range; - range.location = loc; - range.length = len; - return range; -} -typedef const void * CFTypeRef; -typedef const struct __CFString * CFStringRef; -typedef const struct __CFAllocator * CFAllocatorRef; -extern const CFAllocatorRef kCFAllocatorDefault; -extern CFTypeRef CFRetain(CFTypeRef cf); - -CF_IMPLICIT_BRIDGING_ENABLED - -extern void CFRelease(CFTypeRef cf); - -CF_IMPLICIT_BRIDGING_DISABLED - -extern CFTypeRef CFAutorelease(CFTypeRef cf); -extern CFTypeRef CFMakeCollectable(CFTypeRef cf); -typedef struct { -} -CFArrayCallBacks; -extern const CFArrayCallBacks kCFTypeArrayCallBacks; -typedef const struct __CFArray * CFArrayRef; -typedef struct __CFArray * CFMutableArrayRef; -extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) CF_RETURNS_RETAINED; -extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx) CF_RETURNS_NOT_RETAINED; -extern void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value); -typedef struct { -} -CFDictionaryKeyCallBacks; -extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; -typedef struct { -} -CFDictionaryValueCallBacks; -extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; -extern CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) CF_RETURNS_RETAINED; -typedef UInt32 CFStringEncoding; -enum { -kCFStringEncodingMacRoman = 0, kCFStringEncodingWindowsLatin1 = 0x0500, kCFStringEncodingISOLatin1 = 0x0201, kCFStringEncodingNextStepLatin = 0x0B01, kCFStringEncodingASCII = 0x0600, kCFStringEncodingUnicode = 0x0100, kCFStringEncodingUTF8 = 0x08000100, kCFStringEncodingNonLossyASCII = 0x0BFF , kCFStringEncodingUTF16 = 0x0100, kCFStringEncodingUTF16BE = 0x10000100, kCFStringEncodingUTF16LE = 0x14000100, kCFStringEncodingUTF32 = 0x0c000100, kCFStringEncodingUTF32BE = 0x18000100, kCFStringEncodingUTF32LE = 0x1c000100 }; -extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding) CF_RETURNS_RETAINED; -typedef double CFTimeInterval; -typedef CFTimeInterval CFAbsoluteTime; -extern CFAbsoluteTime CFAbsoluteTimeGetCurrent(void); -typedef const struct __CFDate * CFDateRef; -extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at) CF_RETURNS_RETAINED; -extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate); -typedef __darwin_natural_t natural_t; -typedef natural_t mach_port_name_t; -typedef mach_port_name_t mach_port_t; -typedef int kern_return_t; -typedef kern_return_t mach_error_t; -enum { -kCFNumberSInt8Type = 1, kCFNumberSInt16Type = 2, kCFNumberSInt32Type = 3, kCFNumberSInt64Type = 4, kCFNumberFloat32Type = 5, kCFNumberFloat64Type = 6, kCFNumberCharType = 7, kCFNumberShortType = 8, kCFNumberIntType = 9, kCFNumberLongType = 10, kCFNumberLongLongType = 11, kCFNumberFloatType = 12, kCFNumberDoubleType = 13, kCFNumberCFIndexType = 14, kCFNumberNSIntegerType = 15, kCFNumberCGFloatType = 16, kCFNumberMaxType = 16 }; -typedef CFIndex CFNumberType; -typedef const struct __CFNumber * CFNumberRef; -extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr) CF_RETURNS_RETAINED; -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; -extern CFAttributedStringRef CFAttributedStringCreate(CFAllocatorRef alloc, CFStringRef str, CFDictionaryRef attributes) CF_RETURNS_RETAINED ; -extern CFMutableAttributedStringRef CFAttributedStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFAttributedStringRef aStr) CF_RETURNS_RETAINED ; -extern void CFAttributedStringSetAttribute(CFMutableAttributedStringRef aStr, CFRange range, CFStringRef attrName, CFTypeRef value) ; -typedef signed char BOOL; -typedef unsigned long NSUInteger; -@class NSString, Protocol; -extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))); -typedef struct _NSZone NSZone; -@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -- (id)autorelease; -- (NSString *)description; -- (instancetype)init; -@end -@protocol NSCopying -- (id)copyWithZone:(NSZone *)zone; -@end -@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; -@end -@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; -@end -@interface NSObject {} -+ (id)allocWithZone:(NSZone *)zone; -+ (id)alloc; -+ (id)new; -- (void)dealloc; -@end -@interface NSObject (NSCoderMethods) -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder; -@end -extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); -typedef struct { -} -NSFastEnumerationState; -@protocol NSFastEnumeration -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len; -@end -@class NSString, NSDictionary; -@interface NSValue : NSObject - (void)getValue:(void *)value; -@end -@interface NSNumber : NSValue -- (char)charValue; -- (instancetype)initWithInt:(int)value; -+ (NSNumber *)numberWithInt:(int)value; -@end -@class NSString; -@interface NSArray : NSObject -- (NSUInteger)count; -- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (instancetype)arrayWithObject:(id)anObject; -+ (instancetype)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt; -+ (instancetype)arrayWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (instancetype)initWithObjects:(id)firstObj, ... __attribute__((sentinel(0,1))); -- (instancetype)initWithArray:(NSArray *)array; -@end @interface NSArray (NSArrayCreation) + (instancetype)array; -@end @interface NSAutoreleasePool : NSObject { -} -- (void)drain; -@end extern NSString * const NSBundleDidLoadNotification; -typedef double NSTimeInterval; -@interface NSDate : NSObject - (NSTimeInterval)timeIntervalSinceReferenceDate; -@end typedef unsigned short unichar; -@interface NSString : NSObject -- (NSUInteger)length; -- (NSString *)stringByAppendingString:(NSString *)aString; -- ( const char *)UTF8String; -- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; -+ (instancetype)stringWithUTF8String:(const char *)nullTerminatedCString; -@end @class NSString, NSURL, NSError; -@interface NSData : NSObject - (NSUInteger)length; -+ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length; -+ (instancetype)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length freeWhenDone:(BOOL)b; -@end @class NSLocale, NSDate, NSCalendar, NSTimeZone, NSError, NSArray, NSMutableDictionary; -@interface NSDictionary : NSObject -- (NSUInteger)count; -+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -+ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; -@end -@interface NSMutableDictionary : NSDictionary - (void)removeObjectForKey:(id)aKey; -- (void)setObject:(id)anObject forKey:(id)aKey; -@end @interface NSMutableDictionary (NSMutableDictionaryCreation) + (instancetype)dictionaryWithCapacity:(NSUInteger)numItems; -@end typedef double CGFloat; -struct CGSize { -}; -typedef struct CGSize CGSize; -struct CGRect { -}; -typedef struct CGRect CGRect; -typedef mach_port_t io_object_t; -typedef char io_name_t[128]; -typedef io_object_t io_iterator_t; -typedef io_object_t io_service_t; -typedef struct IONotificationPort * IONotificationPortRef; -typedef void (*IOServiceMatchingCallback)( void * refcon, io_iterator_t iterator ); - -CF_IMPLICIT_BRIDGING_ENABLED - -io_service_t IOServiceGetMatchingService( mach_port_t mainPort, CFDictionaryRef matching ); -kern_return_t IOServiceGetMatchingServices( mach_port_t mainPort, CFDictionaryRef matching, io_iterator_t * existing ); - -CF_IMPLICIT_BRIDGING_DISABLED - -kern_return_t IOServiceAddNotification( mach_port_t mainPort, const io_name_t notificationType, CFDictionaryRef matching, mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}} -kern_return_t IOServiceAddMatchingNotification( IONotificationPortRef notifyPort, const io_name_t notificationType, CFDictionaryRef CF_CONSUMED matching, IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification ); - -CF_IMPLICIT_BRIDGING_ENABLED - -CFMutableDictionaryRef IOServiceMatching( const char * name ); -CFMutableDictionaryRef IOServiceNameMatching( const char * name ); -CFMutableDictionaryRef IOBSDNameMatching( mach_port_t mainPort, uint32_t options, const char * bsdName ); -CFMutableDictionaryRef IOOpenFirmwarePathMatching( mach_port_t mainPort, uint32_t options, const char * path ); -CFMutableDictionaryRef IORegistryEntryIDMatching( uint64_t entryID ); - -CF_IMPLICIT_BRIDGING_DISABLED - -typedef struct __DASession * DASessionRef; -extern DASessionRef DASessionCreate( CFAllocatorRef allocator ) CF_RETURNS_RETAINED; -typedef struct __DADisk * DADiskRef; -extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name ) CF_RETURNS_RETAINED; -extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media ) CF_RETURNS_RETAINED; -extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk ) CF_RETURNS_RETAINED; -extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk ) CF_RETURNS_RETAINED; -@interface NSTask : NSObject - (instancetype)init; -@end typedef struct CGColorSpace *CGColorSpaceRef; -typedef struct CGImage *CGImageRef; -typedef struct CGLayer *CGLayerRef; -@interface NSResponder : NSObject { -} -@end @protocol NSAnimatablePropertyContainer - (id)animator; -@end extern NSString *NSAnimationTriggerOrderIn ; -@interface NSView : NSResponder { -} -@end @protocol NSValidatedUserInterfaceItem - (SEL)action; -@end @protocol NSUserInterfaceValidations - (BOOL)validateUserInterfaceItem:(id )anItem; -@end @class NSDate, NSDictionary, NSError, NSException, NSNotification; -@class NSTextField, NSPanel, NSArray, NSWindow, NSImage, NSButton, NSError; -@interface NSApplication : NSResponder { -} -- (void)beginSheet:(NSWindow *)sheet modalForWindow:(NSWindow *)docWindow modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; -@end enum { -NSTerminateCancel = 0, NSTerminateNow = 1, NSTerminateLater = 2 }; -typedef NSUInteger NSApplicationTerminateReply; -@protocol NSApplicationDelegate @optional - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; -@end @class NSAttributedString, NSEvent, NSFont, NSFormatter, NSImage, NSMenu, NSText, NSView, NSTextView; -@interface NSCell : NSObject { -} -@end -typedef struct { -} -CVTimeStamp; -@interface CIImage : NSObject { -} -typedef int CIFormat; -@end enum { -kDAReturnSuccess = 0, kDAReturnError = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01, kDAReturnBusy = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02, kDAReturnBadArgument = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03, kDAReturnExclusiveAccess = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04, kDAReturnNoResources = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05, kDAReturnNotFound = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06, kDAReturnNotMounted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07, kDAReturnNotPermitted = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08, kDAReturnNotPrivileged = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09, kDAReturnNotReady = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A, kDAReturnNotWritable = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B, kDAReturnUnsupported = (((0x3eU)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C }; -typedef mach_error_t DAReturn; -typedef const struct __DADissenter * DADissenterRef; -extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string ) CF_RETURNS_RETAINED; -@interface CIContext: NSObject { -} -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r CF_RETURNS_RETAINED; -- (CGImageRef)createCGImage:(CIImage *)im fromRect:(CGRect)r format:(CIFormat)f colorSpace:(CGColorSpaceRef)cs CF_RETURNS_RETAINED; -- (CGLayerRef)createCGLayerWithSize:(CGSize)size info:(CFDictionaryRef)d CF_RETURNS_RETAINED; -@end extern NSString* const QCRendererEventKey; -@protocol QCCompositionRenderer - (NSDictionary*) attributes; -@end @interface QCRenderer : NSObject { -} -- (id) createSnapshotImageOfType:(NSString*)type NS_RETURNS_RETAINED; -@end extern NSString* const QCViewDidStartRenderingNotification; -@interface QCView : NSView { -} -- (id) createSnapshotImageOfType:(NSString*)type NS_RETURNS_RETAINED; -@end enum { -ICEXIFOrientation1 = 1, ICEXIFOrientation2 = 2, ICEXIFOrientation3 = 3, ICEXIFOrientation4 = 4, ICEXIFOrientation5 = 5, ICEXIFOrientation6 = 6, ICEXIFOrientation7 = 7, ICEXIFOrientation8 = 8, }; -@class ICDevice; -@protocol ICDeviceDelegate @required - (void)didRemoveDevice:(ICDevice*)device; -@end extern NSString *const ICScannerStatusWarmingUp; -@class ICScannerDevice; -@protocol ICScannerDeviceDelegate @optional - (void)scannerDeviceDidBecomeAvailable:(ICScannerDevice*)scanner; -@end - -typedef long unsigned int __darwin_size_t; -typedef __darwin_size_t size_t; -typedef unsigned long CFTypeID; -struct CGPoint { - CGFloat x; - CGFloat y; -}; -typedef struct CGPoint CGPoint; -typedef struct CGGradient *CGGradientRef; -typedef uint32_t CGGradientDrawingOptions; -extern CFTypeID CGGradientGetTypeID(void); -extern CGGradientRef CGGradientCreateWithColorComponents(CGColorSpaceRef - space, const CGFloat components[], const CGFloat locations[], size_t count) CF_RETURNS_RETAINED; -extern CGGradientRef CGGradientCreateWithColors(CGColorSpaceRef space, - CFArrayRef colors, const CGFloat locations[]) CF_RETURNS_RETAINED; -extern CGGradientRef CGGradientRetain(CGGradientRef gradient); - -CF_IMPLICIT_BRIDGING_ENABLED - -extern void CGGradientRelease(CGGradientRef gradient); - -CF_IMPLICIT_BRIDGING_DISABLED - -typedef struct CGContext *CGContextRef; -extern void CGContextDrawLinearGradient(CGContextRef context, - CGGradientRef gradient, CGPoint startPoint, CGPoint endPoint, - CGGradientDrawingOptions options); - -CF_IMPLICIT_BRIDGING_ENABLED - -extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void); - -CF_IMPLICIT_BRIDGING_DISABLED - - -@interface NSMutableArray : NSObject -- (void)addObject:(id)object; -+ (instancetype)array; -@end - -// This is how NSMakeCollectable is declared in the OS X 10.8 headers. -id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained)); - -typedef const struct __CFUUID * CFUUIDRef; - -extern -void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID); - -//===----------------------------------------------------------------------===// -// Test cases. -//===----------------------------------------------------------------------===// - -CFAbsoluteTime f1(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - CFRetain(date); - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - CFRelease(date); - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - -CFAbsoluteTime f2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // expected-warning{{Reference-counted object is used after it is released}} - return t; -} - - -NSDate* global_x; - -// Test to see if we suppress an error when we store the pointer -// to a global. - -CFAbsoluteTime f3(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); - [((NSDate*) date) retain]; - CFRelease(date); - CFDateGetAbsoluteTime(date); // no-warning - global_x = (NSDate*) date; - [((NSDate*) date) release]; - t = CFDateGetAbsoluteTime(date); // no-warning - return t; -} - -//--------------------------------------------------------------------------- -// Test case 'f4' differs for region store and basic store. See -// retain-release-region-store.m and retain-release-basic-store.m. -//--------------------------------------------------------------------------- - -// Test a leak. - -CFAbsoluteTime f5(int x) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFDateRef date = CFDateCreate(0, t); // expected-warning{{leak}} - - if (x) - CFRelease(date); - - return t; -} - -// Test a leak involving the return. - -CFDateRef f6(int x) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -// Test a leak involving an overwrite. - -CFDateRef f7(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} - CFRetain(date); - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // expected-warning {{leak}} - return date; -} - -// Generalization of Create rule. MyDateCreate returns a CFXXXTypeRef, and -// has the word create. - -CF_IMPLICIT_BRIDGING_ENABLED - -CFDateRef MyDateCreate(void); - -CF_IMPLICIT_BRIDGING_DISABLED - - -CFDateRef f8(void) { - CFDateRef date = MyDateCreate(); // expected-warning{{leak}} - CFRetain(date); - return date; -} - -__attribute__((cf_returns_retained)) CFDateRef f9(void) { - CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); // no-warning - int *p = 0; - // When allocations fail, CFDateCreate can return null. - if (!date) *p = 1; // expected-warning{{null}} - return date; -} - -// Handle DiskArbitration API: -// -// http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/DiscArbitrationFramework/ -// -void f10(io_service_t media, DADiskRef d, CFStringRef s) { - DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, 0, "hello"); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - disk = DADiskCreateFromIOMedia(kCFAllocatorDefault, 0, media); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - CFDictionaryRef dict = DADiskCopyDescription(d); // expected-warning{{leak}} - if (dict) NSLog(@"ok"); - - disk = DADiskCopyWholeDisk(d); // expected-warning{{leak}} - if (disk) NSLog(@"ok"); - - DADissenterRef dissenter = DADissenterCreate(kCFAllocatorDefault, // expected-warning{{leak}} - kDAReturnSuccess, s); - if (dissenter) NSLog(@"ok"); - - DASessionRef session = DASessionCreate(kCFAllocatorDefault); // expected-warning{{leak}} - if (session) NSLog(@"ok"); -} - -// Test retain/release checker with CFString and CFMutableArray. -void f11(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - - // Create a string. - CFStringRef s1 = CFStringCreateWithCString(0, "hello world", - kCFStringEncodingUTF8); - - // Add the string to the array. - CFArrayAppendValue(A, s1); - - // Decrement the reference count. - CFRelease(s1); // no-warning - - // Get the string. We don't own it. - s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0); - - // Release the array. - CFRelease(A); // no-warning - - // Release the string. This is a bug. - CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3337: Handle functions declared using typedefs. -typedef CFTypeRef CREATEFUN(void); - -CF_IMPLICIT_BRIDGING_ENABLED - -CFTypeRef MyCreateFun(void); - -CF_IMPLICIT_BRIDGING_DISABLED - - -void f12(void) { - CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} -} - -void f13_autorelease(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning - [(id) A autorelease]; // no-warning -} - -void f13_autorelease_b(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; -} // expected-warning{{Object autoreleased too many times}} - -CFMutableArrayRef f13_autorelease_c(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - return A; // expected-warning{{Object autoreleased too many times}} -} - -CFMutableArrayRef f13_autorelease_d(void) { - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - [(id) A autorelease]; - [(id) A autorelease]; - CFMutableArrayRef B = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{Object autoreleased too many times}} - CFRelease(B); // no-warning - while (1) {} -} - - -// This case exercises the logic where the leak site is the same as the allocation site. -void f14_leakimmediately(void) { - CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}} -} - -// Test that we track an allocated object beyond the point where the *name* -// of the variable storing the reference is no longer live. -void f15(void) { - // Create the array. - CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); - CFMutableArrayRef *B = &A; - // At this point, the name 'A' is no longer live. - CFRelease(*B); // no-warning -} - -// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f16(int x, CFTypeRef p) { - if (p) - return; - - switch (x) { - case 0: - CFRelease(p); - break; - case 1: - CFRetain(p); - break; - case 2: - CFMakeCollectable(p); - break; - case 3: - CFAutorelease(p); - break; - default: - break; - } -} - -// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease. -void f17(int x, CFTypeRef p) { - switch (x) { - case 0: - CFRelease(p); - if (!p) - CFRelease(0); // no-warning - break; - case 1: - CFRetain(p); - if (!p) - CFRetain(0); // no-warning - break; - case 2: - CFMakeCollectable(p); - if (!p) - CFMakeCollectable(0); // no-warning - break; - case 3: - CFAutorelease(p); - if (!p) - CFAutorelease(0); // no-warning - break; - default: - break; - } -} - -// Test basic tracking of ivars associated with 'self'. For the retain/release -// checker we currently do not want to flag leaks associated with stores -// of tracked objects to ivars. -@interface SelfIvarTest : NSObject { - id myObj; -} -- (void)test_self_tracking; -@end - -@implementation SelfIvarTest -- (void)test_self_tracking { - myObj = (id) CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} -@end - -// Test return of non-owned objects in contexts where an owned object -// is expected. -@interface TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString; -@end - -@implementation TestReturnNotOwnedWhenExpectedOwned -- (NSString*)newString { - NSString *s = [NSString stringWithUTF8String:"hello"]; - return s; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} -@end - -int isFoo(char c); - -static void rdar_6659160(char *inkind, char *inname) -{ - // We currently expect that [NSObject alloc] cannot fail. This - // will be a toggled flag in the future. It can indeed return null, but - // Cocoa programmers generally aren't expected to reason about out-of-memory - // conditions. - NSString *kind = [[NSString alloc] initWithUTF8String:inkind]; // expected-warning{{leak}} - - // We do allow stringWithUTF8String to fail. This isn't really correct, as - // far as returning 0. In most error conditions it will throw an exception. - // If allocation fails it could return 0, but again this - // isn't expected. - NSString *name = [NSString stringWithUTF8String:inname]; - if(!name) - return; - - const char *kindC = 0; - const char *nameC = 0; - - // In both cases, we cannot reach a point down below where we - // dereference kindC or nameC with either being null. This is because - // we assume that [NSObject alloc] doesn't fail and that we have the guard - // up above. - - if(kind) - kindC = [kind UTF8String]; - if(name) - nameC = [name UTF8String]; - if(!isFoo(kindC[0])) // expected-warning{{null}} - return; - if(!isFoo(nameC[0])) // no-warning - return; - - [kind release]; - [name release]; // expected-warning{{Incorrect decrement of the reference count}} -} - -// PR 3677 - 'allocWithZone' should be treated as following the Cocoa naming -// conventions with respect to 'return'ing ownership. -@interface PR3677: NSObject @end -@implementation PR3677 -+ (id)allocWithZone:(NSZone *)inZone { - return [super allocWithZone:inZone]; // no-warning -} -@end - -// PR 3820 - Reason about calls to -dealloc -void pr3820_DeallocInsteadOfRelease(void) -{ - id foo = [[NSString alloc] init]; // no-warning - [foo dealloc]; - // foo is not leaked, since it has been deallocated. -} - -void pr3820_ReleaseAfterDealloc(void) -{ - id foo = [[NSString alloc] init]; - [foo dealloc]; - [foo release]; // expected-warning{{used after it is release}} - // NSInternalInconsistencyException: message sent to deallocated object -} - -void pr3820_DeallocAfterRelease(void) -{ - NSLog(@"\n\n[%s]", __FUNCTION__); - id foo = [[NSString alloc] init]; - [foo release]; - [foo dealloc]; // expected-warning{{used after it is released}} - // message sent to released object -} - -// The problem here is that 'length' binds to '($0 - 1)' after '--length', but -// SimpleConstraintManager doesn't know how to reason about -// '($0 - 1) > constant'. As a temporary hack, we drop the value of '($0 - 1)' -// and conjure a new symbol. -void rdar6704930(unsigned char *s, unsigned int length) { - NSString* name = 0; - if (s != 0) { - if (length > 0) { - while (length > 0) { - if (*s == ':') { - ++s; - --length; - name = [[NSString alloc] init]; // no-warning - break; - } - ++s; - --length; - } - if ((length == 0) && (name != 0)) { - [name release]; - name = 0; - } - if (length == 0) { // no ':' found -> use it all as name - name = [[NSString alloc] init]; // no-warning - } - } - } - - if (name != 0) { - [name release]; - } -} - -//===----------------------------------------------------------------------===// -// One build of the analyzer accidentally stopped tracking the allocated -// object after the 'retain'. -//===----------------------------------------------------------------------===// - -@interface rdar_6833332 : NSObject { - NSWindow *window; -} -@property (nonatomic, retain) NSWindow *window; -@end - -@implementation rdar_6833332 -@synthesize window; -- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - - [dict setObject:@"foo" forKey:@"bar"]; - - NSLog(@"%@", dict); -} -- (void)dealloc { - [window release]; - [super dealloc]; -} - -- (void)radar10102244 { - NSMutableDictionary *dict = [[NSMutableDictionary dictionaryWithCapacity:4] retain]; // expected-warning{{leak}} - if (window) - NSLog(@"%@", window); -} -@end - -//===----------------------------------------------------------------------===// -// clang checker fails to catch use-after-release -//===----------------------------------------------------------------------===// -int rdar_6257780_Case1(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSArray *array = [NSArray array]; - [array release]; // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} - [pool drain]; - return 0; -} - -//===----------------------------------------------------------------------===// -// Analyzer is confused about NSAutoreleasePool -allocWithZone:. -//===----------------------------------------------------------------------===// -void rdar_10640253_autorelease_allocWithZone(void) { - NSAutoreleasePool *pool = [[NSAutoreleasePool allocWithZone:(NSZone*)0] init]; - (void) pool; -} - -//===----------------------------------------------------------------------===// -// Checker should understand new/setObject:/release constructs -//===----------------------------------------------------------------------===// -void rdar_6866843(void) { - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; - NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init]; - NSArray* array = [[NSArray alloc] init]; - [dictionary setObject:array forKey:@"key"]; - [array release]; - // Using 'array' here should be fine - NSLog(@"array = %@\n", array); // no-warning - // Now the array is released - [dictionary release]; - [pool drain]; -} - - -//===----------------------------------------------------------------------===// -// Classes typedef-ed to CF objects should get the same treatment as CF objects -//===----------------------------------------------------------------------===// -typedef CFTypeRef OtherRef; - -@interface RDar6877235 : NSObject {} -- (CFTypeRef)_copyCFTypeRef CF_RETURNS_RETAINED; -- (OtherRef)_copyOtherRef CF_RETURNS_RETAINED; -@end - -@implementation RDar6877235 -- (CFTypeRef)_copyCFTypeRef { - return [[NSString alloc] init]; // no-warning -} -- (OtherRef)_copyOtherRef { - return [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// false positive - init method returns an object owned by caller -//===----------------------------------------------------------------------===// -@interface RDar6320065 : NSObject { - NSString *_foo; -} -- (instancetype)initReturningNewClass; -- (id)_initReturningNewClassBad; -- (instancetype)initReturningNewClassBad2; -@end - -@interface RDar6320065Subclass : RDar6320065 -@end - -@implementation RDar6320065 -- (instancetype)initReturningNewClass { - [self release]; - self = [[RDar6320065Subclass alloc] init]; // no-warning - return self; -} -- (id)_initReturningNewClassBad { - [self release]; - [[RDar6320065Subclass alloc] init]; // expected-warning {{leak}} - return self; -} -- (instancetype)initReturningNewClassBad2 { - [self release]; - self = [[RDar6320065Subclass alloc] init]; - return [self autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -@end - -@implementation RDar6320065Subclass -@end - -int RDar6320065_test(void) { - RDar6320065 *test = [[RDar6320065 alloc] init]; // no-warning - [test release]; - return 0; -} - -//===----------------------------------------------------------------------===// -// -awakeAfterUsingCoder: returns an owned object and claims the receiver -//===----------------------------------------------------------------------===// -@interface RDar7129086 : NSObject {} @end -@implementation RDar7129086 -- (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { - [self release]; // no-warning - return [NSString alloc]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// [NSData dataWithBytesNoCopy] does not return a retained object -//===----------------------------------------------------------------------===// -@interface RDar6859457 : NSObject {} -- (NSString*) NoCopyString; -- (NSString*) noCopyString; -@end - -@implementation RDar6859457 -- (NSString*) NoCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -- (NSString*) noCopyString { return [[NSString alloc] init]; } // expected-warning{{leak}} -@end - -void test_RDar6859457(RDar6859457 *x, void *bytes, NSUInteger dataLength) { - [x NoCopyString]; // expected-warning{{leak}} - [x noCopyString]; // expected-warning{{leak}} - [NSData dataWithBytesNoCopy:bytes length:dataLength]; // no-warning - [NSData dataWithBytesNoCopy:bytes length:dataLength freeWhenDone:1]; // no-warning -} - -//===----------------------------------------------------------------------===// -// PR 4230 - an autorelease pool is not necessarily leaked during a premature -// return -//===----------------------------------------------------------------------===// - -static void PR4230(void) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -static void PR4230_new(void) -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; // no-warning - NSString *object = [[[NSString alloc] init] autorelease]; // no-warning - return; -} - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return [[NSString alloc] init]; // expected-warning{{leak}} -} -@end - -//===----------------------------------------------------------------------===// -// don't flag leaks for return types that cannot be determined to be CF types -//===----------------------------------------------------------------------===// - -// We don't know if 'struct s6893565' represents a Core Foundation type, so -// we shouldn't emit an error here. -typedef struct s6893565* TD6893565; - -@interface RDar6893565 {} --(TD6893565)newThing; -@end - -@implementation RDar6893565 --(TD6893565)newThing { - return (TD6893565) [[NSString alloc] init]; // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// clang: false positives w/QC and CoreImage methods -//===----------------------------------------------------------------------===// -void rdar6902710(QCView *view, QCRenderer *renderer, CIContext *context, - NSString *str, CIImage *img, CGRect rect, - CIFormat form, CGColorSpaceRef cs) { - [view createSnapshotImageOfType:str]; // expected-warning{{leak}} - [renderer createSnapshotImageOfType:str]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect]; // expected-warning{{leak}} - [context createCGImage:img fromRect:rect format:form colorSpace:cs]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// -[CIContext createCGLayerWithSize:info:] misinterpreted by clang scan-build -//===----------------------------------------------------------------------===// -void rdar6945561(CIContext *context, CGSize size, CFDictionaryRef d) { - [context createCGLayerWithSize:size info:d]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Add knowledge of IOKit functions to retain/release checker. -//===----------------------------------------------------------------------===// -void IOBSDNameMatching_wrapper(mach_port_t mainPort, uint32_t options, const char * bsdName) { - IOBSDNameMatching(mainPort, options, bsdName); // expected-warning{{leak}} -} - -void IOServiceMatching_wrapper(const char * name) { - IOServiceMatching(name); // expected-warning{{leak}} -} - -void IOServiceNameMatching_wrapper(const char * name) { - IOServiceNameMatching(name); // expected-warning{{leak}} -} - -CF_RETURNS_RETAINED CFDictionaryRef CreateDict(void); - -void IOServiceAddNotification_wrapper(mach_port_t mainPort, const io_name_t notificationType, - mach_port_t wakePort, uintptr_t reference, io_iterator_t * notification ) { - - CFDictionaryRef matching = CreateDict(); - CFRelease(matching); - IOServiceAddNotification(mainPort, notificationType, matching, // expected-warning{{used after it is released}} expected-warning{{deprecated}} - wakePort, reference, notification); -} - -void IORegistryEntryIDMatching_wrapper(uint64_t entryID ) { - IORegistryEntryIDMatching(entryID); // expected-warning{{leak}} -} - -void IOOpenFirmwarePathMatching_wrapper(mach_port_t mainPort, uint32_t options, - const char * path) { - IOOpenFirmwarePathMatching(mainPort, options, path); // expected-warning{{leak}} -} - -void IOServiceGetMatchingService_wrapper(mach_port_t mainPort) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingService(mainPort, matching); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceGetMatchingServices_wrapper(mach_port_t mainPort, io_iterator_t *existing) { - CFDictionaryRef matching = CreateDict(); - IOServiceGetMatchingServices(mainPort, matching, existing); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -void IOServiceAddMatchingNotification_wrapper(IONotificationPortRef notifyPort, const io_name_t notificationType, - IOServiceMatchingCallback callback, void * refCon, io_iterator_t * notification) { - - CFDictionaryRef matching = CreateDict(); - IOServiceAddMatchingNotification(notifyPort, notificationType, matching, callback, refCon, notification); - CFRelease(matching); // expected-warning{{used after it is released}} -} - -//===----------------------------------------------------------------------===// -// Test of handling objects whose references "escape" to containers. -//===----------------------------------------------------------------------===// -void CFDictionaryAddValue(CFMutableDictionaryRef, void *, void *); - -void rdar_6539791(CFMutableDictionaryRef y, void* key, void* val_key) { - CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionaryAddValue(y, key, x); - CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - if (value) { - CFDictionaryAddValue(x, val_key, (void*)value); // no-warning - CFRelease(value); - CFDictionaryAddValue(y, val_key, (void*)value); // no-warning - } -} - -// Same issue, except with "AppendValue" functions. -void rdar_6560661(CFMutableArrayRef x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); - // CFArrayAppendValue keeps a reference to value. - CFArrayAppendValue(x, value); - CFRelease(value); - CFRetain(value); - CFRelease(value); // no-warning -} - -// Same issue, excwept with "CFAttributeStringSetAttribute". -void rdar_7152619(CFStringRef str) { - CFAttributedStringRef string = CFAttributedStringCreate(kCFAllocatorDefault, str, 0); - CFMutableAttributedStringRef attrString = CFAttributedStringCreateMutableCopy(kCFAllocatorDefault, 100, string); - CFRelease(string); - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 1), str, number); - [number release]; - [number retain]; - CFRelease(attrString); -} - -//===----------------------------------------------------------------------===// -// Test of handling CGGradientXXX functions. -//===----------------------------------------------------------------------===// - -void rdar_7184450(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), // expected-warning{{leak}} - components, locations, num_locations); - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); - CGGradientRelease(myGradient); -} - -void rdar_7184450_pos(CGContextRef myContext, CGFloat x, CGPoint myStartPoint, - CGPoint myEndPoint) { - size_t num_locations = 6; - CGFloat locations[6] = { 0.0, 0.265, 0.28, 0.31, 0.36, 1.0 }; - CGFloat components[28] = { 239.0/256.0, 167.0/256.0, 170.0/256.0, - x, // Start color - 207.0/255.0, 39.0/255.0, 39.0/255.0, x, - 147.0/255.0, 21.0/255.0, 22.0/255.0, x, - 175.0/255.0, 175.0/255.0, 175.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x, - 255.0/255.0,255.0/255.0, 255.0/255.0, x - }; // End color - - CGGradientRef myGradient = - CGGradientCreateWithColorComponents(CGColorSpaceCreateDeviceRGB(), components, locations, num_locations); // expected-warning 2 {{leak}} - - CGContextDrawLinearGradient(myContext, myGradient, myStartPoint, myEndPoint, - 0); -} - -//===----------------------------------------------------------------------===// -// clang false positive: retained instance passed to thread in pthread_create -// marked as leak -// -// Until we have full IPA, the analyzer should stop tracking the reference -// count of objects passed to pthread_create. -// -//===----------------------------------------------------------------------===// -struct _opaque_pthread_t {}; -struct _opaque_pthread_attr_t {}; -typedef struct _opaque_pthread_t *__darwin_pthread_t; -typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t; -typedef __darwin_pthread_t pthread_t; -typedef __darwin_pthread_attr_t pthread_attr_t; -typedef unsigned long __darwin_pthread_key_t; -typedef __darwin_pthread_key_t pthread_key_t; - -int pthread_create(pthread_t *, const pthread_attr_t *, - void *(*)(void *), void *); - -int pthread_setspecific(pthread_key_t key, const void *value); - -void *rdar_7299394_start_routine(void *p) { - [((id) p) release]; - return 0; -} -void rdar_7299394(pthread_attr_t *attr, pthread_t *thread, void *args) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_create(thread, attr, rdar_7299394_start_routine, number); -} -void rdar_7299394_positive(pthread_attr_t *attr, pthread_t *thread) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// false positive with not understanding thread local storage -//===----------------------------------------------------------------------===// -void rdar11282706(pthread_key_t key) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - pthread_setspecific(key, (void*) number); -} - -//===----------------------------------------------------------------------===// -// False leak associated with call to CVPixelBufferCreateWithBytes () -// -// According to the Core Video Reference (ADC), CVPixelBufferCreateWithBytes and -// CVPixelBufferCreateWithPlanarBytes can release (via a callback) the -// pixel buffer object. These test cases show how the analyzer stops tracking -// the reference count for the objects passed for this argument. This -// could be made smarter. -//===----------------------------------------------------------------------===// -typedef int int32_t; -typedef UInt32 FourCharCode; -typedef FourCharCode OSType; -typedef uint64_t CVOptionFlags; -typedef int32_t CVReturn; -typedef struct __CVBuffer *CVBufferRef; -typedef CVBufferRef CVImageBufferRef; -typedef CVImageBufferRef CVPixelBufferRef; -typedef void (*CVPixelBufferReleaseBytesCallback)( void *releaseRefCon, const void *baseAddress ); - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -typedef void (*CVPixelBufferReleasePlanarBytesCallback)( void *releaseRefCon, const void *dataPtr, size_t dataSize, size_t numberOfPlanes, const void *planeAddresses[] ); - -extern CVReturn CVPixelBufferCreateWithPlanarBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *dataPtr, - size_t dataSize, - size_t numberOfPlanes, - void *planeBaseAddress[], - size_t planeWidth[], - size_t planeHeight[], - size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -extern CVReturn CVPixelBufferCreateWithBytes(CFAllocatorRef allocator, - size_t width, - size_t height, - OSType pixelFormatType, - void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - void *releaseRefCon, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) ; - -CVReturn rdar_7283567(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *baseAddress, - size_t bytesPerRow, - CVPixelBufferReleaseBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithBytes(allocator, width, height, pixelFormatType, - baseAddress, bytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -CVReturn rdar_7283567_2(CFAllocatorRef allocator, size_t width, size_t height, - OSType pixelFormatType, void *dataPtr, size_t dataSize, - size_t numberOfPlanes, void *planeBaseAddress[], - size_t planeWidth[], size_t planeHeight[], size_t planeBytesPerRow[], - CVPixelBufferReleasePlanarBytesCallback releaseCallback, - CFDictionaryRef pixelBufferAttributes, - CVPixelBufferRef *pixelBufferOut) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - return CVPixelBufferCreateWithPlanarBytes(allocator, - width, height, pixelFormatType, dataPtr, dataSize, - numberOfPlanes, planeBaseAddress, planeWidth, - planeHeight, planeBytesPerRow, releaseCallback, - number, // potentially released by callback - pixelBufferAttributes, pixelBufferOut) ; -} - -//===----------------------------------------------------------------------===// -// False leak associated with CGBitmapContextCreateWithData -//===----------------------------------------------------------------------===// -typedef uint32_t CGBitmapInfo; -typedef void (*CGBitmapContextReleaseDataCallback)(void *releaseInfo, void *data); - -CGContextRef CGBitmapContextCreateWithData(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback, void *releaseInfo) CF_RETURNS_RETAINED; - -void rdar_7358899(void *data, - size_t width, size_t height, size_t bitsPerComponent, - size_t bytesPerRow, CGColorSpaceRef space, CGBitmapInfo bitmapInfo, - CGBitmapContextReleaseDataCallback releaseCallback) { - - // For the allocated object, it doesn't really matter what type it is - // for the purpose of this test. All we want to show is that - // this is freed later by the callback. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - - CGBitmapContextCreateWithData(data, width, height, bitsPerComponent, // expected-warning{{leak}} - bytesPerRow, space, bitmapInfo, releaseCallback, number); -} - -//===----------------------------------------------------------------------===// -// Allow 'new', 'copy', 'alloc', 'init' prefix to start before '_' when -// determining Cocoa fundamental rule. -// -// Previously the retain/release checker just skipped prefixes before the -// first '_' entirely. Now the checker honors the prefix if it results in a -// recognizable naming convention (e.g., 'new', 'init'). -//===----------------------------------------------------------------------===// -@interface RDar7265711 {} -- (id) new_stuff; -@end - -void rdar7265711_a(RDar7265711 *x) { - id y = [x new_stuff]; // expected-warning{{leak}} -} - -void rdar7265711_b(RDar7265711 *x) { - id y = [x new_stuff]; // no-warning - [y release]; -} - -//===----------------------------------------------------------------------===// -// clang thinks [NSCursor dragCopyCursor] returns a retained reference -//===----------------------------------------------------------------------===// -@interface NSCursor : NSObject -+ (NSCursor *)dragCopyCursor; -@end - -void rdar7306898(void) { - // 'dragCopyCursor' does not follow Cocoa's fundamental rule. It is a noun, not an sentence - // implying a 'copy' of something. - NSCursor *c = [NSCursor dragCopyCursor]; // no-warning - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} -} - -//===----------------------------------------------------------------------===// -// Sending 'release', 'retain', etc. to a Class directly is not likely what the -// user intended. -//===----------------------------------------------------------------------===// -@interface RDar7252064 : NSObject @end -void rdar7252064(void) { - [RDar7252064 release]; // expected-warning{{The 'release' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 retain]; // expected-warning{{The 'retain' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [RDar7252064 autorelease]; // expected-warning{{The 'autorelease' message should be sent to instances of class 'RDar7252064' and not the class directly}} - [NSAutoreleasePool drain]; // expected-warning{{method '+drain' not found}} expected-warning{{The 'drain' message should be sent to instances of class 'NSAutoreleasePool' and not the class directly}} -} - -//===----------------------------------------------------------------------===// -// Tests of ownership attributes. -//===----------------------------------------------------------------------===// - -typedef NSString* MyStringTy; - -@protocol FooP; - -@interface TestOwnershipAttr : NSObject -- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning -- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning -- (NSString*) newStringNoAttr; -- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}} -- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED; -+ (void) consume:(id) NS_CONSUMED x; -+ (void) consume2:(id) CF_CONSUMED x; -@end - -static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}} - -void test_attr_1(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}} -} - -void test_attr_1b(TestOwnershipAttr *X) { - NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}} -} - -void test_attr1c(TestOwnershipAttr *X) { - NSString *str = [X newString]; // no-warning - NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}} - NSString *str3 = [X newString_auto]; // no-warning - NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}} -} - -void testattr2_a(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // expected-warning{{leak}} -} - -void testattr2_b(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // expected-warning{{leak}} -} - -void testattr2_b_11358224_self_assign_looses_the_leak(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit];// expected-warning{{leak}} - x = x; -} - -void testattr2_c(void) { - TestOwnershipAttr *x = [[TestOwnershipAttr alloc] pseudoInit]; // no-warning - [x release]; -} - -void testattr3(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume:x]; - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - [TestOwnershipAttr consume2:y]; -} - -void consume_ns(id NS_CONSUMED x); -void consume_cf(id CF_CONSUMED x); - -void testattr4(void) { - TestOwnershipAttr *x = [TestOwnershipAttr alloc]; // no-warning - consume_ns(x); - TestOwnershipAttr *y = [TestOwnershipAttr alloc]; // no-warning - consume_cf(y); -} - -@interface TestOwnershipAttr2 : NSObject -- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning -@end - -@implementation TestOwnershipAttr2 -- (NSString*) newString { - return [NSString alloc]; // expected-warning {{Potential leak of an object}} -} -@end - -@interface MyClassTestCFAttr : NSObject {} -- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED; -- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED; -- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED; -- (CFDateRef) newCFRetainedAsCFNoAttr CF_RETURNS_RETAINED; -- (NSDate*) alsoReturnsRetained; -- (CFDateRef) alsoReturnsRetainedAsCF CF_RETURNS_NOT_RETAINED; -- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED; -@end - -CF_RETURNS_RETAINED -CFDateRef returnsRetainedCFDate(void) { - return CFDateCreate(0, CFAbsoluteTimeGetCurrent()); -} - -@implementation MyClassTestCFAttr -- (NSDate*) returnsCFRetained { - return (NSDate*) returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) returnsCFRetainedAsCF { - return returnsRetainedCFDate(); // No leak. -} - -- (CFDateRef) newCFRetainedAsCF { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; -} - -- (CFDateRef) newCFRetainedAsCFNoAttr { - return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}} -} - -- (NSDate*) alsoReturnsRetained { - return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}} -} - -- (CFDateRef) alsoReturnsRetainedAsCF { - return returnsRetainedCFDate(); // expected-warning{{leak}} -} - - -- (NSDate*) returnsNSRetained { - return (NSDate*) returnsRetainedCFDate(); // no-warning -} -@end - -//===----------------------------------------------------------------------===// -// Test that leaks post-dominated by "panic" functions are not reported. -// -// Do not report a leak when post-dominated by a call to a noreturn or panic -// function. -//===----------------------------------------------------------------------===// -void panic(void) __attribute__((noreturn)); -void panic_not_in_hardcoded_list(void) __attribute__((noreturn)); - -void test_panic_negative(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} -} - -void test_panic_positive(void) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - panic(); -} - -void test_panic_neg_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // expected-warning{{leak}} - if (x) - panic(); -} - -void test_panic_pos_2(int x) { - signed z = 1; - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z); // no-warning - if (x) - panic(); - if (!x) { - // This showed up previously where we silently missed checking the function - // type for noreturn. "panic()" is a hard-coded known panic function that - // isn't always noreturn. - panic_not_in_hardcoded_list(); - } -} - -//===----------------------------------------------------------------------===// -// Test uses of blocks (closures) -//===----------------------------------------------------------------------===// - -void test_blocks_1_pos(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning{{leak}} - ^{}(); -} - -void test_blocks_1_indirect_release(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number release]; }(); -} - -void test_blocks_1_indirect_retain(void) { - // Eventually this should be reported as a leak. - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^{ [number retain]; }(); -} - -void test_blocks_1_indirect_release_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // no-warning - ^(NSObject *o){ [o release]; }(number); -} - -void test_blocks_1_indirect_retain_via_call(void) { - NSNumber *number = [[NSNumber alloc] initWithInt:5]; // expected-warning {{leak}} - ^(NSObject *o){ [o retain]; }(number); -} - -//===--------------------------------------------------------------------===// -// Test sending message to super that returns an object alias. Previously -// this caused a crash in the analyzer. -//===--------------------------------------------------------------------===// - -@interface Rdar8015556 : NSObject {} @end -@implementation Rdar8015556 -- (id)retain { - return [super retain]; -} -@end - -// Correcly handle Class<...> in Cocoa Conventions detector. -@protocol Prot_R8272168 @end -Class GetAClassThatImplementsProt_R8272168(void); -void r8272168(void) { - GetAClassThatImplementsProt_R8272168(); -} - -// Test case which in the past triggered a false positive. -@interface RDar8356342 -- (NSDate*) rdar8356342:(NSDate *)inValue; -@end - -@implementation RDar8356342 -- (NSDate*) rdar8356342:(NSDate*)inValue { - NSDate *outValue = inValue; - if (outValue == 0) - outValue = [[NSDate alloc] init]; // no-warning - - if (outValue != inValue) - [outValue autorelease]; - - return outValue; -} -@end - -// This test case previously crashed because of a bug in BugReporter. -extern const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key) CF_RETURNS_NOT_RETAINED; -typedef struct __CFError * CFErrorRef; -extern const CFStringRef kCFErrorUnderlyingErrorKey; -extern CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err) CF_RETURNS_RETAINED; -static void rdar_8724287(CFErrorRef error) -{ - CFErrorRef error_to_dump; - - error_to_dump = error; - while (error_to_dump != ((void*)0)) { - CFDictionaryRef info; - - info = CFErrorCopyUserInfo(error_to_dump); // expected-warning{{Potential leak of an object}} - - if (info != ((void*)0)) { - } - - error_to_dump = (CFErrorRef) CFDictionaryGetValue(info, kCFErrorUnderlyingErrorKey); - } -} - -// Make sure the model applies cf_consumed correctly in argument positions -// besides the first. - -CF_IMPLICIT_BRIDGING_ENABLED - -extern void *CFStringCreate(void); - -CF_IMPLICIT_BRIDGING_DISABLED - -extern void rdar_9234108_helper(void *key, void * CF_CONSUMED value); -void rdar_9234108(void) { - rdar_9234108_helper(0, CFStringCreate()); -} - -// Make sure that objc_method_family works to override naming conventions. -struct TwoDoubles { - double one; - double two; -}; -typedef struct TwoDoubles TwoDoubles; - -@interface NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles __attribute__((objc_method_family(init))); -@end - -@implementation NSValue (Mine) -- (id)_prefix_initWithTwoDoubles:(TwoDoubles)twoDoubles -{ - return [self init]; -} -@end - -void rdar9726279(void) { - TwoDoubles twoDoubles = { 0.0, 0.0 }; - NSValue *value = [[NSValue alloc] _prefix_initWithTwoDoubles:twoDoubles]; - [value release]; -} - -// Test camelcase support for CF conventions. While Core Foundation APIs -// don't use camel casing, other code is allowed to use it. -CFArrayRef camelcase_create_1(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_createno(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camelcase_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camelcase_copying(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __copyCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef __createCamelCase(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_create(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - - -CFArrayRef camel_creat(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -CFArrayRef camel_copy(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copyMachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning -} - -CFArrayRef camel_copymachine(void) { - return CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning {{leak}} -} - -@protocol F18P -- (id) clone; -@end -@interface F18 : NSObject @end -@interface F18(Cat) -- (id) clone NS_RETURNS_RETAINED; -@end - -@implementation F18 -- (id) clone { - return [F18 alloc]; -} -@end - -void rdar6582778(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - CFTypeRef vals[] = { CFDateCreate(0, t) }; // expected-warning {{leak}} -} - -CFTypeRef global; - -void rdar6582778_2(void) { - CFAbsoluteTime t = CFAbsoluteTimeGetCurrent(); - global = CFDateCreate(0, t); // no-warning -} - -// Test that objects passed to containers are marked "escaped". -void rdar10232019(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [array addObject:string]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // no-warning - NSLog(@"%@", otherString); -} - -void rdar10232019_positive(void) { - NSMutableArray *array = [NSMutableArray array]; - - NSString *string = [[NSString alloc] initWithUTF8String:"foo"]; - [string release]; - - NSString *otherString = [string stringByAppendingString:@"bar"]; // expected-warning {{Reference-counted object is used after it is release}} - NSLog(@"%@", otherString); -} - -// RetainCountChecker support for XPC. -typedef void * xpc_object_t; -xpc_object_t _CFXPCCreateXPCObjectFromCFObject(CFTypeRef cf); -void xpc_release(xpc_object_t object); - -void rdar9658496(void) { - CFStringRef cf; - xpc_object_t xpc; - cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - xpc = _CFXPCCreateXPCObjectFromCFObject( cf ); - CFRelease(cf); - xpc_release(xpc); -} - -// Support annotations with method families. -@interface RDar10824732 : NSObject -- (instancetype)initWithObj:(id CF_CONSUMED)obj; -@end - -@implementation RDar10824732 -- (instancetype)initWithObj:(id)obj { - [obj release]; - return [super init]; -} -@end - -void rdar_10824732(void) { - @autoreleasepool { - NSString *obj = @"test"; - RDar10824732 *foo = [[RDar10824732 alloc] initWithObj:obj]; // no-warning - [foo release]; - } -} - -// Stop tracking objects passed to functions, which take callbacks as parameters. -typedef int (*CloseCallback) (void *); -void ReaderForIO(CloseCallback ioclose, void *ioctx); -int IOClose(void *context); - -@protocol SInS -@end - -@interface radar10973977 : NSObject -- (id)inputS; -- (void)reader; -@end - -@implementation radar10973977 -- (void)reader -{ - id inputS = [[self inputS] retain]; - ReaderForIO(IOClose, inputS); -} -- (id)inputS -{ - return 0; -} -@end - -// Object escapes through a selector callback -extern id NSApp; -@interface MySheetController -- (id)inputS; -- (void)showDoSomethingSheetAction:(id)action; -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; -@end - -@implementation MySheetController -- (id)inputS { - return 0; -} -- (void)showDoSomethingSheetAction:(id)action { - id inputS = [[self inputS] retain]; - [NSApp beginSheet:0 - modalForWindow:0 - modalDelegate:0 - didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo:(void *)inputS]; // no - warning -} -- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo { - - id contextObject = (id)contextInfo; - [contextObject release]; -} - -- (id)copyAutoreleaseRadar13081402 { - id x = [[[NSString alloc] initWithUTF8String:"foo"] autorelease]; - [x retain]; - return x; // no warning -} - -@end -//===----------------------------------------------------------------------===// -// Test returning allocated memory in a struct. -// -// We currently don't have a general way to track pointers that "escape". -// Here we test that RetainCountChecker doesn't get excited about returning -// allocated CF objects in struct fields. -//===----------------------------------------------------------------------===// -void *malloc(size_t); -struct rdar11104566 { CFStringRef myStr; }; -struct rdar11104566 test_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 V; - V.myStr = cf; - return V; // no-warning -} - -struct rdar11104566 *test_2_rdar11104566(void) { - CFStringRef cf = CFStringCreateWithCString( ((CFAllocatorRef)0), "test", kCFStringEncodingUTF8 ); // no-warning - struct rdar11104566 *V = (struct rdar11104566 *) malloc(sizeof(*V)); - V->myStr = cf; - return V; // no-warning -} - -//===----------------------------------------------------------------------===// -// ObjC literals support. -//===----------------------------------------------------------------------===// - -void test_objc_arrays(void) { - { // CASE ONE -- OBJECT IN ARRAY CREATED DIRECTLY - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithObjects:o, (void*)0]; // expected-warning {{leak}} - [o release]; - [a description]; - [o description]; - } - - { // CASE TWO -- OBJECT IN ARRAY CREATED BY DUPING AUTORELEASED ARRAY - NSObject *o = [[NSObject alloc] init]; - NSArray *a1 = [NSArray arrayWithObjects:o, (void*)0]; - NSArray *a2 = [[NSArray alloc] initWithArray:a1]; // expected-warning {{leak}} - [o release]; - [a2 description]; - [o description]; - } - - { // CASE THREE -- OBJECT IN RETAINED @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a3 = [@[o] retain]; // expected-warning {{leak}} - [o release]; - [a3 description]; - [o description]; - } - - { // CASE FOUR -- OBJECT IN ARRAY CREATED BY DUPING @[] - NSObject *o = [[NSObject alloc] init]; - NSArray *a = [[NSArray alloc] initWithArray:@[o]]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } - - { // CASE FIVE -- OBJECT IN RETAINED @{} - NSValue *o = [[NSValue alloc] init]; - NSDictionary *a = [@{o : o} retain]; // expected-warning {{leak}} - [o release]; - - [a description]; - [o description]; - } -} - -void test_objc_integer_literals(void) { - id value = [@1 retain]; // expected-warning {{leak}} - [value description]; -} - -void test_objc_boxed_expressions(int x, const char *y) { - id value = [@(x) retain]; // expected-warning {{leak}} - [value description]; - - value = [@(y) retain]; // expected-warning {{leak}} - [value description]; -} - -// Test NSLog doesn't escape tracked objects. -void rdar11400885(int y) -{ - @autoreleasepool { - NSString *printString; - if(y > 2) - printString = [[NSString alloc] init]; - else - printString = [[NSString alloc] init]; - NSLog(@"Once %@", printString); - [printString release]; - NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}} - } -} - -id makeCollectableNonLeak(void) { - extern CFTypeRef CFCreateSomething(void); - - CFTypeRef object = CFCreateSomething(); // +1 - CFRetain(object); // +2 - id objCObject = NSMakeCollectable(object); // +2 - [objCObject release]; // +1 - return [objCObject autorelease]; // +0 -} - - -void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void)); -void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void)); - -void testConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - consumeAndStopTracking(retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - consumeAndStopTracking(doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -void testCFConsumeAndStopTracking(void) { - id retained = [@[] retain]; // +1 - CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning - - id doubleRetained = [[@[] retain] retain]; // +2 - CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{ - [doubleRetained release]; - }); // no-warning - - id unretained = @[]; // +0 - CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} -//===----------------------------------------------------------------------===// -// Test 'pragma clang arc_cf_code_audited' support. -//===----------------------------------------------------------------------===// - -typedef void *MyCFType; -#pragma clang arc_cf_code_audited begin -MyCFType CreateMyCFType(void); -#pragma clang arc_cf_code_audited end - -void test_custom_cf(void) { - MyCFType x = CreateMyCFType(); // expected-warning {{leak of an object stored into 'x'}} -} - -//===----------------------------------------------------------------------===// -// Test calling CFPlugInInstanceCreate, which appears in CF but doesn't -// return a CF object. -//===----------------------------------------------------------------------===// - -void test_CFPlugInInstanceCreate(CFUUIDRef factoryUUID, CFUUIDRef typeUUID) { - CFPlugInInstanceCreate(kCFAllocatorDefault, factoryUUID, typeUUID); // no-warning -} - -//===----------------------------------------------------------------------===// -// PR14927: -drain only has retain-count semantics on NSAutoreleasePool. -//===----------------------------------------------------------------------===// - -@interface PR14927 : NSObject -- (void)drain; -@end - -void test_drain(void) { - PR14927 *obj = [[PR14927 alloc] init]; - [obj drain]; - [obj release]; // no-warning -} - -//===----------------------------------------------------------------------===// -// Allow cf_returns_retained and cf_returns_not_retained to mark a return -// value as tracked, even if the object isn't a known CF type. -//===----------------------------------------------------------------------===// - -MyCFType getCustom(void) __attribute__((cf_returns_not_retained)); -MyCFType makeCustom(void) __attribute__((cf_returns_retained)); - -void testCustomReturnsRetained(void) { - MyCFType obj = makeCustom(); // expected-warning {{leak of an object stored into 'obj'}} -} - -void testCustomReturnsNotRetained(void) { - CFRelease(getCustom()); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} -} - -//===----------------------------------------------------------------------===// -// Don't print variables which are out of the current scope. -//===----------------------------------------------------------------------===// -@interface MyObj12706177 : NSObject --(instancetype)initX; -+(void)test12706177; -@end -static int Cond; -@implementation MyObj12706177 --(instancetype)initX { - if (Cond) - return 0; - self = [super init]; - return self; -} -+(void)test12706177 { - id x = [[MyObj12706177 alloc] initX]; //expected-warning {{Potential leak of an object}} - [x release]; -} -@end - -//===----------------------------------------------------------------------===// -// xpc_connection_set_finalizer_f -//===----------------------------------------------------------------------===// -typedef xpc_object_t xpc_connection_t; -typedef void (*xpc_finalizer_t)(void *value); -void xpc_connection_set_context(xpc_connection_t connection, void *ctx); -void xpc_connection_set_finalizer_f(xpc_connection_t connection, - xpc_finalizer_t finalizer); -void releaseAfterXPC(void *context) { - [(NSArray *)context release]; -} - -void rdar13783514(xpc_connection_t connection) { - xpc_connection_set_context(connection, [[NSMutableArray alloc] init]); - xpc_connection_set_finalizer_f(connection, releaseAfterXPC); -} // no-warning - -CFAttributedStringRef CFAttributedCreate(void *CFObj CF_CONSUMED) CF_RETURNS_RETAINED; - -@interface Action -@property (nonatomic) SEL action; -@property (nonatomic, assign) id target; -@end diff --git a/clang/test/ARCMT/objcmt-atomic-property.m b/clang/test/ARCMT/objcmt-atomic-property.m deleted file mode 100644 index 00b5e09c8e084..0000000000000 --- a/clang/test/ARCMT/objcmt-atomic-property.m +++ /dev/null @@ -1,227 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -- (void) setWeakProp : (NSString *__weak)Val; -- (NSString *__weak) WeakProp; - -- (NSString *) StrongProp; -- (void) setStrongProp : (NSString *)Val; - -- (NSString *) UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -- (NSString *) UnavailProp1 __attribute__((unavailable)); -- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); - -- (NSString *) UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -- (NSDictionary*) undoAction; -- (void) setUndoAction: (NSDictionary*)Arg; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -- (void)setNames1:(NSArray *)names; -- (void)setNames4:(__strong NSArray *)names; -- (void)setNames3:(__strong NSArray *)names; -- (void)setNames2:(NSArray *)names; -- (NSArray *) names2; -- (NSArray *)names3; -- (__strong NSArray *)names4; -- (NSArray *) names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; -- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -- (BOOL)isIgnoringInteractionEvents; - -- (NSString *)getStringValue; -- (BOOL)getCounterValue; -- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; -- (NSDictionary *)getns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - - -@interface NSInvocation(CAT) -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -- (NSURL *)appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; -- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -- (id)OkToInfer NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -- (id)method1 ALIGNED NS_AVAILABLE; -- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; -- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; -- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; -- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; -- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; -- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; -@end diff --git a/clang/test/ARCMT/objcmt-atomic-property.m.result b/clang/test/ARCMT/objcmt-atomic-property.m.result deleted file mode 100644 index c829a7aacb50d..0000000000000 --- a/clang/test/ARCMT/objcmt-atomic-property.m.result +++ /dev/null @@ -1,200 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -@property (weak) NSString *WeakProp; - -@property (strong) NSString *StrongProp; - -@property (strong) NSString *UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -@property (strong) NSString *UnavailProp1 __attribute__((unavailable)); - -@property (strong) NSString *UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -@property (copy) NSDictionary *undoAction; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -@property (strong) NSArray *names2; -@property (strong) NSArray *names3; -@property (strong) NSArray *names4; -@property (strong) NSArray *names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -@property (assign) id target; - -@property (assign) id dataSource; - -@property (assign) id xxxdelegateYYY; - - -@property (strong) id MYtarget; - -@property (strong) id targetX; - -@property int value; - -@property (getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (readonly) int Length; -@property (readonly, strong) id object; -+ (double) D; -@property (readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -@property (getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; - -@property (getter=getStringValue, strong) NSString *stringValue; -@property (getter=getCounterValue, readonly) BOOL counterValue; -@property (getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (getter=getM, readonly) BOOL m; -@property (getter=getMA, readonly) BOOL MA; -@property (getter=getALL, readonly) BOOL ALL; -@property (getter=getMANY, readonly) BOOL MANY; -@property (getter=getSome, readonly) BOOL some; -@end - - -@interface NSInvocation(CAT) -@property (assign) id target; - -@property (assign) id dataSource; - -@property (assign) id xxxdelegateYYY; - - -@property (strong) id MYtarget; - -@property (strong) id targetX; - -@property int value; - -@property (getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (readonly) int Length; -@property (readonly, strong) id object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (getter=getM, readonly) BOOL m; -@property (getter=getMA, readonly) BOOL MA; -@property (getter=getALL, readonly) BOOL ALL; -@property (getter=getMANY, readonly) BOOL MANY; -@property (getter=getSome, readonly) BOOL some; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -@property (strong) NSURL *appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -@property (strong) NSURL *appStoreReceiptURLX NS_AVAILABLE; - -// Do not infer a property. -@property (strong) NSURL *appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -@property (readonly, strong) id OkToInfer NS_AVAILABLE; - -// Do not infer a property. -@property (strong) NSURL *appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -@property (strong) id method1 ALIGNED NS_AVAILABLE; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -@property (getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -@property (readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); -@property (copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); -@property (readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); -@property id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); -@end diff --git a/clang/test/ARCMT/objcmt-boxing.m b/clang/test/ARCMT/objcmt-boxing.m deleted file mode 100644 index 07ee68dda33bd..0000000000000 --- a/clang/test/ARCMT/objcmt-boxing.m +++ /dev/null @@ -1,106 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -verify -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -#define INT_MIN (-__INT_MAX__ -1) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -enum { - NSASCIIStringEncoding = 1, - NSUTF8StringEncoding = 4, - NSUnicodeStringEncoding = 10 -}; -typedef NSUInteger NSStringEncoding; - -@interface NSString : NSObject -@end - -@interface NSString (NSStringExtensionMethods) -+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; -+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc; -+ (id)stringWithCString:(const char *)bytes; -- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; -@end - -enum MyEnm { - ME_foo -}; - -void foo() { - [NSNumber numberWithInt:INT_MIN]; - bool cppb; - [NSNumber numberWithBool:cppb]; - MyEnm myenum; - [NSNumber numberWithInteger:myenum]; - [NSNumber numberWithInteger:ME_foo]; - [NSNumber numberWithDouble:cppb]; // expected-warning {{converting to boxing syntax requires casting 'bool' to 'double'}} -} - -void boxString() { - NSString *s = [NSString stringWithUTF8String:"box"]; - const char *cstr1; - char *cstr2; - s = [NSString stringWithUTF8String:cstr1]; - s = [NSString stringWithUTF8String:cstr2]; - s = [NSString stringWithCString:cstr1 encoding:NSASCIIStringEncoding]; - s = [NSString stringWithCString:cstr1 encoding:NSUTF8StringEncoding]; - s = [NSString stringWithCString:cstr1 encoding: NSUnicodeStringEncoding]; - NSStringEncoding encode; - s = [NSString stringWithCString:cstr1 encoding:encode]; - s = [NSString stringWithCString:cstr1]; - - static const char strarr[] = "coolbox"; - s = [NSString stringWithUTF8String:strarr]; - const char *utf8Bytes = "blah"; - NSString *string1 = [NSString stringWithUTF8String:utf8Bytes]; - NSString *string2 = [[NSString alloc] initWithUTF8String:utf8Bytes]; -} diff --git a/clang/test/ARCMT/objcmt-boxing.m.result b/clang/test/ARCMT/objcmt-boxing.m.result deleted file mode 100644 index a60b35900bf38..0000000000000 --- a/clang/test/ARCMT/objcmt-boxing.m.result +++ /dev/null @@ -1,106 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -verify -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -#define INT_MIN (-__INT_MAX__ -1) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -enum { - NSASCIIStringEncoding = 1, - NSUTF8StringEncoding = 4, - NSUnicodeStringEncoding = 10 -}; -typedef NSUInteger NSStringEncoding; - -@interface NSString : NSObject -@end - -@interface NSString (NSStringExtensionMethods) -+ (id)stringWithUTF8String:(const char *)nullTerminatedCString; -+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc; -+ (id)stringWithCString:(const char *)bytes; -- (instancetype)initWithUTF8String:(const char *)nullTerminatedCString; -@end - -enum MyEnm { - ME_foo -}; - -void foo() { - @INT_MIN; - bool cppb; - @(cppb); - MyEnm myenum; - @(myenum); - @(ME_foo); - [NSNumber numberWithDouble:cppb]; // expected-warning {{converting to boxing syntax requires casting 'bool' to 'double'}} -} - -void boxString() { - NSString *s = @"box"; - const char *cstr1; - char *cstr2; - s = @(cstr1); - s = @(cstr2); - s = @(cstr1); - s = @(cstr1); - s = [NSString stringWithCString:cstr1 encoding: NSUnicodeStringEncoding]; - NSStringEncoding encode; - s = [NSString stringWithCString:cstr1 encoding:encode]; - s = @(cstr1); - - static const char strarr[] = "coolbox"; - s = @(strarr); - const char *utf8Bytes = "blah"; - NSString *string1 = @(utf8Bytes); - NSString *string2 = @(utf8Bytes); -} diff --git a/clang/test/ARCMT/objcmt-designated-initializer.m b/clang/test/ARCMT/objcmt-designated-initializer.m deleted file mode 100644 index 279d4f35d8eb1..0000000000000 --- a/clang/test/ARCMT/objcmt-designated-initializer.m +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result - -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(id)init; -@end - -@interface S1 : B1 --(id)initWithFoo:(NSString*)foo; -@end - -@implementation S1 --(id)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end - -@interface B2 --(id)init NS_DESIGNATED_INITIALIZER; -@end - -@interface S2 : B2 --(id)init; -@end - -@implementation S2 --(id)init -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/objcmt-designated-initializer.m.result b/clang/test/ARCMT/objcmt-designated-initializer.m.result deleted file mode 100644 index 4c59b0cc58261..0000000000000 --- a/clang/test/ARCMT/objcmt-designated-initializer.m.result +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result - -#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) - -@class NSString; - -@interface B1 --(id)init; -@end - -@interface S1 : B1 --(id)initWithFoo:(NSString*)foo NS_DESIGNATED_INITIALIZER; -@end - -@implementation S1 --(id)initWithFoo:(NSString*)foo -{ - self = [super init]; - if (self) { - } - return self; -} -@end - -@interface B2 --(id)init NS_DESIGNATED_INITIALIZER; -@end - -@interface S2 : B2 --(id)init; -@end - -@implementation S2 --(id)init -{ - self = [super init]; - if (self) { - } - return self; -} -@end diff --git a/clang/test/ARCMT/objcmt-instancetype-2.m b/clang/test/ARCMT/objcmt-instancetype-2.m deleted file mode 100644 index fb59265c4be32..0000000000000 --- a/clang/test/ARCMT/objcmt-instancetype-2.m +++ /dev/null @@ -1,103 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef unsigned int NSUInteger; -typedef int NSInteger; -typedef char BOOL; -@class NSData, NSError, NSProtocolChecker, NSObject; -@class NSPortNameServer, NSTimeZone; - -@interface NSMutableString -@end - -@interface NSString @end - -@class NSString, NSURL; -@interface NSString (NSStringDeprecated) -+ (id)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -@end - - -typedef enum NSURLBookmarkResolutionOptions { - Bookmark -} NSURLBookmarkResolutionOptions; - -@interface NSURL -+ (id)URLWithString:(NSString *)URLString; -+ (id)URLWithString:(NSString *)URLString relativeToURL:(NSURL *)baseURL; -+ (id)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(NSURLBookmarkResolutionOptions)options relativeToURL:(NSURL *)relativeURL bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error __attribute__((availability(macosx,introduced=10.6))); -@end - -@class NSDictionary; -@interface NSError -+ (id)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict; -@end - - -@interface NSMutableString (NSMutableStringExtensionMethods) -+ (id)stringWithCapacity:(NSUInteger)capacity; -@end - -@interface NSMutableData -+ (id)dataWithCapacity:(NSUInteger)aNumItems; -+ (id)dataWithLength:(NSUInteger)length; -@end - -@interface NSMutableDictionary @end - -@interface NSMutableDictionary (NSSharedKeySetDictionary) -+ (id )dictionaryWithSharedKeySet:(id)keyset __attribute__((availability(macosx,introduced=10.8))); -@end - -@interface NSProtocolChecker -+ (id)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol; -@end - -@interface NSConnection -+ (id)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName; -+ (id)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName usingNameServer:(NSPortNameServer *)server; -@end - -@interface NSDate -+ (id)dateWithString:(NSString *)aString __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSCalendarDate : NSDate -+ (id)calendarDate __attribute__((availability(macosx,introduced=10.4))); -+ (id)dateWithString:(NSString *)description calendarFormat:(NSString *)format locale:(id)locale __attribute__((availability(macosx,introduced=10.4))); -+ (id)dateWithString:(NSString *)description calendarFormat:(NSString *)format __attribute__((availability(macosx,introduced=10.4))); -+ (id)dateWithYear:(NSInteger)year month:(NSUInteger)month day:(NSUInteger)day hour:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second timeZone:(NSTimeZone *)aTimeZone __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSUserDefaults -+ (id) standardUserDefaults; -@end - -@interface NSNotificationCenter -+ (id) defaultCenter; -+ sharedCenter; -@end - -@interface UIApplication -+ (id)sharedApplication; -+ defaultApplication; -@end - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return 0; -} -@end - diff --git a/clang/test/ARCMT/objcmt-instancetype-2.m.result b/clang/test/ARCMT/objcmt-instancetype-2.m.result deleted file mode 100644 index 7a32894f57060..0000000000000 --- a/clang/test/ARCMT/objcmt-instancetype-2.m.result +++ /dev/null @@ -1,103 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef unsigned int NSUInteger; -typedef int NSInteger; -typedef char BOOL; -@class NSData, NSError, NSProtocolChecker, NSObject; -@class NSPortNameServer, NSTimeZone; - -@interface NSMutableString -@end - -@interface NSString @end - -@class NSString, NSURL; -@interface NSString (NSStringDeprecated) -+ (id)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -+ (id)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" ))); -@end - - -typedef enum NSURLBookmarkResolutionOptions { - Bookmark -} NSURLBookmarkResolutionOptions; - -@interface NSURL -+ (instancetype)URLWithString:(NSString *)URLString; -+ (instancetype)URLWithString:(NSString *)URLString relativeToURL:(NSURL *)baseURL; -+ (instancetype)URLByResolvingBookmarkData:(NSData *)bookmarkData options:(NSURLBookmarkResolutionOptions)options relativeToURL:(NSURL *)relativeURL bookmarkDataIsStale:(BOOL *)isStale error:(NSError **)error __attribute__((availability(macosx,introduced=10.6))); -@end - -@class NSDictionary; -@interface NSError -+ (instancetype)errorWithDomain:(NSString *)domain code:(NSInteger)code userInfo:(NSDictionary *)dict; -@end - - -@interface NSMutableString (NSMutableStringExtensionMethods) -+ (instancetype)stringWithCapacity:(NSUInteger)capacity; -@end - -@interface NSMutableData -+ (instancetype)dataWithCapacity:(NSUInteger)aNumItems; -+ (instancetype)dataWithLength:(NSUInteger)length; -@end - -@interface NSMutableDictionary @end - -@interface NSMutableDictionary (NSSharedKeySetDictionary) -+ (instancetype )dictionaryWithSharedKeySet:(id)keyset __attribute__((availability(macosx,introduced=10.8))); -@end - -@interface NSProtocolChecker -+ (instancetype)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol; -@end - -@interface NSConnection -+ (instancetype)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName; -+ (instancetype)connectionWithRegisteredName:(NSString *)name host:(NSString *)hostName usingNameServer:(NSPortNameServer *)server; -@end - -@interface NSDate -+ (instancetype)dateWithString:(NSString *)aString __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSCalendarDate : NSDate -+ (instancetype)calendarDate __attribute__((availability(macosx,introduced=10.4))); -+ (instancetype)dateWithString:(NSString *)description calendarFormat:(NSString *)format locale:(id)locale __attribute__((availability(macosx,introduced=10.4))); -+ (instancetype)dateWithString:(NSString *)description calendarFormat:(NSString *)format __attribute__((availability(macosx,introduced=10.4))); -+ (instancetype)dateWithYear:(NSInteger)year month:(NSUInteger)month day:(NSUInteger)day hour:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second timeZone:(NSTimeZone *)aTimeZone __attribute__((availability(macosx,introduced=10.4))); -@end - -@interface NSUserDefaults -+ (instancetype) standardUserDefaults; -@end - -@interface NSNotificationCenter -+ (NSNotificationCenter*) defaultCenter; -+ (NSNotificationCenter*) sharedCenter; -@end - -@interface UIApplication -+ (UIApplication*)sharedApplication; -+ (UIApplication*) defaultApplication; -@end - -//===----------------------------------------------------------------------===// -// Method name that has a null IdentifierInfo* for its first selector slot. -// This test just makes sure that we handle it. -//===----------------------------------------------------------------------===// -@interface TestNullIdentifier -@end - -@implementation TestNullIdentifier -+ (id):(int)x, ... { - return 0; -} -@end - diff --git a/clang/test/ARCMT/objcmt-instancetype-unnecessary-diff.m b/clang/test/ARCMT/objcmt-instancetype-unnecessary-diff.m deleted file mode 100644 index e250bb0956c05..0000000000000 --- a/clang/test/ARCMT/objcmt-instancetype-unnecessary-diff.m +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -objcmt-migrate-instancetype %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap -// RUN: FileCheck %s -input-file=%t.remap - -// Make sure we don't create an edit unnecessarily. -// CHECK-NOT: instancetype - -@class NSString; -@interface NSDictionary -+(instancetype) dictionaryWithURLEncodedString:(NSString *)urlEncodedString; -@end diff --git a/clang/test/ARCMT/objcmt-instancetype.m b/clang/test/ARCMT/objcmt-instancetype.m deleted file mode 100644 index 17dd5a46b1e78..0000000000000 --- a/clang/test/ARCMT/objcmt-instancetype.m +++ /dev/null @@ -1,111 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@implementation NSString : NSObject -+ (id)stringWithString:(NSString *)string { return 0; }; -- (instancetype)initWithString:(NSString *)aString { return 0; }; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -- (id)objectAtIndexedSubscript:(int)index; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; - -- (id)objectAtIndex:(unsigned long)index; -@end - -@implementation NSArray (NSArrayCreation) -+ (id)array { return 0; } -+ (id)arrayWithObject:(id)anObject { - return anObject; -} -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -+ (id)arrayWithObjects:(id)firstObj, ... { - return 0; } -+ arrayWithArray:(NSArray *)array { - return 0; -} - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -- (id)initWithObjects:(id)firstObj, ... { return 0; } -- (id)initWithArray:(NSArray *)array { return 0; } - -- (id)objectAtIndex:(unsigned long)index { return 0; } -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -- (void)setObject:(id)object atIndexedSubscript:(int)index; -@end - -@interface NSDictionary : NSObject -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -- (void)setObject:(id)object forKeyedSubscript:(id)key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -@implementation NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value { return 0; } -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) - -void foo(void) { - NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} - str = [[NSString alloc] initWithString:@"foo"]; // expected-warning {{redundant}} - NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} - NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} -} diff --git a/clang/test/ARCMT/objcmt-instancetype.m.result b/clang/test/ARCMT/objcmt-instancetype.m.result deleted file mode 100644 index 5203368aad644..0000000000000 --- a/clang/test/ARCMT/objcmt-instancetype.m.result +++ /dev/null @@ -1,111 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-instancetype -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSString : NSObject -+ (instancetype)stringWithString:(NSString *)string; -- (instancetype)initWithString:(NSString *)aString; -@end - -@implementation NSString : NSObject -+ (instancetype)stringWithString:(NSString *)string { return 0; }; -- (instancetype)initWithString:(NSString *)aString { return 0; }; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -- (id)objectAtIndexedSubscript:(int)index; -@end - -@interface NSArray (NSArrayCreation) -+ (instancetype)array; -+ (instancetype)arrayWithObject:(id)anObject; -+ (instancetype)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (instancetype)arrayWithObjects:(id)firstObj, ...; -+ (instancetype) arrayWithArray:(NSArray *)array; - -- (instancetype)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (instancetype)initWithObjects:(id)firstObj, ...; -- (instancetype)initWithArray:(NSArray *)array; - -- (id)objectAtIndex:(unsigned long)index; -@end - -@implementation NSArray (NSArrayCreation) -+ (instancetype)array { return 0; } -+ (instancetype)arrayWithObject:(id)anObject { - return anObject; -} -+ (instancetype)arrayWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -+ (instancetype)arrayWithObjects:(id)firstObj, ... { - return 0; } -+ (instancetype) arrayWithArray:(NSArray *)array { - return 0; -} - -- (instancetype)initWithObjects:(const id [])objects count:(unsigned long)cnt { return 0; } -- (instancetype)initWithObjects:(id)firstObj, ... { return 0; } -- (instancetype)initWithArray:(NSArray *)array { return 0; } - -- (id)objectAtIndex:(unsigned long)index { return 0; } -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -- (void)setObject:(id)object atIndexedSubscript:(int)index; -@end - -@interface NSDictionary : NSObject -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (instancetype)dictionary; -+ (instancetype)dictionaryWithObject:(id)object forKey:(id)key; -+ (instancetype)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (instancetype) dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (instancetype)dictionaryWithDictionary:(NSDictionary *)dict; -+ (instancetype)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (instancetype)initWithObjectsAndKeys:(id)firstObject, ...; -- (instancetype)initWithDictionary:(NSDictionary *)otherDictionary; -- (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -- (void)setObject:(id)object forKeyedSubscript:(id)key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -@implementation NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value { return 0; } -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) - -void foo(void) { - NSString *str = M([NSString stringWithString:@"foo"]); // expected-warning {{redundant}} - str = [[NSString alloc] initWithString:@"foo"]; // expected-warning {{redundant}} - NSArray *arr = [NSArray arrayWithArray:@[str]]; // expected-warning {{redundant}} - NSDictionary *dict = [NSDictionary dictionaryWithDictionary:@{str: arr}]; // expected-warning {{redundant}} -} diff --git a/clang/test/ARCMT/objcmt-invalid-code.mm b/clang/test/ARCMT/objcmt-invalid-code.mm deleted file mode 100644 index f780d3de57ed8..0000000000000 --- a/clang/test/ARCMT/objcmt-invalid-code.mm +++ /dev/null @@ -1,19 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s -verify -// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -// Make sure there is no crash. - -@interface NSObject @end -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(int x = undeclared) { // expected-error {{undeclared}} - NSNumber *n = [NSNumber numberWithInt:1]; -} diff --git a/clang/test/ARCMT/objcmt-invalid-code.mm.result b/clang/test/ARCMT/objcmt-invalid-code.mm.result deleted file mode 100644 index 52b2db00f6109..0000000000000 --- a/clang/test/ARCMT/objcmt-invalid-code.mm.result +++ /dev/null @@ -1,19 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s -verify -// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -// Make sure there is no crash. - -@interface NSObject @end -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(int x = undeclared) { // expected-error {{undeclared}} - NSNumber *n = @1; -} diff --git a/clang/test/ARCMT/objcmt-migrate-all.m b/clang/test/ARCMT/objcmt-migrate-all.m deleted file mode 100644 index 0aa66756b761c..0000000000000 --- a/clang/test/ARCMT/objcmt-migrate-all.m +++ /dev/null @@ -1,133 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-all -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -- (void*) ReturnsInnerPointer; -- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -- (CGImageRef)CGImage; -@end - -@interface NSData -- (void *)bytes; -- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))); -@end - -@interface NSMutableData -- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); -@end - -@interface JS -- (JSObjectRef)JSObject; -- (TTJSObjectRef)JSObject1; -- (JSObjectRef*)JSObject2; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; -- (void *) FOO NS_AVAILABLE; -@property (readonly) void * mitTrust NS_AVAILABLE; - -@property (readonly) void * mittiTrust; - -@property (readonly) SecTrustRef XserverTrust; - -- (SecTrustRef) FOO1 NS_AVAILABLE; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end - -@interface MustNotMigrateToInnerPointer -- (void*) nono; -- (void) setNono : (void*) val; -@end diff --git a/clang/test/ARCMT/objcmt-migrate-all.m.result b/clang/test/ARCMT/objcmt-migrate-all.m.result deleted file mode 100644 index e0972875e11b8..0000000000000 --- a/clang/test/ARCMT/objcmt-migrate-all.m.result +++ /dev/null @@ -1,132 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-all -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -@property (nonatomic, readonly) void *ReturnsInnerPointer; -@property (nonatomic, readonly) int *AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -@property (nonatomic, readonly) CGImageRef CGImage CF_RETURNS_NOT_RETAINED; -@end - -@interface NSData -@property (nonatomic, readonly) void *bytes; -@property (nonatomic, readonly) void **ptr_bytes __attribute__((availability(macosx,unavailable))); -@end - -@interface NSMutableData -@property (nonatomic, readonly) void *mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); -@end - -@interface JS -@property (nonatomic, readonly) JSObjectRef JSObject; -@property (nonatomic, readonly) TTJSObjectRef JSObject1; -@property (nonatomic, readonly) JSObjectRef *JSObject2; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; -@property (nonatomic, readonly) void *FOO NS_AVAILABLE; -@property (readonly) void * mitTrust NS_AVAILABLE; - -@property (readonly) void * mittiTrust; - -@property (readonly) SecTrustRef XserverTrust; - -@property (nonatomic, readonly) SecTrustRef FOO1 NS_AVAILABLE; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end - -@interface MustNotMigrateToInnerPointer -@property (nonatomic) void *nono; -@end diff --git a/clang/test/ARCMT/objcmt-ns-enum-crash.m b/clang/test/ARCMT/objcmt-ns-enum-crash.m deleted file mode 100644 index 7c9c708efaefb..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-enum-crash.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -typedef long NSInteger; - -typedef enum : NSInteger {five} ApplicableEnum; - -typedef unsigned long mytd; - -#define MY_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t -MY_ENUM(MyEnum, unsigned int, One); diff --git a/clang/test/ARCMT/objcmt-ns-enum-crash.m.result b/clang/test/ARCMT/objcmt-ns-enum-crash.m.result deleted file mode 100644 index 0a76e66ea2111..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-enum-crash.m.result +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -typedef long NSInteger; - -typedef NS_ENUM(NSInteger, ApplicableEnum) {five}; - -typedef unsigned long mytd; - -#define MY_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t -MY_ENUM(MyEnum, unsigned int, One); diff --git a/clang/test/ARCMT/objcmt-ns-macros.m b/clang/test/ARCMT/objcmt-ns-macros.m deleted file mode 100644 index 902e765bead3a..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-macros.m +++ /dev/null @@ -1,379 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long NSInteger; -typedef long long int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long NSUInteger; -typedef unsigned long long uint64_t; - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -#define DEPRECATED __attribute__((deprecated)) - -enum { - blah, - blarg -}; -typedef NSInteger wibble; - -enum { - UIViewAutoresizingNone = 0, - UIViewAutoresizingFlexibleLeftMargin, - UIViewAutoresizingFlexibleWidth, - UIViewAutoresizingFlexibleRightMargin, - UIViewAutoresizingFlexibleTopMargin, - UIViewAutoresizingFlexibleHeight, - UIViewAutoresizingFlexibleBottomMargin -}; -typedef NSUInteger UITableViewCellStyle; - -typedef enum { - UIViewAnimationTransitionNone, - UIViewAnimationTransitionFlipFromLeft, - UIViewAnimationTransitionFlipFromRight, - UIViewAnimationTransitionCurlUp, - UIViewAnimationTransitionCurlDown, -} UIViewAnimationTransition; - -typedef enum { - UIViewOne = 0, - UIViewTwo = 1 << 0, - UIViewThree = 1 << 1, - UIViewFour = 1 << 2, - UIViewFive = 1 << 3, - UIViewSix = 1 << 4, - UIViewSeven = 1 << 5 -} UITableView; - -enum { - UIOne = 0, - UITwo = 0x1, - UIthree = 0x8, - UIFour = 0x100 -}; -typedef NSInteger UI; - -typedef enum { - UIP2One = 0, - UIP2Two = 0x1, - UIP2three = 0x8, - UIP2Four = 0x100 -} UIPOWER2; - -enum { - UNOne, - UNTwo -}; - -// Should use NS_ENUM even though it is all power of 2. -enum { - UIKOne = 1, - UIKTwo = 2, -}; -typedef NSInteger UIK; - -typedef enum { - NSTickMarkBelow = 0, - NSTickMarkAbove = 1, - NSTickMarkLeft = NSTickMarkAbove, - NSTickMarkRight = NSTickMarkBelow -} NSTickMarkPosition; - -enum { - UIViewNone = 0x0, - UIViewMargin = 0x1, - UIViewWidth = 0x2, - UIViewRightMargin = 0x3, - UIViewBottomMargin = 0xbadbeef -}; -typedef NSInteger UITableStyle; - -enum { - UIView0 = 0, - UIView1 = 0XBADBEEF -}; -typedef NSInteger UIStyle; - -enum { - NSTIFFFileType, - NSBMPFileType, - NSGIFFileType, - NSJPEGFileType, - NSPNGFileType, - NSJPEG2000FileType -}; -typedef NSUInteger NSBitmapImageFileType; - -enum { - NSWarningAlertStyle = 0, - NSInformationalAlertStyle = 1, - NSCriticalAlertStyle = 2 -}; -typedef NSUInteger NSAlertStyle; - -enum { - D_NSTIFFFileType, - D_NSBMPFileType, - D_NSGIFFileType, - D_NSJPEGFileType, - D_NSPNGFileType, - D_NSJPEG2000FileType -}; -typedef NSUInteger D_NSBitmapImageFileType DEPRECATED; - -typedef enum { - D_NSTickMarkBelow = 0, - D_NSTickMarkAbove = 1 -} D_NSTickMarkPosition DEPRECATED; - - -#define NS_ENUM_AVAILABLE(X,Y) - -enum { - NSFStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 0), - NSFOpaqueMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 0), - NSFMallocMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 0), - NSFMachVirtualMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 0), - NSFWeakMemory NS_ENUM_AVAILABLE(10_8, 6_0) = (5UL << 0), - - NSFObjectPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 8), - NSFOpaquePersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 8), - NSFObjectPointerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 8), - NSFCStringPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 8), - NSFStructPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 8), - NSFIntegerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (5UL << 8), - NSFCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 16), -}; - -typedef NSUInteger NSFOptions; - -typedef enum { - UIP0One = 0, - UIP0Two = 1, - UIP0Three = 2, - UIP0Four = 10, - UIP0Last = 0x100 -} UIP; - -typedef enum { - UIPZero = 0x0, - UIPOne = 0x1, - UIPTwo = 0x2, - UIP10 = 0x10, - UIPHundred = 0x100 -} UIP_3; - -typedef enum { - UIP4Zero = 0x0, - UIP4One = 0x1, - UIP4Two = 0x2, - UIP410 = 0x10, - UIP4Hundred = 100 -} UIP4_3; - -typedef enum { - UIP5Zero = 0x0, - UIP5Two = 0x2, - UIP510 = 0x3, - UIP5Hundred = 0x4 -} UIP5_3; - -typedef enum { - UIP6Zero = 0x0, - UIP6One = 0x1, - UIP6Two = 0x2, - UIP610 = 10, - UIP6Hundred = 0x100 -} UIP6_3; - -typedef enum { - UIP7Zero = 0x0, - UIP7One = 1, - UIP7Two = 0x2, - UIP710 = 10, - UIP7Hundred = 100 -} UIP7_3; - - -typedef enum { - Random = 0, - Random1 = 2, - Random2 = 4, - Random3 = 0x12345, - Random4 = 0x3444444, - Random5 = 0xbadbeef, - Random6 -} UIP8_3; - -#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) -#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) - -enum { - NSModalResponseStop = (-1000), // Also used as the default response for sheets - NSModalResponseAbort = (-1001), - NSModalResponseContinue = (-1002), -} NS_ENUM_AVAILABLE_MAC(10.9); -typedef NSInteger NSModalResponse NS_AVAILABLE_MAC(10.9); - -typedef NSUInteger FarFarAwayOptions; - -typedef NSUInteger FarAwayOptions; -enum { - NSWorkspaceLaunchAndPrint = 0x00000002, - NSWorkspaceLaunchWithErrorPresentation = 0x00000040, - NSWorkspaceLaunchInhibitingBackgroundOnly = 0x00000080, - NSWorkspaceLaunchWithoutAddingToRecents = 0x00000100, - NSWorkspaceLaunchWithoutActivation = 0x00000200, - NSWorkspaceLaunchAsync = 0x00010000, - NSWorkspaceLaunchAllowingClassicStartup = 0x00020000, - NSWorkspaceLaunchPreferringClassic = 0x00040000, - NSWorkspaceLaunchNewInstance = 0x00080000, - NSWorkspaceLaunchAndHide = 0x00100000, - NSWorkspaceLaunchAndHideOthers = 0x00200000, - NSWorkspaceLaunchDefault = NSWorkspaceLaunchAsync | - NSWorkspaceLaunchAllowingClassicStartup -}; -typedef NSUInteger NSWorkspaceLaunchOptions; - -enum { - NSExcludeQuickDrawElementsIconCreationOption = 1 << 1, - NSExclude10_4ElementsIconCreationOption = 1 << 2 -}; -typedef NSUInteger NSExcludeOptions; - -enum { - NSExcludeQuickDrawElementsCreationOption = 1 << 1, - NSExclude10_4ElementsCreationOption = 1 << 2 -}; -typedef NSUInteger NSExcludeCreationOption; - -enum { - FarAway1 = 1 << 1, - FarAway2 = 1 << 2 -}; - -enum { - NSExcludeQuickDrawElementsIconOption = 1 << 1, - NSExclude10_4ElementsIconOption = 1 << 2 -}; -typedef NSUInteger NSExcludeIconOptions; - -@interface INTF { - NSExcludeIconOptions I1; - NSExcludeIconOptions I2; -} -@end - -enum { - FarFarAway1 = 1 << 1, - FarFarAway2 = 1 << 2 -}; - -typedef NS_OPTIONS(NSUInteger, NSWindowOcclusionState) { - NSWindowOcclusionStateVisible = 1UL << 1, -}; - -typedef NSUInteger NSWindowNumberListOptions; - -enum { - NSDirectSelection = 0, - NSSelectingNext, - NSSelectingPrevious -}; -typedef NSUInteger NSSelectionDirection; - -// standard window buttons -enum { - NSWindowCloseButton, - NSWindowMiniaturizeButton, - NSWindowZoomButton, - NSWindowToolbarButton, - NSWindowDocumentIconButton -}; - -typedef enum : NSUInteger { - ThingOne, - ThingTwo, - ThingThree, -} Thing; - -typedef enum { - one = 1 -} NumericEnum; - -typedef enum { - Two = 2 -}NumericEnum2; - -typedef enum { - Three = 3 -} -NumericEnum3; - -typedef enum { - Four = 4 -} - - NumericEnum4; - -enum -{ - UI8one = 1 -}; -typedef int8_t MyEnumeratedType; - - -enum { - UI16One = 0, - UI16Two = 0x1, - UI16three = 0x8, - UI16Four = 0x100 -}; -typedef int16_t UI16; - -enum { - UI32ViewAutoresizingNone = 0, - UI32ViewAutoresizingFlexibleLeftMargin, - UI32ViewAutoresizingFlexibleWidth, - UI32ViewAutoresizingFlexibleRightMargin, - UI32ViewAutoresizingFlexibleTopMargin, - UI32ViewAutoresizingFlexibleHeight, - UI32ViewAutoresizingFlexibleBottomMargin -}; -typedef uint32_t UI32TableViewCellStyle; - -enum -{ - UIU8one = 1 -}; -typedef uint8_t UI8Type; - -typedef enum : NSInteger {zero} MyEnum; - -typedef enum : NSUInteger {two} MyEnumNSUInteger; - -typedef enum : int {three, four} MyEnumint; - -typedef enum : unsigned long {five} MyEnumlonglong; - -typedef enum : unsigned long long { - ll1, - ll2= 0xff, - ll3, - ll4 -} MyEnumunsignedlonglong; - -typedef enum : int8_t {int8_one} MyOneEnum; - -typedef enum : int16_t { - int16_t_one, - int16_t_two } Myint16_tEnum; diff --git a/clang/test/ARCMT/objcmt-ns-macros.m.result b/clang/test/ARCMT/objcmt-ns-macros.m.result deleted file mode 100644 index d4c0870e8cdc3..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-macros.m.result +++ /dev/null @@ -1,355 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -typedef signed char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long NSInteger; -typedef long long int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long NSUInteger; -typedef unsigned long long uint64_t; - -#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type -#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type -#define DEPRECATED __attribute__((deprecated)) - -typedef NS_ENUM(NSInteger, wibble) { - blah, - blarg -}; - -typedef NS_ENUM(NSUInteger, UITableViewCellStyle) { - UIViewAutoresizingNone = 0, - UIViewAutoresizingFlexibleLeftMargin, - UIViewAutoresizingFlexibleWidth, - UIViewAutoresizingFlexibleRightMargin, - UIViewAutoresizingFlexibleTopMargin, - UIViewAutoresizingFlexibleHeight, - UIViewAutoresizingFlexibleBottomMargin -}; - -typedef NS_ENUM(unsigned int, UIViewAnimationTransition) { - UIViewAnimationTransitionNone, - UIViewAnimationTransitionFlipFromLeft, - UIViewAnimationTransitionFlipFromRight, - UIViewAnimationTransitionCurlUp, - UIViewAnimationTransitionCurlDown, -}; - -typedef NS_OPTIONS(unsigned int, UITableView) { - UIViewOne = 0, - UIViewTwo = 1 << 0, - UIViewThree = 1 << 1, - UIViewFour = 1 << 2, - UIViewFive = 1 << 3, - UIViewSix = 1 << 4, - UIViewSeven = 1 << 5 -}; - -typedef NS_OPTIONS(NSUInteger, UI) { - UIOne = 0, - UITwo = 0x1, - UIthree = 0x8, - UIFour = 0x100 -}; - -typedef NS_OPTIONS(unsigned int, UIPOWER2) { - UIP2One = 0, - UIP2Two = 0x1, - UIP2three = 0x8, - UIP2Four = 0x100 -}; - -enum { - UNOne, - UNTwo -}; - -// Should use NS_ENUM even though it is all power of 2. -typedef NS_ENUM(NSInteger, UIK) { - UIKOne = 1, - UIKTwo = 2, -}; - -typedef NS_ENUM(unsigned int, NSTickMarkPosition) { - NSTickMarkBelow = 0, - NSTickMarkAbove = 1, - NSTickMarkLeft = NSTickMarkAbove, - NSTickMarkRight = NSTickMarkBelow -}; - -typedef NS_OPTIONS(NSUInteger, UITableStyle) { - UIViewNone = 0x0, - UIViewMargin = 0x1, - UIViewWidth = 0x2, - UIViewRightMargin = 0x3, - UIViewBottomMargin = 0xbadbeef -}; - -typedef NS_OPTIONS(NSUInteger, UIStyle) { - UIView0 = 0, - UIView1 = 0XBADBEEF -}; - -typedef NS_ENUM(NSUInteger, NSBitmapImageFileType) { - NSTIFFFileType, - NSBMPFileType, - NSGIFFileType, - NSJPEGFileType, - NSPNGFileType, - NSJPEG2000FileType -}; - -typedef NS_ENUM(NSUInteger, NSAlertStyle) { - NSWarningAlertStyle = 0, - NSInformationalAlertStyle = 1, - NSCriticalAlertStyle = 2 -}; - -enum { - D_NSTIFFFileType, - D_NSBMPFileType, - D_NSGIFFileType, - D_NSJPEGFileType, - D_NSPNGFileType, - D_NSJPEG2000FileType -}; -typedef NSUInteger D_NSBitmapImageFileType DEPRECATED; - -typedef enum { - D_NSTickMarkBelow = 0, - D_NSTickMarkAbove = 1 -} D_NSTickMarkPosition DEPRECATED; - - -#define NS_ENUM_AVAILABLE(X,Y) - - -typedef NS_OPTIONS(NSUInteger, NSFOptions) { - NSFStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 0), - NSFOpaqueMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 0), - NSFMallocMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 0), - NSFMachVirtualMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 0), - NSFWeakMemory NS_ENUM_AVAILABLE(10_8, 6_0) = (5UL << 0), - - NSFObjectPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 8), - NSFOpaquePersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 8), - NSFObjectPointerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 8), - NSFCStringPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (3UL << 8), - NSFStructPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (4UL << 8), - NSFIntegerPersonality NS_ENUM_AVAILABLE(10_5, 6_0) = (5UL << 8), - NSFCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 16), -}; - -typedef NS_ENUM(unsigned int, UIP) { - UIP0One = 0, - UIP0Two = 1, - UIP0Three = 2, - UIP0Four = 10, - UIP0Last = 0x100 -}; - -typedef NS_OPTIONS(unsigned int, UIP_3) { - UIPZero = 0x0, - UIPOne = 0x1, - UIPTwo = 0x2, - UIP10 = 0x10, - UIPHundred = 0x100 -}; - -typedef NS_ENUM(unsigned int, UIP4_3) { - UIP4Zero = 0x0, - UIP4One = 0x1, - UIP4Two = 0x2, - UIP410 = 0x10, - UIP4Hundred = 100 -}; - -typedef NS_OPTIONS(unsigned int, UIP5_3) { - UIP5Zero = 0x0, - UIP5Two = 0x2, - UIP510 = 0x3, - UIP5Hundred = 0x4 -}; - -typedef NS_ENUM(unsigned int, UIP6_3) { - UIP6Zero = 0x0, - UIP6One = 0x1, - UIP6Two = 0x2, - UIP610 = 10, - UIP6Hundred = 0x100 -}; - -typedef NS_ENUM(unsigned int, UIP7_3) { - UIP7Zero = 0x0, - UIP7One = 1, - UIP7Two = 0x2, - UIP710 = 10, - UIP7Hundred = 100 -}; - - -typedef NS_ENUM(unsigned int, UIP8_3) { - Random = 0, - Random1 = 2, - Random2 = 4, - Random3 = 0x12345, - Random4 = 0x3444444, - Random5 = 0xbadbeef, - Random6 -}; - -#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) -#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) - -typedef NS_ENUM(NSInteger, NSModalResponse) { - NSModalResponseStop = (-1000), // Also used as the default response for sheets - NSModalResponseAbort = (-1001), - NSModalResponseContinue = (-1002), -} NS_ENUM_AVAILABLE_MAC(10.9); - -typedef NSUInteger FarFarAwayOptions; - -typedef NS_OPTIONS(NSUInteger, FarAwayOptions) { - FarAway1 = 1 << 1, - FarAway2 = 1 << 2 -}; -typedef NS_OPTIONS(NSUInteger, NSWorkspaceLaunchOptions) { - NSWorkspaceLaunchAndPrint = 0x00000002, - NSWorkspaceLaunchWithErrorPresentation = 0x00000040, - NSWorkspaceLaunchInhibitingBackgroundOnly = 0x00000080, - NSWorkspaceLaunchWithoutAddingToRecents = 0x00000100, - NSWorkspaceLaunchWithoutActivation = 0x00000200, - NSWorkspaceLaunchAsync = 0x00010000, - NSWorkspaceLaunchAllowingClassicStartup = 0x00020000, - NSWorkspaceLaunchPreferringClassic = 0x00040000, - NSWorkspaceLaunchNewInstance = 0x00080000, - NSWorkspaceLaunchAndHide = 0x00100000, - NSWorkspaceLaunchAndHideOthers = 0x00200000, - NSWorkspaceLaunchDefault = NSWorkspaceLaunchAsync | - NSWorkspaceLaunchAllowingClassicStartup -}; - -typedef NS_OPTIONS(NSUInteger, NSExcludeOptions) { - NSExcludeQuickDrawElementsIconCreationOption = 1 << 1, - NSExclude10_4ElementsIconCreationOption = 1 << 2 -}; - -typedef NS_OPTIONS(NSUInteger, NSExcludeCreationOption) { - NSExcludeQuickDrawElementsCreationOption = 1 << 1, - NSExclude10_4ElementsCreationOption = 1 << 2 -}; - - -typedef NS_OPTIONS(NSUInteger, NSExcludeIconOptions) { - NSExcludeQuickDrawElementsIconOption = 1 << 1, - NSExclude10_4ElementsIconOption = 1 << 2 -}; - -@interface INTF { - NSExcludeIconOptions I1; - NSExcludeIconOptions I2; -} -@end - -enum { - FarFarAway1 = 1 << 1, - FarFarAway2 = 1 << 2 -}; - -typedef NS_OPTIONS(NSUInteger, NSWindowOcclusionState) { - NSWindowOcclusionStateVisible = 1UL << 1, -}; - -typedef NS_ENUM(NSUInteger, NSWindowNumberListOptions) { - NSWindowCloseButton, - NSWindowMiniaturizeButton, - NSWindowZoomButton, - NSWindowToolbarButton, - NSWindowDocumentIconButton -}; - -typedef NS_ENUM(NSUInteger, NSSelectionDirection) { - NSDirectSelection = 0, - NSSelectingNext, - NSSelectingPrevious -}; - -// standard window buttons - -typedef NS_ENUM(NSUInteger, Thing) { - ThingOne, - ThingTwo, - ThingThree, -}; - -typedef NS_ENUM(unsigned int, NumericEnum) { - one = 1 -}; - -typedef NS_ENUM(unsigned int, NumericEnum2) { - Two = 2 -}; - -typedef NS_ENUM(unsigned int, NumericEnum3) { - Three = 3 -}; - -typedef NS_OPTIONS(unsigned int, NumericEnum4) { - Four = 4 -}; - -typedef NS_ENUM(int8_t, MyEnumeratedType) -{ - UI8one = 1 -}; - - -typedef NS_OPTIONS(uint16_t, UI16) { - UI16One = 0, - UI16Two = 0x1, - UI16three = 0x8, - UI16Four = 0x100 -}; - -typedef NS_ENUM(uint32_t, UI32TableViewCellStyle) { - UI32ViewAutoresizingNone = 0, - UI32ViewAutoresizingFlexibleLeftMargin, - UI32ViewAutoresizingFlexibleWidth, - UI32ViewAutoresizingFlexibleRightMargin, - UI32ViewAutoresizingFlexibleTopMargin, - UI32ViewAutoresizingFlexibleHeight, - UI32ViewAutoresizingFlexibleBottomMargin -}; - -typedef NS_ENUM(uint8_t, UI8Type) -{ - UIU8one = 1 -}; - -typedef NS_ENUM(NSInteger, MyEnum) {zero}; - -typedef NS_ENUM(NSUInteger, MyEnumNSUInteger) {two}; - -typedef NS_ENUM(int, MyEnumint) {three, four}; - -typedef NS_ENUM(unsigned long, MyEnumlonglong) {five}; - -typedef NS_ENUM(unsigned long long, MyEnumunsignedlonglong) { - ll1, - ll2= 0xff, - ll3, - ll4 -}; - -typedef NS_ENUM(int8_t, MyOneEnum) {int8_one}; - -typedef NS_ENUM(int16_t, Myint16_tEnum) { - int16_t_one, - int16_t_two }; diff --git a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m b/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m deleted file mode 100644 index 55a116c8ca5da..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m +++ /dev/null @@ -1,233 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-ns-nonatomic-iosonly -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -#if TARGET_OS_IPHONE - #define NS_NONATOMIC_IOSONLY nonatomic -#else - #define NS_NONATOMIC_IOSONLY atomic -#endif - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -- (void) setWeakProp : (NSString *__weak)Val; -- (NSString *__weak) WeakProp; - -- (NSString *) StrongProp; -- (void) setStrongProp : (NSString *)Val; - -- (NSString *) UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -- (NSString *) UnavailProp1 __attribute__((unavailable)); -- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); - -- (NSString *) UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -- (NSDictionary*) undoAction; -- (void) setUndoAction: (NSDictionary*)Arg; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -- (void)setNames1:(NSArray *)names; -- (void)setNames4:(__strong NSArray *)names; -- (void)setNames3:(__strong NSArray *)names; -- (void)setNames2:(NSArray *)names; -- (NSArray *) names2; -- (NSArray *)names3; -- (__strong NSArray *)names4; -- (NSArray *) names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; -- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -- (BOOL)isIgnoringInteractionEvents; - -- (NSString *)getStringValue; -- (BOOL)getCounterValue; -- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; -- (NSDictionary *)getns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - - -@interface NSInvocation(CAT) -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -- (NSURL *)appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; -- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -- (id)OkToInfer NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -- (id)method1 ALIGNED NS_AVAILABLE; -- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; -- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; -- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; -- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; -- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; -- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; -@end diff --git a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result b/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result deleted file mode 100644 index 512deb12583a9..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result +++ /dev/null @@ -1,206 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-ns-nonatomic-iosonly -objcmt-migrate-readonly-property -objcmt-atomic-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -#if TARGET_OS_IPHONE - #define NS_NONATOMIC_IOSONLY nonatomic -#else - #define NS_NONATOMIC_IOSONLY atomic -#endif - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -@property (NS_NONATOMIC_IOSONLY, weak) NSString *WeakProp; - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *StrongProp; - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp1 __attribute__((unavailable)); - -@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -@property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *undoAction; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names2; -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names3; -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names4; -@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -@property (NS_NONATOMIC_IOSONLY, assign) id target; - -@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; - -@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; - - -@property (NS_NONATOMIC_IOSONLY, strong) id MYtarget; - -@property (NS_NONATOMIC_IOSONLY, strong) id targetX; - -@property (NS_NONATOMIC_IOSONLY) int value; - -@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (NS_NONATOMIC_IOSONLY, readonly) int Length; -@property (NS_NONATOMIC_IOSONLY, readonly, strong) id object; -+ (double) D; -@property (NS_NONATOMIC_IOSONLY, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -@property (NS_NONATOMIC_IOSONLY, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; - -@property (NS_NONATOMIC_IOSONLY, getter=getStringValue, strong) NSString *stringValue; -@property (NS_NONATOMIC_IOSONLY, getter=getCounterValue, readonly) BOOL counterValue; -@property (NS_NONATOMIC_IOSONLY, getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; -@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; -@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; -@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; -@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; -@end - - -@interface NSInvocation(CAT) -@property (NS_NONATOMIC_IOSONLY, assign) id target; - -@property (NS_NONATOMIC_IOSONLY, assign) id dataSource; - -@property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY; - - -@property (NS_NONATOMIC_IOSONLY, strong) id MYtarget; - -@property (NS_NONATOMIC_IOSONLY, strong) id targetX; - -@property (NS_NONATOMIC_IOSONLY) int value; - -@property (NS_NONATOMIC_IOSONLY, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (NS_NONATOMIC_IOSONLY, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (NS_NONATOMIC_IOSONLY, readonly) int Length; -@property (NS_NONATOMIC_IOSONLY, readonly, strong) id object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (NS_NONATOMIC_IOSONLY, getter=getM, readonly) BOOL m; -@property (NS_NONATOMIC_IOSONLY, getter=getMA, readonly) BOOL MA; -@property (NS_NONATOMIC_IOSONLY, getter=getALL, readonly) BOOL ALL; -@property (NS_NONATOMIC_IOSONLY, getter=getMANY, readonly) BOOL MANY; -@property (NS_NONATOMIC_IOSONLY, getter=getSome, readonly) BOOL some; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLX NS_AVAILABLE; - -// Do not infer a property. -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -@property (NS_NONATOMIC_IOSONLY, readonly, strong) id OkToInfer NS_AVAILABLE; - -// Do not infer a property. -@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -@property (NS_NONATOMIC_IOSONLY, strong) id method1 ALIGNED NS_AVAILABLE; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -@property (NS_NONATOMIC_IOSONLY, getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -@property (NS_NONATOMIC_IOSONLY, readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); -@property (NS_NONATOMIC_IOSONLY, copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); -@property (NS_NONATOMIC_IOSONLY, readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); -@property (NS_NONATOMIC_IOSONLY) id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); -@end diff --git a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m b/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m deleted file mode 100644 index 853d16dc78942..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m +++ /dev/null @@ -1,128 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-returns-innerpointer-property -objcmt-migrate-annotation -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -- (void*) ReturnsInnerPointer; -- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -- (CGImageRef)CGImage; -@end - -@interface NSData -- (void *)bytes; -- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))); -@end - -@interface NSMutableData -- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)); -@end - -@interface JS -- (JSObjectRef)JSObject; -- (TTJSObjectRef)JSObject1; -- (JSObjectRef*)JSObject2; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef serverTrust NS_AVAILABLE; -- (void *) FOO NS_AVAILABLE; -@property (readonly) void * mitTrust NS_AVAILABLE; - -@property (readonly) void * mittiTrust; - -@property (readonly) SecTrustRef XserverTrust; - -- (SecTrustRef) FOO1 NS_AVAILABLE; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end diff --git a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result b/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result deleted file mode 100644 index c89c91eedce35..0000000000000 --- a/clang/test/ARCMT/objcmt-ns-returns-inner-pointer.m.result +++ /dev/null @@ -1,128 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-returns-innerpointer-property -objcmt-migrate-annotation -objcmt-migrate-readwrite-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#ifndef NS_RETURNS_INNER_POINTER // defined in iOS 6 for sure -#define NS_RETURNS_INNER_POINTER __attribute__((objc_returns_inner_pointer)) -#endif - -#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin") - -#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end") - -#if __has_feature(attribute_ns_returns_retained) -#define NS_RETURNS_RETAINED __attribute__((ns_returns_retained)) -#endif -#if __has_feature(attribute_cf_returns_retained) -#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained)) -#endif -#if __has_feature(attribute_ns_returns_not_retained) -#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) -#endif -#if __has_feature(attribute_cf_returns_not_retained) -#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained)) -#endif -#if __has_feature(attribute_ns_consumes_self) -#define NS_CONSUMES_SELF __attribute__((ns_consumes_self)) -#endif -#if __has_feature(attribute_ns_consumed) -#define NS_CONSUMED __attribute__((ns_consumed)) -#endif -#if __has_feature(attribute_cf_consumed) -#define CF_CONSUMED __attribute__((cf_consumed)) -#endif -#if __has_attribute(ns_returns_autoreleased) -#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased)) -#endif - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) - -CF_IMPLICIT_BRIDGING_ENABLED - -typedef unsigned long CFTypeID; -typedef unsigned long CFOptionFlags; -typedef unsigned long CFHashCode; - -typedef signed long CFIndex; /*AnyObj*/ -typedef const struct __CFArray * CFArrayRef; -typedef struct { - CFIndex location; - CFIndex length; -} CFRange; - -typedef void (*CFArrayApplierFunction)(const void *value, void *context); - -typedef enum CFComparisonResult : CFIndex CFComparisonResult; enum CFComparisonResult : CFIndex { - kCFCompareLessThan = -1L, - kCFCompareEqualTo = 0, - kCFCompareGreaterThan = 1 -}; - - -typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context); - -typedef struct __CFArray * CFMutableArrayRef; - -typedef const struct __CFAttributedString *CFAttributedStringRef; -typedef struct __CFAttributedString *CFMutableAttributedStringRef; - -typedef const struct __CFAllocator * CFAllocatorRef; - -typedef const struct __CFString * CFStringRef; -typedef struct __CFString * CFMutableStringRef; - -typedef const struct __CFDictionary * CFDictionaryRef; -typedef struct __CFDictionary * CFMutableDictionaryRef; - -typedef struct CGImage *CGImageRef; - -typedef struct OpaqueJSValue* JSObjectRef; - -typedef JSObjectRef TTJSObjectRef; -typedef unsigned int NSUInteger; - -CF_IMPLICIT_BRIDGING_DISABLED - -@interface I -- (void*) ReturnsInnerPointer NS_RETURNS_INNER_POINTER; -- (int*) AlreadyReturnsInnerPointer NS_RETURNS_INNER_POINTER; -@end - -@interface UIImage -- (CGImageRef)CGImage CF_RETURNS_NOT_RETAINED; -@end - -@interface NSData -- (void *)bytes NS_RETURNS_INNER_POINTER; -- (void **) ptr_bytes __attribute__((availability(macosx,unavailable))) NS_RETURNS_INNER_POINTER; -@end - -@interface NSMutableData -- (void *)mutableBytes __attribute__((deprecated)) __attribute__((unavailable)) NS_RETURNS_INNER_POINTER; -@end - -@interface JS -- (JSObjectRef)JSObject; -- (TTJSObjectRef)JSObject1; -- (JSObjectRef*)JSObject2 NS_RETURNS_INNER_POINTER; -@end - -typedef void *SecTrustRef; - -@interface NSURLProtectionSpace -@property (readonly) SecTrustRef NS_RETURNS_INNER_POINTER serverTrust NS_AVAILABLE; -- (void *) FOO NS_AVAILABLE NS_RETURNS_INNER_POINTER; -@property (readonly) void * NS_RETURNS_INNER_POINTER mitTrust NS_AVAILABLE; - -@property (readonly) void * NS_RETURNS_INNER_POINTER mittiTrust; - -@property (readonly) SecTrustRef NS_RETURNS_INNER_POINTER XserverTrust; - -- (SecTrustRef) FOO1 NS_AVAILABLE NS_RETURNS_INNER_POINTER; - -+ (const NSURLProtectionSpace *)ProtectionSpace; - -// pointer personality functions -@property NSUInteger (*hashFunction)(const void *item, NSUInteger (*size)(const void *item)); -@end diff --git a/clang/test/ARCMT/objcmt-numeric-literals.m b/clang/test/ARCMT/objcmt-numeric-literals.m deleted file mode 100644 index 7f33dc27997e1..0000000000000 --- a/clang/test/ARCMT/objcmt-numeric-literals.m +++ /dev/null @@ -1,502 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -#define VAL_INT 2 -#define VAL_UINT 2U -#define VAL_CHAR 'a' - -void foo() { - [NSNumber numberWithChar:'a']; - [NSNumber numberWithChar:L'a']; - [NSNumber numberWithChar:2]; - [NSNumber numberWithChar:2U]; - [NSNumber numberWithChar:2u]; - [NSNumber numberWithChar:2L]; - [NSNumber numberWithChar:2l]; - [NSNumber numberWithChar:2LL]; - [NSNumber numberWithChar:2ll]; - [NSNumber numberWithChar:2ul]; - [NSNumber numberWithChar:2lu]; - [NSNumber numberWithChar:2ull]; - [NSNumber numberWithChar:2llu]; - [NSNumber numberWithChar:2.0]; - [NSNumber numberWithChar:2.0f]; - [NSNumber numberWithChar:2.0F]; - [NSNumber numberWithChar:2.0l]; - [NSNumber numberWithChar:2.0L]; - [NSNumber numberWithChar:0x2f]; - [NSNumber numberWithChar:04]; - [NSNumber numberWithChar:0]; - [NSNumber numberWithChar:0.0]; - [NSNumber numberWithChar:YES]; - [NSNumber numberWithChar:NO]; - [NSNumber numberWithChar:true]; - [NSNumber numberWithChar:false]; - [NSNumber numberWithChar:VAL_INT]; - [NSNumber numberWithChar:VAL_UINT]; - [NSNumber numberWithChar:VAL_CHAR]; - - [NSNumber numberWithUnsignedChar:'a']; - [NSNumber numberWithUnsignedChar:L'a']; - [NSNumber numberWithUnsignedChar:2]; - [NSNumber numberWithUnsignedChar:2U]; - [NSNumber numberWithUnsignedChar:2u]; - [NSNumber numberWithUnsignedChar:2L]; - [NSNumber numberWithUnsignedChar:2l]; - [NSNumber numberWithUnsignedChar:2LL]; - [NSNumber numberWithUnsignedChar:2ll]; - [NSNumber numberWithUnsignedChar:2ul]; - [NSNumber numberWithUnsignedChar:2lu]; - [NSNumber numberWithUnsignedChar:2ull]; - [NSNumber numberWithUnsignedChar:2llu]; - [NSNumber numberWithUnsignedChar:2.0]; - [NSNumber numberWithUnsignedChar:2.0f]; - [NSNumber numberWithUnsignedChar:2.0F]; - [NSNumber numberWithUnsignedChar:2.0l]; - [NSNumber numberWithUnsignedChar:2.0L]; - [NSNumber numberWithUnsignedChar:0x2f]; - [NSNumber numberWithUnsignedChar:04]; - [NSNumber numberWithUnsignedChar:0]; - [NSNumber numberWithUnsignedChar:0.0]; - [NSNumber numberWithUnsignedChar:YES]; - [NSNumber numberWithUnsignedChar:NO]; - [NSNumber numberWithUnsignedChar:true]; - [NSNumber numberWithUnsignedChar:false]; - [NSNumber numberWithUnsignedChar:VAL_INT]; - [NSNumber numberWithUnsignedChar:VAL_UINT]; - [NSNumber numberWithUnsignedChar:VAL_CHAR]; - - [NSNumber numberWithShort:'a']; - [NSNumber numberWithShort:L'a']; - [NSNumber numberWithShort:2]; - [NSNumber numberWithShort:2U]; - [NSNumber numberWithShort:2u]; - [NSNumber numberWithShort:2L]; - [NSNumber numberWithShort:2l]; - [NSNumber numberWithShort:2LL]; - [NSNumber numberWithShort:2ll]; - [NSNumber numberWithShort:2ul]; - [NSNumber numberWithShort:2lu]; - [NSNumber numberWithShort:2ull]; - [NSNumber numberWithShort:2llu]; - [NSNumber numberWithShort:2.0]; - [NSNumber numberWithShort:2.0f]; - [NSNumber numberWithShort:2.0F]; - [NSNumber numberWithShort:2.0l]; - [NSNumber numberWithShort:2.0L]; - [NSNumber numberWithShort:0x2f]; - [NSNumber numberWithShort:04]; - [NSNumber numberWithShort:0]; - [NSNumber numberWithShort:0.0]; - [NSNumber numberWithShort:YES]; - [NSNumber numberWithShort:NO]; - [NSNumber numberWithShort:true]; - [NSNumber numberWithShort:false]; - [NSNumber numberWithShort:VAL_INT]; - [NSNumber numberWithShort:VAL_UINT]; - - [NSNumber numberWithUnsignedShort:'a']; - [NSNumber numberWithUnsignedShort:L'a']; - [NSNumber numberWithUnsignedShort:2]; - [NSNumber numberWithUnsignedShort:2U]; - [NSNumber numberWithUnsignedShort:2u]; - [NSNumber numberWithUnsignedShort:2L]; - [NSNumber numberWithUnsignedShort:2l]; - [NSNumber numberWithUnsignedShort:2LL]; - [NSNumber numberWithUnsignedShort:2ll]; - [NSNumber numberWithUnsignedShort:2ul]; - [NSNumber numberWithUnsignedShort:2lu]; - [NSNumber numberWithUnsignedShort:2ull]; - [NSNumber numberWithUnsignedShort:2llu]; - [NSNumber numberWithUnsignedShort:2.0]; - [NSNumber numberWithUnsignedShort:2.0f]; - [NSNumber numberWithUnsignedShort:2.0F]; - [NSNumber numberWithUnsignedShort:2.0l]; - [NSNumber numberWithUnsignedShort:2.0L]; - [NSNumber numberWithUnsignedShort:0x2f]; - [NSNumber numberWithUnsignedShort:04]; - [NSNumber numberWithUnsignedShort:0]; - [NSNumber numberWithUnsignedShort:0.0]; - [NSNumber numberWithUnsignedShort:YES]; - [NSNumber numberWithUnsignedShort:NO]; - [NSNumber numberWithUnsignedShort:true]; - [NSNumber numberWithUnsignedShort:false]; - [NSNumber numberWithUnsignedShort:VAL_INT]; - [NSNumber numberWithUnsignedShort:VAL_UINT]; - - [NSNumber numberWithInt:'a']; - [NSNumber numberWithInt:L'a']; - [NSNumber numberWithInt:2]; - [NSNumber numberWithInt:2U]; - [NSNumber numberWithInt:2u]; - [NSNumber numberWithInt:2L]; - [NSNumber numberWithInt:2l]; - [NSNumber numberWithInt:2LL]; - [NSNumber numberWithInt:2ll]; - [NSNumber numberWithInt:2ul]; - [NSNumber numberWithInt:2lu]; - [NSNumber numberWithInt:2ull]; - [NSNumber numberWithInt:2llu]; - [NSNumber numberWithInt:2.0]; - [NSNumber numberWithInt:2.0f]; - [NSNumber numberWithInt:2.0F]; - [NSNumber numberWithInt:2.0l]; - [NSNumber numberWithInt:2.0L]; - [NSNumber numberWithInt:0x2f]; - [NSNumber numberWithInt:04]; - [NSNumber numberWithInt:0]; - [NSNumber numberWithInt:0.0]; - [NSNumber numberWithInt:YES]; - [NSNumber numberWithInt:NO]; - [NSNumber numberWithInt:true]; - [NSNumber numberWithInt:false]; - [NSNumber numberWithInt:VAL_INT]; - [NSNumber numberWithInt:VAL_UINT]; - - (void)[[NSNumber alloc] initWithInt:2]; - (void)[[NSNumber alloc] initWithInt:2U]; - - [NSNumber numberWithInt:+2]; - [NSNumber numberWithInt:-2]; - - [NSNumber numberWithUnsignedInt:'a']; - [NSNumber numberWithUnsignedInt:L'a']; - [NSNumber numberWithUnsignedInt:2]; - [NSNumber numberWithUnsignedInt:2U]; - [NSNumber numberWithUnsignedInt:2u]; - [NSNumber numberWithUnsignedInt:2L]; - [NSNumber numberWithUnsignedInt:2l]; - [NSNumber numberWithUnsignedInt:2LL]; - [NSNumber numberWithUnsignedInt:2ll]; - [NSNumber numberWithUnsignedInt:2ul]; - [NSNumber numberWithUnsignedInt:2lu]; - [NSNumber numberWithUnsignedInt:2ull]; - [NSNumber numberWithUnsignedInt:2llu]; - [NSNumber numberWithUnsignedInt:2.0]; - [NSNumber numberWithUnsignedInt:2.0f]; - [NSNumber numberWithUnsignedInt:2.0F]; - [NSNumber numberWithUnsignedInt:2.0l]; - [NSNumber numberWithUnsignedInt:2.0L]; - [NSNumber numberWithUnsignedInt:0x2f]; - [NSNumber numberWithUnsignedInt:04]; - [NSNumber numberWithUnsignedInt:0]; - [NSNumber numberWithUnsignedInt:0.0]; - [NSNumber numberWithUnsignedInt:YES]; - [NSNumber numberWithUnsignedInt:NO]; - [NSNumber numberWithUnsignedInt:true]; - [NSNumber numberWithUnsignedInt:false]; - [NSNumber numberWithUnsignedInt:VAL_INT]; - [NSNumber numberWithUnsignedInt:VAL_UINT]; - - [NSNumber numberWithLong:'a']; - [NSNumber numberWithLong:L'a']; - [NSNumber numberWithLong:2]; - [NSNumber numberWithLong:2U]; - [NSNumber numberWithLong:2u]; - [NSNumber numberWithLong:2L]; - [NSNumber numberWithLong:2l]; - [NSNumber numberWithLong:2LL]; - [NSNumber numberWithLong:2ll]; - [NSNumber numberWithLong:2ul]; - [NSNumber numberWithLong:2lu]; - [NSNumber numberWithLong:2ull]; - [NSNumber numberWithLong:2llu]; - [NSNumber numberWithLong:2.0]; - [NSNumber numberWithLong:2.0f]; - [NSNumber numberWithLong:2.0F]; - [NSNumber numberWithLong:2.0l]; - [NSNumber numberWithLong:2.0L]; - [NSNumber numberWithLong:0x2f]; - [NSNumber numberWithLong:04]; - [NSNumber numberWithLong:0]; - [NSNumber numberWithLong:0.0]; - [NSNumber numberWithLong:YES]; - [NSNumber numberWithLong:NO]; - [NSNumber numberWithLong:true]; - [NSNumber numberWithLong:false]; - [NSNumber numberWithLong:VAL_INT]; - [NSNumber numberWithLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLong:'a']; - [NSNumber numberWithUnsignedLong:L'a']; - [NSNumber numberWithUnsignedLong:2]; - [NSNumber numberWithUnsignedLong:2U]; - [NSNumber numberWithUnsignedLong:2u]; - [NSNumber numberWithUnsignedLong:2L]; - [NSNumber numberWithUnsignedLong:2l]; - [NSNumber numberWithUnsignedLong:2LL]; - [NSNumber numberWithUnsignedLong:2ll]; - [NSNumber numberWithUnsignedLong:2ul]; - [NSNumber numberWithUnsignedLong:2lu]; - [NSNumber numberWithUnsignedLong:2ull]; - [NSNumber numberWithUnsignedLong:2llu]; - [NSNumber numberWithUnsignedLong:2.0]; - [NSNumber numberWithUnsignedLong:2.0f]; - [NSNumber numberWithUnsignedLong:2.0F]; - [NSNumber numberWithUnsignedLong:2.0l]; - [NSNumber numberWithUnsignedLong:2.0L]; - [NSNumber numberWithUnsignedLong:0x2f]; - [NSNumber numberWithUnsignedLong:04]; - [NSNumber numberWithUnsignedLong:0]; - [NSNumber numberWithUnsignedLong:0.0]; - [NSNumber numberWithUnsignedLong:YES]; - [NSNumber numberWithUnsignedLong:NO]; - [NSNumber numberWithUnsignedLong:true]; - [NSNumber numberWithUnsignedLong:false]; - [NSNumber numberWithUnsignedLong:VAL_INT]; - [NSNumber numberWithUnsignedLong:VAL_UINT]; - - [NSNumber numberWithLongLong:'a']; - [NSNumber numberWithLongLong:L'a']; - [NSNumber numberWithLongLong:2]; - [NSNumber numberWithLongLong:2U]; - [NSNumber numberWithLongLong:2u]; - [NSNumber numberWithLongLong:2L]; - [NSNumber numberWithLongLong:2l]; - [NSNumber numberWithLongLong:2LL]; - [NSNumber numberWithLongLong:2ll]; - [NSNumber numberWithLongLong:2ul]; - [NSNumber numberWithLongLong:2lu]; - [NSNumber numberWithLongLong:2ull]; - [NSNumber numberWithLongLong:2llu]; - [NSNumber numberWithLongLong:2.0]; - [NSNumber numberWithLongLong:2.0f]; - [NSNumber numberWithLongLong:2.0F]; - [NSNumber numberWithLongLong:2.0l]; - [NSNumber numberWithLongLong:2.0L]; - [NSNumber numberWithLongLong:0x2f]; - [NSNumber numberWithLongLong:04]; - [NSNumber numberWithLongLong:0]; - [NSNumber numberWithLongLong:0.0]; - [NSNumber numberWithLongLong:YES]; - [NSNumber numberWithLongLong:NO]; - [NSNumber numberWithLongLong:true]; - [NSNumber numberWithLongLong:false]; - [NSNumber numberWithLongLong:VAL_INT]; - [NSNumber numberWithLongLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLongLong:'a']; - [NSNumber numberWithUnsignedLongLong:L'a']; - [NSNumber numberWithUnsignedLongLong:2]; - [NSNumber numberWithUnsignedLongLong:2U]; - [NSNumber numberWithUnsignedLongLong:2u]; - [NSNumber numberWithUnsignedLongLong:2L]; - [NSNumber numberWithUnsignedLongLong:2l]; - [NSNumber numberWithUnsignedLongLong:2LL]; - [NSNumber numberWithUnsignedLongLong:2ll]; - [NSNumber numberWithUnsignedLongLong:2ul]; - [NSNumber numberWithUnsignedLongLong:2lu]; - [NSNumber numberWithUnsignedLongLong:2ull]; - [NSNumber numberWithUnsignedLongLong:2llu]; - [NSNumber numberWithUnsignedLongLong:2.0]; - [NSNumber numberWithUnsignedLongLong:2.0f]; - [NSNumber numberWithUnsignedLongLong:2.0F]; - [NSNumber numberWithUnsignedLongLong:2.0l]; - [NSNumber numberWithUnsignedLongLong:2.0L]; - [NSNumber numberWithUnsignedLongLong:0x2f]; - [NSNumber numberWithUnsignedLongLong:04]; - [NSNumber numberWithUnsignedLongLong:0]; - [NSNumber numberWithUnsignedLongLong:0.0]; - [NSNumber numberWithUnsignedLongLong:YES]; - [NSNumber numberWithUnsignedLongLong:NO]; - [NSNumber numberWithUnsignedLongLong:true]; - [NSNumber numberWithUnsignedLongLong:false]; - [NSNumber numberWithUnsignedLongLong:VAL_INT]; - [NSNumber numberWithUnsignedLongLong:VAL_UINT]; - - [NSNumber numberWithFloat:'a']; - [NSNumber numberWithFloat:L'a']; - [NSNumber numberWithFloat:2]; - [NSNumber numberWithFloat:2U]; - [NSNumber numberWithFloat:2u]; - [NSNumber numberWithFloat:2L]; - [NSNumber numberWithFloat:2l]; - [NSNumber numberWithFloat:2LL]; - [NSNumber numberWithFloat:2ll]; - [NSNumber numberWithFloat:2ul]; - [NSNumber numberWithFloat:2lu]; - [NSNumber numberWithFloat:2ull]; - [NSNumber numberWithFloat:2llu]; - [NSNumber numberWithFloat:2.0]; - [NSNumber numberWithFloat:2.0f]; - [NSNumber numberWithFloat:2.0F]; - [NSNumber numberWithFloat:2.0l]; - [NSNumber numberWithFloat:2.0L]; - [NSNumber numberWithFloat:0x2f]; - [NSNumber numberWithFloat:04]; - [NSNumber numberWithFloat:0]; - [NSNumber numberWithFloat:0.0]; - [NSNumber numberWithFloat:YES]; - [NSNumber numberWithFloat:NO]; - [NSNumber numberWithFloat:true]; - [NSNumber numberWithFloat:false]; - [NSNumber numberWithFloat:VAL_INT]; - [NSNumber numberWithFloat:VAL_UINT]; - - [NSNumber numberWithDouble:'a']; - [NSNumber numberWithDouble:L'a']; - [NSNumber numberWithDouble:2]; - [NSNumber numberWithDouble:2U]; - [NSNumber numberWithDouble:2u]; - [NSNumber numberWithDouble:2L]; - [NSNumber numberWithDouble:2l]; - [NSNumber numberWithDouble:2LL]; - [NSNumber numberWithDouble:2ll]; - [NSNumber numberWithDouble:2ul]; - [NSNumber numberWithDouble:2lu]; - [NSNumber numberWithDouble:2ull]; - [NSNumber numberWithDouble:2llu]; - [NSNumber numberWithDouble:2.0]; - [NSNumber numberWithDouble:2.0f]; - [NSNumber numberWithDouble:2.0F]; - [NSNumber numberWithDouble:2.0l]; - [NSNumber numberWithDouble:2.0L]; - [NSNumber numberWithDouble:0x2f]; - [NSNumber numberWithDouble:04]; - [NSNumber numberWithDouble:0]; - [NSNumber numberWithDouble:0.0]; - [NSNumber numberWithDouble:YES]; - [NSNumber numberWithDouble:NO]; - [NSNumber numberWithDouble:true]; - [NSNumber numberWithDouble:false]; - [NSNumber numberWithDouble:VAL_INT]; - [NSNumber numberWithDouble:VAL_UINT]; - - [NSNumber numberWithBool:'a']; - [NSNumber numberWithBool:L'a']; - [NSNumber numberWithBool:2]; - [NSNumber numberWithBool:2U]; - [NSNumber numberWithBool:2u]; - [NSNumber numberWithBool:2L]; - [NSNumber numberWithBool:2l]; - [NSNumber numberWithBool:2LL]; - [NSNumber numberWithBool:2ll]; - [NSNumber numberWithBool:2ul]; - [NSNumber numberWithBool:2lu]; - [NSNumber numberWithBool:2ull]; - [NSNumber numberWithBool:2llu]; - [NSNumber numberWithBool:2.0]; - [NSNumber numberWithBool:2.0f]; - [NSNumber numberWithBool:2.0F]; - [NSNumber numberWithBool:2.0l]; - [NSNumber numberWithBool:2.0L]; - [NSNumber numberWithBool:0x2f]; - [NSNumber numberWithBool:04]; - [NSNumber numberWithBool:0]; - [NSNumber numberWithBool:0.0]; - [NSNumber numberWithBool:YES]; - [NSNumber numberWithBool:NO]; - [NSNumber numberWithBool:true]; - [NSNumber numberWithBool:false]; - [NSNumber numberWithBool:VAL_INT]; - [NSNumber numberWithBool:VAL_UINT]; - - [NSNumber numberWithInteger:'a']; - [NSNumber numberWithInteger:L'a']; - [NSNumber numberWithInteger:2]; - [NSNumber numberWithInteger:2U]; - [NSNumber numberWithInteger:2u]; - [NSNumber numberWithInteger:2L]; - [NSNumber numberWithInteger:2l]; - [NSNumber numberWithInteger:2LL]; - [NSNumber numberWithInteger:2ll]; - [NSNumber numberWithInteger:2ul]; - [NSNumber numberWithInteger:2lu]; - [NSNumber numberWithInteger:2ull]; - [NSNumber numberWithInteger:2llu]; - [NSNumber numberWithInteger:2.0]; - [NSNumber numberWithInteger:2.0f]; - [NSNumber numberWithInteger:2.0F]; - [NSNumber numberWithInteger:2.0l]; - [NSNumber numberWithInteger:2.0L]; - [NSNumber numberWithInteger:0x2f]; - [NSNumber numberWithInteger:04]; - [NSNumber numberWithInteger:0]; - [NSNumber numberWithInteger:0.0]; - [NSNumber numberWithInteger:YES]; - [NSNumber numberWithInteger:NO]; - [NSNumber numberWithInteger:true]; - [NSNumber numberWithInteger:false]; - [NSNumber numberWithInteger:VAL_INT]; - [NSNumber numberWithInteger:VAL_UINT]; - - [NSNumber numberWithUnsignedInteger:'a']; - [NSNumber numberWithUnsignedInteger:L'a']; - [NSNumber numberWithUnsignedInteger:2]; - [NSNumber numberWithUnsignedInteger:2U]; - [NSNumber numberWithUnsignedInteger:2u]; - [NSNumber numberWithUnsignedInteger:2L]; - [NSNumber numberWithUnsignedInteger:2l]; - [NSNumber numberWithUnsignedInteger:2LL]; - [NSNumber numberWithUnsignedInteger:2ll]; - [NSNumber numberWithUnsignedInteger:2ul]; - [NSNumber numberWithUnsignedInteger:2lu]; - [NSNumber numberWithUnsignedInteger:2ull]; - [NSNumber numberWithUnsignedInteger:2llu]; - [NSNumber numberWithUnsignedInteger:2.0]; - [NSNumber numberWithUnsignedInteger:2.0f]; - [NSNumber numberWithUnsignedInteger:2.0F]; - [NSNumber numberWithUnsignedInteger:2.0l]; - [NSNumber numberWithUnsignedInteger:2.0L]; - [NSNumber numberWithUnsignedInteger:0x2f]; - [NSNumber numberWithUnsignedInteger:04]; - [NSNumber numberWithUnsignedInteger:0]; - [NSNumber numberWithUnsignedInteger:0.0]; - [NSNumber numberWithUnsignedInteger:YES]; - [NSNumber numberWithUnsignedInteger:NO]; - [NSNumber numberWithUnsignedInteger:true]; - [NSNumber numberWithUnsignedInteger:false]; - [NSNumber numberWithUnsignedInteger:VAL_INT]; - [NSNumber numberWithUnsignedInteger:VAL_UINT]; -} diff --git a/clang/test/ARCMT/objcmt-numeric-literals.m.result b/clang/test/ARCMT/objcmt-numeric-literals.m.result deleted file mode 100644 index bb7b515566d09..0000000000000 --- a/clang/test/ARCMT/objcmt-numeric-literals.m.result +++ /dev/null @@ -1,502 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s.result - -#define YES __objc_yes -#define NO __objc_no - -typedef long NSInteger; -typedef unsigned long NSUInteger; -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -- (id)initWithChar:(char)value; -- (id)initWithUnsignedChar:(unsigned char)value; -- (id)initWithShort:(short)value; -- (id)initWithUnsignedShort:(unsigned short)value; -- (id)initWithInt:(int)value; -- (id)initWithUnsignedInt:(unsigned int)value; -- (id)initWithLong:(long)value; -- (id)initWithUnsignedLong:(unsigned long)value; -- (id)initWithLongLong:(long long)value; -- (id)initWithUnsignedLongLong:(unsigned long long)value; -- (id)initWithFloat:(float)value; -- (id)initWithDouble:(double)value; -- (id)initWithBool:(BOOL)value; -- (id)initWithInteger:(NSInteger)value; -- (id)initWithUnsignedInteger:(NSUInteger)value; - -+ (NSNumber *)numberWithChar:(char)value; -+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value; -+ (NSNumber *)numberWithShort:(short)value; -+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value; -+ (NSNumber *)numberWithInt:(int)value; -+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value; -+ (NSNumber *)numberWithLong:(long)value; -+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value; -+ (NSNumber *)numberWithLongLong:(long long)value; -+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value; -+ (NSNumber *)numberWithFloat:(float)value; -+ (NSNumber *)numberWithDouble:(double)value; -+ (NSNumber *)numberWithBool:(BOOL)value; -+ (NSNumber *)numberWithInteger:(NSInteger)value; -+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; -@end - -#define VAL_INT 2 -#define VAL_UINT 2U -#define VAL_CHAR 'a' - -void foo() { - @'a'; - [NSNumber numberWithChar:L'a']; - [NSNumber numberWithChar:2]; - [NSNumber numberWithChar:2U]; - [NSNumber numberWithChar:2u]; - [NSNumber numberWithChar:2L]; - [NSNumber numberWithChar:2l]; - [NSNumber numberWithChar:2LL]; - [NSNumber numberWithChar:2ll]; - [NSNumber numberWithChar:2ul]; - [NSNumber numberWithChar:2lu]; - [NSNumber numberWithChar:2ull]; - [NSNumber numberWithChar:2llu]; - [NSNumber numberWithChar:2.0]; - [NSNumber numberWithChar:2.0f]; - [NSNumber numberWithChar:2.0F]; - [NSNumber numberWithChar:2.0l]; - [NSNumber numberWithChar:2.0L]; - [NSNumber numberWithChar:0x2f]; - [NSNumber numberWithChar:04]; - [NSNumber numberWithChar:0]; - [NSNumber numberWithChar:0.0]; - [NSNumber numberWithChar:YES]; - [NSNumber numberWithChar:NO]; - [NSNumber numberWithChar:true]; - [NSNumber numberWithChar:false]; - [NSNumber numberWithChar:VAL_INT]; - [NSNumber numberWithChar:VAL_UINT]; - @VAL_CHAR; - - [NSNumber numberWithUnsignedChar:'a']; - [NSNumber numberWithUnsignedChar:L'a']; - [NSNumber numberWithUnsignedChar:2]; - [NSNumber numberWithUnsignedChar:2U]; - [NSNumber numberWithUnsignedChar:2u]; - [NSNumber numberWithUnsignedChar:2L]; - [NSNumber numberWithUnsignedChar:2l]; - [NSNumber numberWithUnsignedChar:2LL]; - [NSNumber numberWithUnsignedChar:2ll]; - [NSNumber numberWithUnsignedChar:2ul]; - [NSNumber numberWithUnsignedChar:2lu]; - [NSNumber numberWithUnsignedChar:2ull]; - [NSNumber numberWithUnsignedChar:2llu]; - [NSNumber numberWithUnsignedChar:2.0]; - [NSNumber numberWithUnsignedChar:2.0f]; - [NSNumber numberWithUnsignedChar:2.0F]; - [NSNumber numberWithUnsignedChar:2.0l]; - [NSNumber numberWithUnsignedChar:2.0L]; - [NSNumber numberWithUnsignedChar:0x2f]; - [NSNumber numberWithUnsignedChar:04]; - [NSNumber numberWithUnsignedChar:0]; - [NSNumber numberWithUnsignedChar:0.0]; - [NSNumber numberWithUnsignedChar:YES]; - [NSNumber numberWithUnsignedChar:NO]; - [NSNumber numberWithUnsignedChar:true]; - [NSNumber numberWithUnsignedChar:false]; - [NSNumber numberWithUnsignedChar:VAL_INT]; - [NSNumber numberWithUnsignedChar:VAL_UINT]; - [NSNumber numberWithUnsignedChar:VAL_CHAR]; - - [NSNumber numberWithShort:'a']; - [NSNumber numberWithShort:L'a']; - [NSNumber numberWithShort:2]; - [NSNumber numberWithShort:2U]; - [NSNumber numberWithShort:2u]; - [NSNumber numberWithShort:2L]; - [NSNumber numberWithShort:2l]; - [NSNumber numberWithShort:2LL]; - [NSNumber numberWithShort:2ll]; - [NSNumber numberWithShort:2ul]; - [NSNumber numberWithShort:2lu]; - [NSNumber numberWithShort:2ull]; - [NSNumber numberWithShort:2llu]; - [NSNumber numberWithShort:2.0]; - [NSNumber numberWithShort:2.0f]; - [NSNumber numberWithShort:2.0F]; - [NSNumber numberWithShort:2.0l]; - [NSNumber numberWithShort:2.0L]; - [NSNumber numberWithShort:0x2f]; - [NSNumber numberWithShort:04]; - [NSNumber numberWithShort:0]; - [NSNumber numberWithShort:0.0]; - [NSNumber numberWithShort:YES]; - [NSNumber numberWithShort:NO]; - [NSNumber numberWithShort:true]; - [NSNumber numberWithShort:false]; - [NSNumber numberWithShort:VAL_INT]; - [NSNumber numberWithShort:VAL_UINT]; - - [NSNumber numberWithUnsignedShort:'a']; - [NSNumber numberWithUnsignedShort:L'a']; - [NSNumber numberWithUnsignedShort:2]; - [NSNumber numberWithUnsignedShort:2U]; - [NSNumber numberWithUnsignedShort:2u]; - [NSNumber numberWithUnsignedShort:2L]; - [NSNumber numberWithUnsignedShort:2l]; - [NSNumber numberWithUnsignedShort:2LL]; - [NSNumber numberWithUnsignedShort:2ll]; - [NSNumber numberWithUnsignedShort:2ul]; - [NSNumber numberWithUnsignedShort:2lu]; - [NSNumber numberWithUnsignedShort:2ull]; - [NSNumber numberWithUnsignedShort:2llu]; - [NSNumber numberWithUnsignedShort:2.0]; - [NSNumber numberWithUnsignedShort:2.0f]; - [NSNumber numberWithUnsignedShort:2.0F]; - [NSNumber numberWithUnsignedShort:2.0l]; - [NSNumber numberWithUnsignedShort:2.0L]; - [NSNumber numberWithUnsignedShort:0x2f]; - [NSNumber numberWithUnsignedShort:04]; - [NSNumber numberWithUnsignedShort:0]; - [NSNumber numberWithUnsignedShort:0.0]; - [NSNumber numberWithUnsignedShort:YES]; - [NSNumber numberWithUnsignedShort:NO]; - [NSNumber numberWithUnsignedShort:true]; - [NSNumber numberWithUnsignedShort:false]; - [NSNumber numberWithUnsignedShort:VAL_INT]; - [NSNumber numberWithUnsignedShort:VAL_UINT]; - - [NSNumber numberWithInt:'a']; - [NSNumber numberWithInt:L'a']; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - @2; - [NSNumber numberWithInt:2.0]; - [NSNumber numberWithInt:2.0f]; - [NSNumber numberWithInt:2.0F]; - [NSNumber numberWithInt:2.0l]; - [NSNumber numberWithInt:2.0L]; - @0x2f; - @04; - @0; - [NSNumber numberWithInt:0.0]; - [NSNumber numberWithInt:YES]; - [NSNumber numberWithInt:NO]; - [NSNumber numberWithInt:true]; - [NSNumber numberWithInt:false]; - @VAL_INT; - [NSNumber numberWithInt:VAL_UINT]; - - (void)[[NSNumber alloc] initWithInt:2]; - (void)[[NSNumber alloc] initWithInt:2U]; - - @+2; - @-2; - - [NSNumber numberWithUnsignedInt:'a']; - [NSNumber numberWithUnsignedInt:L'a']; - @2U; - @2U; - @2u; - @2U; - @2u; - @2U; - @2u; - @2u; - @2u; - @2u; - @2u; - [NSNumber numberWithUnsignedInt:2.0]; - [NSNumber numberWithUnsignedInt:2.0f]; - [NSNumber numberWithUnsignedInt:2.0F]; - [NSNumber numberWithUnsignedInt:2.0l]; - [NSNumber numberWithUnsignedInt:2.0L]; - @0x2fU; - @04U; - @0U; - [NSNumber numberWithUnsignedInt:0.0]; - [NSNumber numberWithUnsignedInt:YES]; - [NSNumber numberWithUnsignedInt:NO]; - [NSNumber numberWithUnsignedInt:true]; - [NSNumber numberWithUnsignedInt:false]; - [NSNumber numberWithUnsignedInt:VAL_INT]; - @VAL_UINT; - - [NSNumber numberWithLong:'a']; - [NSNumber numberWithLong:L'a']; - @2L; - @2L; - @2l; - @2L; - @2l; - @2L; - @2l; - @2l; - @2l; - @2l; - @2l; - [NSNumber numberWithLong:2.0]; - [NSNumber numberWithLong:2.0f]; - [NSNumber numberWithLong:2.0F]; - [NSNumber numberWithLong:2.0l]; - [NSNumber numberWithLong:2.0L]; - @0x2fL; - @04L; - @0L; - [NSNumber numberWithLong:0.0]; - [NSNumber numberWithLong:YES]; - [NSNumber numberWithLong:NO]; - [NSNumber numberWithLong:true]; - [NSNumber numberWithLong:false]; - [NSNumber numberWithLong:VAL_INT]; - [NSNumber numberWithLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLong:'a']; - [NSNumber numberWithUnsignedLong:L'a']; - @2UL; - @2UL; - @2ul; - @2UL; - @2ul; - @2UL; - @2ul; - @2ul; - @2lu; - @2ul; - @2ul; - [NSNumber numberWithUnsignedLong:2.0]; - [NSNumber numberWithUnsignedLong:2.0f]; - [NSNumber numberWithUnsignedLong:2.0F]; - [NSNumber numberWithUnsignedLong:2.0l]; - [NSNumber numberWithUnsignedLong:2.0L]; - @0x2fUL; - @04UL; - @0UL; - [NSNumber numberWithUnsignedLong:0.0]; - [NSNumber numberWithUnsignedLong:YES]; - [NSNumber numberWithUnsignedLong:NO]; - [NSNumber numberWithUnsignedLong:true]; - [NSNumber numberWithUnsignedLong:false]; - [NSNumber numberWithUnsignedLong:VAL_INT]; - [NSNumber numberWithUnsignedLong:VAL_UINT]; - - [NSNumber numberWithLongLong:'a']; - [NSNumber numberWithLongLong:L'a']; - @2LL; - @2LL; - @2ll; - @2LL; - @2ll; - @2LL; - @2ll; - @2ll; - @2ll; - @2ll; - @2ll; - [NSNumber numberWithLongLong:2.0]; - [NSNumber numberWithLongLong:2.0f]; - [NSNumber numberWithLongLong:2.0F]; - [NSNumber numberWithLongLong:2.0l]; - [NSNumber numberWithLongLong:2.0L]; - @0x2fLL; - @04LL; - @0LL; - [NSNumber numberWithLongLong:0.0]; - [NSNumber numberWithLongLong:YES]; - [NSNumber numberWithLongLong:NO]; - [NSNumber numberWithLongLong:true]; - [NSNumber numberWithLongLong:false]; - [NSNumber numberWithLongLong:VAL_INT]; - [NSNumber numberWithLongLong:VAL_UINT]; - - [NSNumber numberWithUnsignedLongLong:'a']; - [NSNumber numberWithUnsignedLongLong:L'a']; - @2ULL; - @2ULL; - @2ull; - @2ULL; - @2ull; - @2ULL; - @2ull; - @2ull; - @2ull; - @2ull; - @2llu; - [NSNumber numberWithUnsignedLongLong:2.0]; - [NSNumber numberWithUnsignedLongLong:2.0f]; - [NSNumber numberWithUnsignedLongLong:2.0F]; - [NSNumber numberWithUnsignedLongLong:2.0l]; - [NSNumber numberWithUnsignedLongLong:2.0L]; - @0x2fULL; - @04ULL; - @0ULL; - [NSNumber numberWithUnsignedLongLong:0.0]; - [NSNumber numberWithUnsignedLongLong:YES]; - [NSNumber numberWithUnsignedLongLong:NO]; - [NSNumber numberWithUnsignedLongLong:true]; - [NSNumber numberWithUnsignedLongLong:false]; - [NSNumber numberWithUnsignedLongLong:VAL_INT]; - [NSNumber numberWithUnsignedLongLong:VAL_UINT]; - - [NSNumber numberWithFloat:'a']; - [NSNumber numberWithFloat:L'a']; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0f; - @2.0F; - @2.0f; - @2.0f; - [NSNumber numberWithFloat:0x2f]; - [NSNumber numberWithFloat:04]; - @0.0f; - @0.0f; - [NSNumber numberWithFloat:YES]; - [NSNumber numberWithFloat:NO]; - [NSNumber numberWithFloat:true]; - [NSNumber numberWithFloat:false]; - [NSNumber numberWithFloat:VAL_INT]; - [NSNumber numberWithFloat:VAL_UINT]; - - [NSNumber numberWithDouble:'a']; - [NSNumber numberWithDouble:L'a']; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - @2.0; - [NSNumber numberWithDouble:0x2f]; - [NSNumber numberWithDouble:04]; - @0.0; - @0.0; - [NSNumber numberWithDouble:YES]; - [NSNumber numberWithDouble:NO]; - [NSNumber numberWithDouble:true]; - [NSNumber numberWithDouble:false]; - [NSNumber numberWithDouble:VAL_INT]; - [NSNumber numberWithDouble:VAL_UINT]; - - [NSNumber numberWithBool:'a']; - [NSNumber numberWithBool:L'a']; - [NSNumber numberWithBool:2]; - [NSNumber numberWithBool:2U]; - [NSNumber numberWithBool:2u]; - [NSNumber numberWithBool:2L]; - [NSNumber numberWithBool:2l]; - [NSNumber numberWithBool:2LL]; - [NSNumber numberWithBool:2ll]; - [NSNumber numberWithBool:2ul]; - [NSNumber numberWithBool:2lu]; - [NSNumber numberWithBool:2ull]; - [NSNumber numberWithBool:2llu]; - [NSNumber numberWithBool:2.0]; - [NSNumber numberWithBool:2.0f]; - [NSNumber numberWithBool:2.0F]; - [NSNumber numberWithBool:2.0l]; - [NSNumber numberWithBool:2.0L]; - [NSNumber numberWithBool:0x2f]; - [NSNumber numberWithBool:04]; - [NSNumber numberWithBool:0]; - [NSNumber numberWithBool:0.0]; - @YES; - @NO; - @true; - @false; - [NSNumber numberWithBool:VAL_INT]; - [NSNumber numberWithBool:VAL_UINT]; - - [NSNumber numberWithInteger:'a']; - [NSNumber numberWithInteger:L'a']; - @2; - @2; - @2; - @2L; - @2l; - @2; - @2; - @2; - @2; - @2; - @2; - [NSNumber numberWithInteger:2.0]; - [NSNumber numberWithInteger:2.0f]; - [NSNumber numberWithInteger:2.0F]; - [NSNumber numberWithInteger:2.0l]; - [NSNumber numberWithInteger:2.0L]; - @0x2f; - @04; - @0; - [NSNumber numberWithInteger:0.0]; - [NSNumber numberWithInteger:YES]; - [NSNumber numberWithInteger:NO]; - [NSNumber numberWithInteger:true]; - [NSNumber numberWithInteger:false]; - @VAL_INT; - [NSNumber numberWithInteger:VAL_UINT]; - - [NSNumber numberWithUnsignedInteger:'a']; - [NSNumber numberWithUnsignedInteger:L'a']; - @2U; - @2U; - @2u; - @2U; - @2u; - @2U; - @2u; - @2ul; - @2lu; - @2u; - @2u; - [NSNumber numberWithUnsignedInteger:2.0]; - [NSNumber numberWithUnsignedInteger:2.0f]; - [NSNumber numberWithUnsignedInteger:2.0F]; - [NSNumber numberWithUnsignedInteger:2.0l]; - [NSNumber numberWithUnsignedInteger:2.0L]; - @0x2fU; - @04U; - @0U; - [NSNumber numberWithUnsignedInteger:0.0]; - [NSNumber numberWithUnsignedInteger:YES]; - [NSNumber numberWithUnsignedInteger:NO]; - [NSNumber numberWithUnsignedInteger:true]; - [NSNumber numberWithUnsignedInteger:false]; - [NSNumber numberWithUnsignedInteger:VAL_INT]; - @VAL_UINT; -} diff --git a/clang/test/ARCMT/objcmt-property-availability.m b/clang/test/ARCMT/objcmt-property-availability.m deleted file mode 100644 index 37ba74f3346fb..0000000000000 --- a/clang/test/ARCMT/objcmt-property-availability.m +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - - -#define __NSi_7_0 introduced=7.0 -#define __NSi_6_0 introduced=6.0 - -#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,__NSi_##_ios))) -#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,__NSi_##_mac))) -#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable))) - -#define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios) -#define NS_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac) -#define NS_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios) - -#define UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) - -@interface MKMapItem -- (MKMapItem *)source NS_AVAILABLE(10_9, 6_0); -- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0); - -- (void)setDest:(MKMapItem *)source NS_AVAILABLE(10_9, 6_0); -- (MKMapItem *)dest NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)final; -- (void)setFinal:(MKMapItem *)source; - -- (MKMapItem *)total NS_AVAILABLE(10_9, 6_0); -- (void)setTotal:(MKMapItem *)source; - -- (MKMapItem *)comp NS_AVAILABLE(10_9, 6_0); -- (void)setComp:(MKMapItem *)source UNAVAILABLE; - -- (MKMapItem *)tally UNAVAILABLE NS_AVAILABLE(10_9, 6_0); -- (void)setTally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)itally NS_AVAILABLE(10_9, 6_0); -- (void)setItally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)normal UNAVAILABLE; -- (void)setNormal:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); -@end - diff --git a/clang/test/ARCMT/objcmt-property-availability.m.result b/clang/test/ARCMT/objcmt-property-availability.m.result deleted file mode 100644 index 3a212ac894c4a..0000000000000 --- a/clang/test/ARCMT/objcmt-property-availability.m.result +++ /dev/null @@ -1,42 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - - -#define __NSi_7_0 introduced=7.0 -#define __NSi_6_0 introduced=6.0 - -#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,__NSi_##_ios))) -#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,__NSi_##_mac))) -#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable))) - -#define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios) -#define NS_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac) -#define NS_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios) - -#define UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode"))) - -@interface MKMapItem -@property (nonatomic, strong) MKMapItem *source NS_AVAILABLE(10_9, 6_0); -- (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0); - -@property (nonatomic, strong) MKMapItem *dest NS_AVAILABLE(10_9, 6_0); - -@property (nonatomic, strong) MKMapItem *final; - -@property (nonatomic, strong) MKMapItem *total NS_AVAILABLE(10_9, 6_0); -- (void)setTotal:(MKMapItem *)source; - -- (MKMapItem *)comp NS_AVAILABLE(10_9, 6_0); -- (void)setComp:(MKMapItem *)source UNAVAILABLE; - -@property (nonatomic, strong) MKMapItem *tally UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)itally NS_AVAILABLE(10_9, 6_0); -- (void)setItally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); - -- (MKMapItem *)normal UNAVAILABLE; -- (void)setNormal:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0); -@end - diff --git a/clang/test/ARCMT/objcmt-property-dot-syntax.m b/clang/test/ARCMT/objcmt-property-dot-syntax.m deleted file mode 100644 index ec75b5140e18d..0000000000000 --- a/clang/test/ARCMT/objcmt-property-dot-syntax.m +++ /dev/null @@ -1,117 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-property-dot-syntax -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@class NSString; - -@protocol NSObject -@property (readonly, copy) NSString *description; -@end - -@interface NSObject @end - -@interface P : NSObject -{ - P* obj; - int i1, i2, i3; -} -@property int count; -@property (copy) P* PropertyReturnsPObj; -- (P*) MethodReturnsPObj; -@end - -P* fun(void); - -@implementation P -- (int) Meth : (P*)array { - [obj setCount : 100]; - - [(P*)0 setCount : [array count]]; - - [[obj PropertyReturnsPObj] setCount : [array count]]; - - [obj setCount : (i1+i2*i3 - 100)]; - - return [obj count] - - [(P*)0 count] + [array count] + - [fun() count] - - [[obj PropertyReturnsPObj] count] + - [self->obj count]; -} - -- (P*) MethodReturnsPObj { return 0; } - -- (NSString *)description { return [super description]; } -@end - -@interface Sub : P -@end - -@implementation Sub -- (int) Meth : (P*)array { - [super setCount : 100]; - - [super setCount : [array count]]; - - [[super PropertyReturnsPObj] setCount : [array count]]; - - [super setCount : (i1+i2*i3 - 100)]; - - return [super count] - - [(P*)0 count] + [array count] + - [fun() count] - - [[super PropertyReturnsPObj] count] + - [self->obj count]; -} -@end - - -@interface Rdar19038838 -@property id newItem; // should be marked objc_method_family(none), but isn't. -@end - -id testRdar19038838(Rdar19038838 *obj) { - return [obj newItem]; -} - -@interface rdar19381786 : NSObject -{ - rdar19381786* obj; -} -@property int count; -@end - -@protocol PR -@property int count; -@end - -@implementation rdar19381786 --(void)test:(id)some : (id)qsome : (SEL)selsome -{ - [obj setCount : 100]; - [some setCount : [some count]]; - [qsome setCount : [qsome count]]; -} -@end - -int NSOnState; -int ArrNSOnState[4]; -@interface rdar19140114 : NSObject -{ - rdar19140114* menuItem; -} -@property int state; -@end - -@implementation rdar19140114 -- (void) Meth { - [menuItem setState:NSOnState]; - [menuItem setState :NSOnState]; - [menuItem setState :ArrNSOnState[NSOnState]]; - [menuItem setState : NSOnState]; - [menuItem setState: NSOnState]; - [menuItem setState: NSOnState]; - [menuItem setState : NSOnState]; -} -@end diff --git a/clang/test/ARCMT/objcmt-property-dot-syntax.m.result b/clang/test/ARCMT/objcmt-property-dot-syntax.m.result deleted file mode 100644 index 5153b0e658f6a..0000000000000 --- a/clang/test/ARCMT/objcmt-property-dot-syntax.m.result +++ /dev/null @@ -1,117 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-property-dot-syntax -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@class NSString; - -@protocol NSObject -@property (readonly, copy) NSString *description; -@end - -@interface NSObject @end - -@interface P : NSObject -{ - P* obj; - int i1, i2, i3; -} -@property int count; -@property (copy) P* PropertyReturnsPObj; -- (P*) MethodReturnsPObj; -@end - -P* fun(void); - -@implementation P -- (int) Meth : (P*)array { - obj.count = 100; - - ((P*)0).count = array.count; - - obj.PropertyReturnsPObj.count = array.count; - - obj.count = (i1+i2*i3 - 100); - - return obj.count - - ((P*)0).count + array.count + - fun().count - - obj.PropertyReturnsPObj.count + - self->obj.count; -} - -- (P*) MethodReturnsPObj { return 0; } - -- (NSString *)description { return super.description; } -@end - -@interface Sub : P -@end - -@implementation Sub -- (int) Meth : (P*)array { - super.count = 100; - - super.count = array.count; - - super.PropertyReturnsPObj.count = array.count; - - super.count = (i1+i2*i3 - 100); - - return super.count - - ((P*)0).count + array.count + - fun().count - - super.PropertyReturnsPObj.count + - self->obj.count; -} -@end - - -@interface Rdar19038838 -@property id newItem; // should be marked objc_method_family(none), but isn't. -@end - -id testRdar19038838(Rdar19038838 *obj) { - return obj.newItem; -} - -@interface rdar19381786 : NSObject -{ - rdar19381786* obj; -} -@property int count; -@end - -@protocol PR -@property int count; -@end - -@implementation rdar19381786 --(void)test:(id)some : (id)qsome : (SEL)selsome -{ - obj.count = 100; - [some setCount : [some count]]; - qsome.count = qsome.count; -} -@end - -int NSOnState; -int ArrNSOnState[4]; -@interface rdar19140114 : NSObject -{ - rdar19140114* menuItem; -} -@property int state; -@end - -@implementation rdar19140114 -- (void) Meth { - menuItem.state = NSOnState; - menuItem.state = NSOnState; - menuItem.state = ArrNSOnState[NSOnState]; - menuItem.state = NSOnState; - menuItem.state = NSOnState; - menuItem.state = NSOnState; - menuItem.state = NSOnState; -} -@end diff --git a/clang/test/ARCMT/objcmt-property.m b/clang/test/ARCMT/objcmt-property.m deleted file mode 100644 index f2b722e66d969..0000000000000 --- a/clang/test/ARCMT/objcmt-property.m +++ /dev/null @@ -1,243 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -- (void) setWeakProp : (NSString *__weak)Val; -- (NSString *__weak) WeakProp; - -- (NSString *) StrongProp; -- (void) setStrongProp : (NSString *)Val; - -- (NSString *) UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -- (NSString *) UnavailProp1 __attribute__((unavailable)); -- (void) setUnavailProp1 : (NSString *)Val __attribute__((unavailable)); - -- (NSString *) UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -- (NSDictionary*) undoAction; -- (void) setUndoAction: (NSDictionary*)Arg; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -- (void)setNames1:(NSArray *)names; -- (void)setNames4:(__strong NSArray *)names; -- (void)setNames3:(__strong NSArray *)names; -- (void)setNames2:(NSArray *)names; -- (NSArray *) names2; -- (NSArray *)names3; -- (__strong NSArray *)names4; -- (NSArray *) names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)delegate; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; -- (void *)JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -- (BOOL)isIgnoringInteractionEvents; - -- (NSString *)getStringValue; -- (BOOL)getCounterValue; -- (void)setStringValue:(NSString *)stringValue AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER; -- (NSDictionary *)getns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - - -@interface NSInvocation(CAT) -- (id)target; -- (void)setTarget:(id)target; - -- (id) dataSource; - -- (id)xxxdelegateYYY; -- (void)setXxxdelegateYYY:(id)delegate; - -- (void)setDataSource:(id)source; - -- (id)MYtarget; -- (void)setMYtarget: (id)target; - -- (id)targetX; -- (void)setTargetX: (id)t; - -- (int)value; -- (void)setValue: (int)val; - --(BOOL) isContinuous; --(void) setContinuous:(BOOL)value; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -- (int) Length; -- (id) object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -- (BOOL) getM; -- (BOOL) getMA; -- (BOOL) getALL; -- (BOOL) getMANY; -- (BOOL) getSome; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -- (NSURL *)appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -- (NSURL *)appStoreReceiptURLX NS_AVAILABLE; -- (void) setAppStoreReceiptURLX : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -- (id)OkToInfer NS_AVAILABLE; - -// Do not infer a property. -- (NSURL *)appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -- (id)method1 ALIGNED NS_AVAILABLE; -- (void) setMethod1 : (id) object NS_AVAILABLE ALIGNED; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -- (BOOL)isClass; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -- (id (^)(id, NSArray *, NSMutableDictionary *)) expressionBlock; -- (id (^)(id, NSArray *, NSMutableDictionary *)) MyBlock; -- (void) setMyBlock : (id (^)(id, NSArray *, NSMutableDictionary *)) bl; -- (id (*)(id, NSArray *, NSMutableDictionary *)) expressionFuncptr; -- (id (*)(id, NSArray *, NSMutableDictionary *)) MyFuncptr; -- (void) setMyFuncptr : (id (*)(id, NSArray *, NSMutableDictionary *)) bl; -@end - -@interface rdar15231241 -@property (nonatomic, readonly) double Ddelegate; -@property (nonatomic, readonly) float Fdelegate; -@property (nonatomic, readonly) int Idelegate; -@property (nonatomic, readonly) BOOL Bdelegate; -@end - -@protocol NSObject @end -@protocol MyProtocol -- (id)readonlyProperty; -- (id)readWriteProperty; -- (void)setReadWriteProperty:(id)readWriteProperty; -@end diff --git a/clang/test/ARCMT/objcmt-property.m.result b/clang/test/ARCMT/objcmt-property.m.result deleted file mode 100644 index 610f027cee5c1..0000000000000 --- a/clang/test/ARCMT/objcmt-property.m.result +++ /dev/null @@ -1,215 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fblocks -objcmt-migrate-readwrite-property -objcmt-migrate-readonly-property -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -#define WEBKIT_OBJC_METHOD_ANNOTATION(ANNOTATION) ANNOTATION -#define WEAK_IMPORT_ATTRIBUTE __attribute__((objc_arc_weak_reference_unavailable)) -#define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER -#define DEPRECATED __attribute__((deprecated)) - -typedef char BOOL; -@class NSString; -@protocol NSCopying @end - -@interface NSObject -@end - -@interface NSDictionary : NSObject -@end - -@interface I : NSObject { - int ivarVal; -} -@property (nonatomic, weak) NSString *WeakProp; - -@property (nonatomic, strong) NSString *StrongProp; - -@property (nonatomic, strong) NSString *UnavailProp __attribute__((unavailable)); -- (void) setUnavailProp : (NSString *)Val; - -@property (nonatomic, strong) NSString *UnavailProp1 __attribute__((unavailable)); - -@property (nonatomic, strong) NSString *UnavailProp2; -- (void) setUnavailProp2 : (NSString *)Val __attribute__((unavailable)); - -@property (nonatomic, copy) NSDictionary *undoAction; -@end - -@implementation I -@end - -@class NSArray; - -@interface MyClass2 { -@private - NSArray *_names1; - NSArray *_names2; - NSArray *_names3; - NSArray *_names4; -} -@property (nonatomic, strong) NSArray *names2; -@property (nonatomic, strong) NSArray *names3; -@property (nonatomic, strong) NSArray *names4; -@property (nonatomic, strong) NSArray *names1; -@end - -// Properties that contain the name "delegate" or "dataSource", -// or have exact name "target" have unsafe_unretained attribute. -@interface NSInvocation -@property (nonatomic, assign) id target; - -@property (nonatomic, assign) id dataSource; - -@property (nonatomic, readonly, assign) id delegate; - -@property (nonatomic, assign) id xxxdelegateYYY; - - -@property (nonatomic, strong) id MYtarget; - -@property (nonatomic, strong) id targetX; - -@property (nonatomic) int value; - -@property (nonatomic, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (nonatomic, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (nonatomic, readonly) int Length; -@property (nonatomic, readonly, strong) id object; -+ (double) D; -@property (nonatomic, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER); -@property (nonatomic, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents; - -@property (nonatomic, getter=getStringValue, strong) NSString *stringValue; -@property (nonatomic, getter=getCounterValue, readonly) BOOL counterValue; -@property (nonatomic, getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (nonatomic, getter=getM, readonly) BOOL m; -@property (nonatomic, getter=getMA, readonly) BOOL MA; -@property (nonatomic, getter=getALL, readonly) BOOL ALL; -@property (nonatomic, getter=getMANY, readonly) BOOL MANY; -@property (nonatomic, getter=getSome, readonly) BOOL some; -@end - - -@interface NSInvocation(CAT) -@property (nonatomic, assign) id target; - -@property (nonatomic, assign) id dataSource; - -@property (nonatomic, assign) id xxxdelegateYYY; - - -@property (nonatomic, strong) id MYtarget; - -@property (nonatomic, strong) id targetX; - -@property (nonatomic) int value; - -@property (nonatomic, getter=isContinuous) BOOL continuous; - -- (id) isAnObject; -- (void)setAnObject : (id) object; - -@property (nonatomic, getter=isinValid, readonly) BOOL inValid; -- (void) setInValid : (BOOL) arg; - -- (void) Nothing; -@property (nonatomic, readonly) int Length; -@property (nonatomic, readonly, strong) id object; -+ (double) D; - -- (BOOL)is3bar; // watch out -- (NSString *)get3foo; // watch out - -@property (nonatomic, getter=getM, readonly) BOOL m; -@property (nonatomic, getter=getMA, readonly) BOOL MA; -@property (nonatomic, getter=getALL, readonly) BOOL ALL; -@property (nonatomic, getter=getMANY, readonly) BOOL MANY; -@property (nonatomic, getter=getSome, readonly) BOOL some; -@end - -DEPRECATED -@interface I_DEP -- (BOOL) isinValid; -- (void) setInValid : (BOOL) arg; -@end - -@interface AnotherOne -- (BOOL) isinValid DEPRECATED; -- (void) setInValid : (BOOL) arg; -- (id)MYtarget; -- (void)setMYtarget: (id)target DEPRECATED; -- (BOOL) getM DEPRECATED; - -- (id)xxxdelegateYYY DEPRECATED; -- (void)setXxxdelegateYYY:(id)delegate DEPRECATED; -@end - -#define NS_AVAILABLE __attribute__((availability(macosx,introduced=10.0))) -#define NORETURN __attribute__((noreturn)) -#define ALIGNED __attribute__((aligned(16))) - -@interface NSURL -// Do not infer a property. -@property (nonatomic, strong) NSURL *appStoreReceiptURL NS_AVAILABLE; -- (void) setAppStoreReceiptURL : (NSURL *)object; - -@property (nonatomic, strong) NSURL *appStoreReceiptURLX NS_AVAILABLE; - -// Do not infer a property. -@property (nonatomic, strong) NSURL *appStoreReceiptURLY ; -- (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE; - -@property (nonatomic, readonly, strong) id OkToInfer NS_AVAILABLE; - -// Do not infer a property. -@property (nonatomic, strong) NSURL *appStoreReceiptURLZ ; -- (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE; - -// Do not infer a property. -- (id) t1 NORETURN NS_AVAILABLE; -- (void) setT1 : (id) arg NS_AVAILABLE; - -@property (nonatomic, strong) id method1 ALIGNED NS_AVAILABLE; - -- (NSURL *)init; // No Change -+ (id)alloc; // No Change - -- (BOOL)is1stClass; // Not a valid property -@property (nonatomic, getter=isClass, readonly) BOOL class; // This is a valid property 'class' is not a keyword in ObjC -- (BOOL)isDouble; // Not a valid property - -@end - -@class NSMutableDictionary; - -@interface NSArray -@property (nonatomic, readonly, copy) id (^expressionBlock)(id, NSArray *, NSMutableDictionary *); -@property (nonatomic, copy) id (^MyBlock)(id, NSArray *, NSMutableDictionary *); -@property (nonatomic, readonly) id (*expressionFuncptr)(id, NSArray *, NSMutableDictionary *); -@property (nonatomic) id (*MyFuncptr)(id, NSArray *, NSMutableDictionary *); -@end - -@interface rdar15231241 -@property (nonatomic, readonly) double Ddelegate; -@property (nonatomic, readonly) float Fdelegate; -@property (nonatomic, readonly) int Idelegate; -@property (nonatomic, readonly) BOOL Bdelegate; -@end - -@protocol NSObject @end -@protocol MyProtocol -@property (nonatomic, readonly, strong) id readonlyProperty; -@property (nonatomic, strong) id readWriteProperty; -@end diff --git a/clang/test/ARCMT/objcmt-protocol-conformance.m b/clang/test/ARCMT/objcmt-protocol-conformance.m deleted file mode 100644 index e9bb4ac12e6d4..0000000000000 --- a/clang/test/ARCMT/objcmt-protocol-conformance.m +++ /dev/null @@ -1,129 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-protocol-conformance -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@interface NSObject @end - -@protocol P -- (id) Meth1: (double) arg; -@end - -@interface Test1 // Test for no super class and no protocol list -@end - -@implementation Test1 -- (id) Meth1: (double) arg { return 0; } -@end - -@protocol P1 @end -@protocol P2 @end - -@interface Test2 // Test for no super class and with protocol list -{ - id IVAR1; - id IVAR2; -} -@end - -@implementation Test2 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test3 : NSObject { // Test for Super class and no protocol list - id IV1; -} -@end - -@implementation Test3 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test4 : NSObject // Test for Super class and protocol list -@end - -@implementation Test4 -- (id) Meth1: (double) arg { return 0; } -@end - -// Test5 - conforms to P3 because it implement's P3's property. -@protocol P3 -@property (copy) id Prop; -@end - -@protocol P4 -@property (copy) id Prop; -@end - -@interface Test5 : NSObject -@end - -@implementation Test5 -@synthesize Prop=_XXX; -@end - -@protocol P5 -@property (copy) id Prop; -@end - -@protocol P6 -@property (copy) id Prop; -@end - -@interface Test6 : NSObject // Test for minimal listing of conforming protocols -@property (copy) id Prop; -@end - -@implementation Test6 -@end - -@class UIDynamicAnimator, UIWindow; -@interface UIResponder : NSObject -@end - -@protocol EmptyProtocol -@end - -@protocol OptionalMethodsOnly -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol OptionalPropertiesOnly -@optional -@property (strong, nonatomic) id OptionalProperty; -@end - -@protocol OptionalEvrything -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -@property (strong, nonatomic) id OptionalProperty; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol UIApplicationDelegate -@end - -@interface Test7 : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end - -@implementation Test7 -@end - -@interface BTLEBrowser -@end - -@protocol CBCentralManagerDelegate; - -@protocol CBCentralManagerDelegate -- (id) Meth1: (double) arg; -@end - -@interface BTLEBrowser() -@end - -@implementation BTLEBrowser -- (id) Meth15515206: (double) arg { return 0; } -@end diff --git a/clang/test/ARCMT/objcmt-protocol-conformance.m.result b/clang/test/ARCMT/objcmt-protocol-conformance.m.result deleted file mode 100644 index 987532544bc64..0000000000000 --- a/clang/test/ARCMT/objcmt-protocol-conformance.m.result +++ /dev/null @@ -1,129 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-protocol-conformance -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc %s.result - -@interface NSObject @end - -@protocol P -- (id) Meth1: (double) arg; -@end - -@interface Test1

// Test for no super class and no protocol list -@end - -@implementation Test1 -- (id) Meth1: (double) arg { return 0; } -@end - -@protocol P1 @end -@protocol P2 @end - -@interface Test2 // Test for no super class and with protocol list -{ - id IVAR1; - id IVAR2; -} -@end - -@implementation Test2 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test3 : NSObject

{ // Test for Super class and no protocol list - id IV1; -} -@end - -@implementation Test3 -- (id) Meth1: (double) arg { return 0; } -@end - -@interface Test4 : NSObject // Test for Super class and protocol list -@end - -@implementation Test4 -- (id) Meth1: (double) arg { return 0; } -@end - -// Test5 - conforms to P3 because it implement's P3's property. -@protocol P3 -@property (copy) id Prop; -@end - -@protocol P4 -@property (copy) id Prop; -@end - -@interface Test5 : NSObject -@end - -@implementation Test5 -@synthesize Prop=_XXX; -@end - -@protocol P5 -@property (copy) id Prop; -@end - -@protocol P6 -@property (copy) id Prop; -@end - -@interface Test6 : NSObject // Test for minimal listing of conforming protocols -@property (copy) id Prop; -@end - -@implementation Test6 -@end - -@class UIDynamicAnimator, UIWindow; -@interface UIResponder : NSObject -@end - -@protocol EmptyProtocol -@end - -@protocol OptionalMethodsOnly -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol OptionalPropertiesOnly -@optional -@property (strong, nonatomic) id OptionalProperty; -@end - -@protocol OptionalEvrything -@optional -- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator; -@property (strong, nonatomic) id OptionalProperty; -- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator; -@end - -@protocol UIApplicationDelegate -@end - -@interface Test7 : UIResponder -@property (strong, nonatomic) UIWindow *window; -@end - -@implementation Test7 -@end - -@interface BTLEBrowser -@end - -@protocol CBCentralManagerDelegate; - -@protocol CBCentralManagerDelegate -- (id) Meth1: (double) arg; -@end - -@interface BTLEBrowser() -@end - -@implementation BTLEBrowser -- (id) Meth15515206: (double) arg { return 0; } -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m b/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m deleted file mode 100644 index 1f56f4a2cf510..0000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m +++ /dev/null @@ -1,108 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fobjc-arc -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -- (id)initWithInt:(int)value; -@end - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = [NSArray arrayWithObjects:str, str, nil]; - arr = [[NSArray alloc] initWithObjects:str, str, nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil]; - dict = [[NSDictionary alloc] initWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil]; - - dict = [[NSDictionary alloc] initWithObjects:[[NSArray alloc] initWithObjects:@"1", @"2", nil] forKeys:[NSArray arrayWithObjects:@"A", @"B", nil]]; - - NSNumber *n = [[NSNumber alloc] initWithInt:2]; -} -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m.result b/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m.result deleted file mode 100644 index d974a2564d430..0000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals-in-arc.m.result +++ /dev/null @@ -1,108 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fobjc-arc -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -fobjc-arc -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -- (id)initWithInt:(int)value; -@end - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = @[str, str]; - arr = @[str, str]; - dict = @{@"key1": @"value1", @"key2": @"value2"}; - dict = @{@"key1": @"value1", @"key2": @"value2"}; - - dict = @{@"A": @"1", @"B": @"2"}; - - NSNumber *n = @2; -} -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-literals.m b/clang/test/ARCMT/objcmt-subscripting-literals.m deleted file mode 100644 index e2b03e2d7b587..0000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals.m +++ /dev/null @@ -1,230 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) -#define TWO_SEP(x,y) ((x), (y)) - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = [NSArray array]; - arr = [NSArray arrayWithObject:str]; - arr = [NSArray arrayWithObjects:str, str, nil]; - dict = [NSDictionary dictionary]; - dict = [NSDictionary dictionaryWithObject:arr forKey:str]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: PAIR(1), PAIR(2), nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: - @"value1", @"key1", -#ifdef BLAH - @"value2", @"key2", -#else - @"value3", @"key3", -#endif - nil ]; - - id o = [arr objectAtIndex:2]; - o = [dict objectForKey:@"key"]; - o = TWO([dict objectForKey:@"key"]); - o = TWO_SEP([dict objectForKey:@"key"], [arr objectAtIndex:2]); - o = [NSDictionary dictionaryWithObject:[NSDictionary dictionary] forKey:@"key"]; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - [marr replaceObjectAtIndex:2 withObject:@"val"]; - [mdict setObject:@"value" forKey:@"key"]; - [marr replaceObjectAtIndex:2 withObject:[arr objectAtIndex:4]]; - [mdict setObject:[dict objectForKey:@"key2"] forKey:@"key"]; - [mdict setObject:[dict objectForKey:@"key2"] forKey: -#if 1 - @"key1" -#else - @"key2" -#endif - ]; - [mdict setObject:[dict objectForKey: -#if 2 - @"key3" -#else - @"key4" -#endif - ] forKey:@"key"]; - [mdict setObject:@"value" forKey:[dict objectForKey: -#if 3 - @"key5" -#else - @"key6" -#endif - ] ]; - [mdict setObject:@"val" forKey:[dict objectForKey:@"key2"]]; - [mdict setObject:[dict objectForKey:@"key1"] forKey:[dict objectForKey:[NSArray arrayWithObject:@"arrkey"]]]; - __strong NSArray **parr = 0; - o = [*parr objectAtIndex:2]; - void *hd; - o = [(NSArray*)hd objectAtIndex:2]; - o = [ivarArr objectAtIndex:2]; - - dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", [NSArray array], nil] forKeys:[NSArray arrayWithObjects:@"A", [arr objectAtIndex:2], nil]]; - dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:arr]; - dict = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1", @"2", nil] forKeys:@[@"A", @"B"]]; - dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray array], @"A", [NSArray array], @"B", nil]; -} -@end - -extern const CFStringRef globStr; - -void test1(NSString *str) { - NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: str, globStr, nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: globStr, str, nil]; - dict = [NSDictionary dictionaryWithObject:str forKey:globStr]; - dict = [NSDictionary dictionaryWithObject:globStr forKey:str]; - - NSArray *arr = [NSArray arrayWithObjects: globStr, globStr, nil]; - arr = [NSArray arrayWithObjects: str, globStr, nil]; - arr = [NSArray arrayWithObjects: globStr, str, nil]; - arr = [NSArray arrayWithObject:globStr]; -} - -@interface Custom : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface Custom (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface MutableCustom : Custom -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustom (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface CustomUnavail : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface CustomUnavail (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -@interface MutableCustomUnavail : CustomUnavail -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustomUnavail (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -void test2(void) { - MutableCustom *mutc; - id o = [mutc objectAtIndex:4]; - [mutc replaceObjectAtIndex:2 withObject:@"val"]; - - MutableCustomUnavail *mutcunaval; - o = [mutcunaval objectAtIndex:4]; - [mutcunaval replaceObjectAtIndex:2 withObject:@"val"]; -} - -@interface NSLocale : NSObject -+ (id)systemLocale; -+ (id)currentLocale; -- (id)objectForKey:(id)key; -@end - -void test3(id key) { - id o = [[NSLocale currentLocale] objectForKey:key]; -} diff --git a/clang/test/ARCMT/objcmt-subscripting-literals.m.result b/clang/test/ARCMT/objcmt-subscripting-literals.m.result deleted file mode 100644 index e0b385741f01e..0000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-literals.m.result +++ /dev/null @@ -1,230 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -typedef const struct __CFString * CFStringRef; - -@interface NSObject -+ (id)alloc; -@end - -@protocol NSCopying -@end - -@interface NSString : NSObject -+ (id)stringWithString:(NSString *)string; -- (id)initWithString:(NSString *)aString; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSExtendedArray) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSMutableArray (NSExtendedMutableArray) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface NSDictionary : NSObject -- (id)objectForKey:(id)aKey; -@end - -@interface NSDictionary (NSExtendedDictionary) -- (id)objectForKeyedSubscript:(id)key; -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface NSMutableDictionary (NSExtendedMutableDictionary) -- (void)setObject:(id)obj forKeyedSubscript:(id )key; -@end - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -#define M(x) (x) -#define PAIR(x) @#x, [NSNumber numberWithInt:(x)] -#define TWO(x) ((x), (x)) -#define TWO_SEP(x,y) ((x), (y)) - -@interface I { - NSArray *ivarArr; -} -@end -@implementation I --(void) foo { - NSString *str; - NSArray *arr; - NSDictionary *dict; - - arr = @[]; - arr = @[str]; - arr = @[str, str]; - dict = @{}; - dict = @{str: arr}; - dict = @{@"key1": @"value1", @"key2": @"value2"}; - dict = [NSDictionary dictionaryWithObjectsAndKeys: PAIR(1), PAIR(2), nil]; - dict = [NSDictionary dictionaryWithObjectsAndKeys: - @"value1", @"key1", -#ifdef BLAH - @"value2", @"key2", -#else - @"value3", @"key3", -#endif - nil ]; - - id o = arr[2]; - o = dict[@"key"]; - o = TWO(dict[@"key"]); - o = TWO_SEP(dict[@"key"], arr[2]); - o = @{@"key": @{}}; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - marr[2] = @"val"; - mdict[@"key"] = @"value"; - marr[2] = arr[4]; - mdict[@"key"] = dict[@"key2"]; - [mdict setObject:dict[@"key2"] forKey: -#if 1 - @"key1" -#else - @"key2" -#endif - ]; - mdict[@"key"] = [dict objectForKey: -#if 2 - @"key3" -#else - @"key4" -#endif - ]; - mdict[[dict objectForKey: -#if 3 - @"key5" -#else - @"key6" -#endif - ]] = @"value"; - mdict[dict[@"key2"]] = @"val"; - mdict[dict[@[@"arrkey"]]] = dict[@"key1"]; - __strong NSArray **parr = 0; - o = (*parr)[2]; - void *hd; - o = ((NSArray*)hd)[2]; - o = ivarArr[2]; - - dict = @{@"A": @"1", arr[2]: @[]}; - dict = [NSDictionary dictionaryWithObjects:@[@"1", @"2"] forKeys:arr]; - dict = @{@"A": @"1", @"B": @"2"}; - dict = @{@"A": @[], @"B": @[]}; -} -@end - -extern const CFStringRef globStr; - -void test1(NSString *str) { - NSDictionary *dict = @{(id)globStr: str}; - dict = @{str: (id)globStr}; - dict = @{(id)globStr: str}; - dict = @{str: (id)globStr}; - - NSArray *arr = @[(id)globStr, (id)globStr]; - arr = @[str, (id)globStr]; - arr = @[(id)globStr, str]; - arr = @[(id)globStr]; -} - -@interface Custom : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface Custom (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx; -@end - -@interface MutableCustom : Custom -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustom (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx; -@end - -@interface CustomUnavail : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface CustomUnavail (Extended) -- (id)objectAtIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -@interface MutableCustomUnavail : CustomUnavail -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface MutableCustomUnavail (Extended) -- (void)setObject:(id)obj atIndexedSubscript:(unsigned)idx __attribute__((unavailable)); -@end - -void test2(void) { - MutableCustom *mutc; - id o = mutc[4]; - mutc[2] = @"val"; - - MutableCustomUnavail *mutcunaval; - o = [mutcunaval objectAtIndex:4]; - [mutcunaval replaceObjectAtIndex:2 withObject:@"val"]; -} - -@interface NSLocale : NSObject -+ (id)systemLocale; -+ (id)currentLocale; -- (id)objectForKey:(id)key; -@end - -void test3(id key) { - id o = [[NSLocale currentLocale] objectForKey:key]; -} diff --git a/clang/test/ARCMT/objcmt-subscripting-unavailable.m b/clang/test/ARCMT/objcmt-subscripting-unavailable.m deleted file mode 100644 index d72c362e30f4f..0000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-unavailable.m +++ /dev/null @@ -1,79 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSDictionary : NSObject -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface I -@end -@implementation I --(void) foo { - id str; - NSArray *arr; - NSDictionary *dict; - - arr = [NSArray array]; - arr = [NSArray arrayWithObject:str]; - arr = [NSArray arrayWithObjects:str, str, nil]; - dict = [NSDictionary dictionary]; - dict = [NSDictionary dictionaryWithObject:arr forKey:str]; - - id o = [arr objectAtIndex:2]; - o = [dict objectForKey:@"key"]; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - [marr replaceObjectAtIndex:2 withObject:@"val"]; - [mdict setObject:@"value" forKey:@"key"]; - [marr replaceObjectAtIndex:2 withObject:[arr objectAtIndex:4]]; - [mdict setObject:[dict objectForKey:@"key2"] forKey:@"key"]; -} -@end diff --git a/clang/test/ARCMT/objcmt-subscripting-unavailable.m.result b/clang/test/ARCMT/objcmt-subscripting-unavailable.m.result deleted file mode 100644 index bd74d55838608..0000000000000 --- a/clang/test/ARCMT/objcmt-subscripting-unavailable.m.result +++ /dev/null @@ -1,79 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result - -typedef signed char BOOL; -#define nil ((void*) 0) - -@interface NSObject -+ (id)alloc; -@end - -@interface NSArray : NSObject -- (id)objectAtIndex:(unsigned long)index; -@end - -@interface NSArray (NSArrayCreation) -+ (id)array; -+ (id)arrayWithObject:(id)anObject; -+ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; -+ (id)arrayWithObjects:(id)firstObj, ...; -+ (id)arrayWithArray:(NSArray *)array; - -- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt; -- (id)initWithObjects:(id)firstObj, ...; -- (id)initWithArray:(NSArray *)array; -@end - -@interface NSMutableArray : NSArray -- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject; -@end - -@interface NSDictionary : NSObject -@end - -@interface NSDictionary (NSDictionaryCreation) -+ (id)dictionary; -+ (id)dictionaryWithObject:(id)object forKey:(id)key; -+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -+ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...; -+ (id)dictionaryWithDictionary:(NSDictionary *)dict; -+ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; -- (id)initWithObjectsAndKeys:(id)firstObject, ...; -- (id)initWithDictionary:(NSDictionary *)otherDictionary; -- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys; - -- (id)objectForKey:(id)aKey; -@end - -@interface NSMutableDictionary : NSDictionary -- (void)setObject:(id)anObject forKey:(id)aKey; -@end - -@interface I -@end -@implementation I --(void) foo { - id str; - NSArray *arr; - NSDictionary *dict; - - arr = @[]; - arr = @[str]; - arr = @[str, str]; - dict = @{}; - dict = @{str: arr}; - - id o = [arr objectAtIndex:2]; - o = [dict objectForKey:@"key"]; - NSMutableArray *marr = 0; - NSMutableDictionary *mdict = 0; - [marr replaceObjectAtIndex:2 withObject:@"val"]; - [mdict setObject:@"value" forKey:@"key"]; - [marr replaceObjectAtIndex:2 withObject:[arr objectAtIndex:4]]; - [mdict setObject:[dict objectForKey:@"key2"] forKey:@"key"]; -} -@end diff --git a/clang/test/ARCMT/objcmt-undefined-ns-macros.m b/clang/test/ARCMT/objcmt-undefined-ns-macros.m deleted file mode 100644 index 473b49589222d..0000000000000 --- a/clang/test/ARCMT/objcmt-undefined-ns-macros.m +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -typedef long NSInteger; -enum { - UIViewNone = 0x0, - UIViewMargin = 0x1, - UIViewWidth = 0x2, - UIViewRightMargin = 0x3, - UIViewBottomMargin = 0xbadbeef -}; -typedef NSInteger UITableStyle; - - -typedef - enum { two = 1 } NumericEnum2; - -typedef enum { three = 1 } NumericEnum3; - -typedef enum { four = 1 } NumericEnum4; - diff --git a/clang/test/ARCMT/objcmt-undefined-ns-macros.m.result b/clang/test/ARCMT/objcmt-undefined-ns-macros.m.result deleted file mode 100644 index a6942e20795fd..0000000000000 --- a/clang/test/ARCMT/objcmt-undefined-ns-macros.m.result +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -objcmt-migrate-ns-macros -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -triple x86_64-apple-darwin11 -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result - -typedef long NSInteger; -#ifndef NS_ENUM -@import Foundation; -#endif -typedef NS_OPTIONS(NSUInteger, UITableStyle) { - UIViewNone = 0x0, - UIViewMargin = 0x1, - UIViewWidth = 0x2, - UIViewRightMargin = 0x3, - UIViewBottomMargin = 0xbadbeef -}; - - -typedef - NS_ENUM(unsigned int, NumericEnum2) { two = 1 }; - -typedef NS_ENUM(unsigned int, NumericEnum3) { three = 1 }; - -typedef NS_ENUM(unsigned int, NumericEnum4) { four = 1 }; - diff --git a/clang/test/ARCMT/objcmt-with-pch.m b/clang/test/ARCMT/objcmt-with-pch.m deleted file mode 100644 index 0925442d45eb9..0000000000000 --- a/clang/test/ARCMT/objcmt-with-pch.m +++ /dev/null @@ -1,17 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -include-pch %t.pch -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result -include-pch %t.pch - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(void) { - NSNumber *n = [NSNumber numberWithInt:1]; -} diff --git a/clang/test/ARCMT/objcmt-with-pch.m.result b/clang/test/ARCMT/objcmt-with-pch.m.result deleted file mode 100644 index 6d37d11fe480d..0000000000000 --- a/clang/test/ARCMT/objcmt-with-pch.m.result +++ /dev/null @@ -1,17 +0,0 @@ -// REQUIRES: x86-registered-target -// RUN: rm -rf %t -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %S/Common.h -emit-pch -o %t.pch -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -include-pch %t.pch -// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result -include-pch %t.pch - -@interface NSNumber : NSObject -@end - -@interface NSNumber (NSNumberCreation) -+ (NSNumber *)numberWithInt:(int)value; -@end - -void foo(void) { - NSNumber *n = @1; -} diff --git a/clang/test/ARCMT/protected-scope.m b/clang/test/ARCMT/protected-scope.m deleted file mode 100644 index b522f54cdf7c1..0000000000000 --- a/clang/test/ARCMT/protected-scope.m +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(id p, int x) { - int v; - switch(x) { - case 0: - v++; - id w1 = p; - id w2 = p; - break; - case 1: - v++; - id w3 = p; - break; - case 2: - case 3: - break; - default: - break; - } -} - -void test2(int p) { - switch (p) { - case 3:; - NSObject *o = [[NSObject alloc] init]; - [o release]; - break; - default: - break; - } -} diff --git a/clang/test/ARCMT/protected-scope.m.result b/clang/test/ARCMT/protected-scope.m.result deleted file mode 100644 index 55070f2732271..0000000000000 --- a/clang/test/ARCMT/protected-scope.m.result +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -void test(id p, int x) { - int v; - switch(x) { - case 0: { - v++; - id w1 = p; - id w2 = p; - break; - } - case 1: { - v++; - id w3 = p; - break; - } - case 2: - case 3: - break; - default: - break; - } -} - -void test2(int p) { - switch (p) { - case 3: {; - NSObject *o = [[NSObject alloc] init]; - break; - } - default: - break; - } -} diff --git a/clang/test/ARCMT/releases-driver.m b/clang/test/ARCMT/releases-driver.m deleted file mode 100644 index 96f96c1d3b482..0000000000000 --- a/clang/test/ARCMT/releases-driver.m +++ /dev/null @@ -1,67 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -triple x86_64-apple-macosx10.6 -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (retain) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - [x retain]; - self.bar = obj; - // do stuff with x; - [x release]; - - [IhaveSideEffect() release]; - - [x release], x = 0; -} - -@end - -void func(Foo *p) { - [p release]; - (([p release])); -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -- (void) dealloc { - [_foo release]; -} -@end - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { - RELEASE_MACRO(p); - RELEASE_MACRO2(p); -} diff --git a/clang/test/ARCMT/releases-driver.m.result b/clang/test/ARCMT/releases-driver.m.result deleted file mode 100644 index e7da9a04fc62a..0000000000000 --- a/clang/test/ARCMT/releases-driver.m.result +++ /dev/null @@ -1,58 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -triple x86_64-apple-macosx10.6 -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (strong) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - self.bar = obj; - // do stuff with x; - - IhaveSideEffect(); - - x = 0; -} - -@end - -void func(Foo *p) { -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -@end - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { -} diff --git a/clang/test/ARCMT/releases.m b/clang/test/ARCMT/releases.m deleted file mode 100644 index 8636a8a5acea8..0000000000000 --- a/clang/test/ARCMT/releases.m +++ /dev/null @@ -1,98 +0,0 @@ -// RUN: %clang_cc1 -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil 0 - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (retain) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - [x retain]; - self.bar = obj; - // do stuff with x; - [x release]; - - [IhaveSideEffect() release]; - - [x release], x = 0; - - @try { - } @finally { - [x release]; - } -} - -@end - -void func(Foo *p) { - [p release]; - (([p release])); -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -- (void) dealloc { - [_foo release]; -} -@end - -void block_test(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = [p retain]; - [p release]; - return bar; - }; - IB(); - } - return [p retain]; - }; -} - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { - RELEASE_MACRO(p); - RELEASE_MACRO2(p); -} - -@implementation Foo2 - -static id internal_var = 0; - -+ (void)setIt:(id)newone { - if (internal_var != newone) { - [internal_var release]; - internal_var = [newone retain]; - } -} -@end diff --git a/clang/test/ARCMT/releases.m.result b/clang/test/ARCMT/releases.m.result deleted file mode 100644 index 261175362b9bd..0000000000000 --- a/clang/test/ARCMT/releases.m.result +++ /dev/null @@ -1,87 +0,0 @@ -// RUN: %clang_cc1 -fobjc-exceptions -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fobjc-exceptions -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil 0 - -typedef int BOOL; - -id IhaveSideEffect(void); - -@protocol NSObject -- (BOOL)isEqual:(id)object; -- (id)retain; -- (oneway void)release; -@end - -@interface NSObject {} -@end - -@interface Foo : NSObject { - id bar; -} -@property (strong) id bar; --(void)test:(id)obj; -@end - -@implementation Foo - -@synthesize bar; - --(void)test:(id)obj { - id x = self.bar; - self.bar = obj; - // do stuff with x; - - IhaveSideEffect(); - - x = 0; - - @try { - } @finally { - x = nil; - } -} - -@end - -void func(Foo *p) { -} - -@interface Baz { - id _foo; -} -@end - -@implementation Baz -@end - -void block_test(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = p; - return bar; - }; - IB(); - } - return p; - }; -} - -#define RELEASE_MACRO(x) [x release] -#define RELEASE_MACRO2(x) RELEASE_MACRO(x) - -void test2(id p) { -} - -@implementation Foo2 - -static id internal_var = 0; - -+ (void)setIt:(id)newone { - if (internal_var != newone) { - internal_var = newone; - } -} -@end diff --git a/clang/test/ARCMT/remap-applying.c b/clang/test/ARCMT/remap-applying.c deleted file mode 100644 index dee2e391d5bd5..0000000000000 --- a/clang/test/ARCMT/remap-applying.c +++ /dev/null @@ -1,4 +0,0 @@ -a bc - -// RUN: echo "[{\"file\": \"%/s\", \"offset\": 1, \"remove\": 2, }]" > %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result diff --git a/clang/test/ARCMT/remap-applying.c.result b/clang/test/ARCMT/remap-applying.c.result deleted file mode 100644 index 514e9c264915d..0000000000000 --- a/clang/test/ARCMT/remap-applying.c.result +++ /dev/null @@ -1,4 +0,0 @@ -ac - -// RUN: echo "[{\"file\": \"%/s\", \"offset\": 1, \"remove\": 2, }]" > %t.remap -// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result diff --git a/clang/test/ARCMT/remove-dealloc-method.m b/clang/test/ARCMT/remove-dealloc-method.m deleted file mode 100644 index 8e39fc874c950..0000000000000 --- a/clang/test/ARCMT/remove-dealloc-method.m +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil ((void*) 0) - -@interface Foo -@property (retain) id x; -@property (retain) id y; -@property (retain) id w; -@property (retain) id z; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize z; - -- (void) dealloc { - self.x = 0; - [self setY:nil]; - w = nil; - self.z = nil; -} -@end diff --git a/clang/test/ARCMT/remove-dealloc-method.m.result b/clang/test/ARCMT/remove-dealloc-method.m.result deleted file mode 100644 index 47e31f9d249ae..0000000000000 --- a/clang/test/ARCMT/remove-dealloc-method.m.result +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#define nil ((void*) 0) - -@interface Foo -@property (strong) id x; -@property (strong) id y; -@property (strong) id w; -@property (strong) id z; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize z; - -@end diff --git a/clang/test/ARCMT/remove-dealloc-zerouts.m b/clang/test/ARCMT/remove-dealloc-zerouts.m deleted file mode 100644 index 4176ec580c3e5..0000000000000 --- a/clang/test/ARCMT/remove-dealloc-zerouts.m +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface Foo -@property (retain) id x; -@property (retain) id y; -@property (retain) id w; -@property (retain) id z; -@property (strong) id q; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize q; -@dynamic z; - -- (void) dealloc { - self.x = self.y = self.w = 0; - self.x = 0, w = 0, y = 0; - [self setY:0]; - w = 0; - q = 0; - self.z = 0; -} -@end - -@interface Bar -@property (retain) Foo *a; -- (void) setA:(Foo*) val; -- (id) a; -@end - -@implementation Bar -- (void) dealloc { - [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. - self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. -} -@synthesize a; -- (void) setA:(Foo*) val { } -- (id) a {return 0;} -@end diff --git a/clang/test/ARCMT/remove-dealloc-zerouts.m.result b/clang/test/ARCMT/remove-dealloc-zerouts.m.result deleted file mode 100644 index 9ae831abacf25..0000000000000 --- a/clang/test/ARCMT/remove-dealloc-zerouts.m.result +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -@interface Foo -@property (strong) id x; -@property (strong) id y; -@property (strong) id w; -@property (strong) id z; -@property (strong) id q; -@end - -@implementation Foo -@synthesize x; -@synthesize y; -@synthesize w; -@synthesize q; -@dynamic z; - -- (void) dealloc { - self.z = 0; -} -@end - -@interface Bar -@property (strong) Foo *a; -- (void) setA:(Foo*) val; -- (id) a; -@end - -@implementation Bar -- (void) dealloc { - [self setA:0]; // This is user-defined setter overriding synthesize, don't touch it. - self.a.x = 0; // every dealloc must zero out its own ivar. This patter is not recognized. -} -@synthesize a; -- (void) setA:(Foo*) val { } -- (id) a {return 0;} -@end diff --git a/clang/test/ARCMT/remove-statements.m b/clang/test/ARCMT/remove-statements.m deleted file mode 100644 index 286a8e715e0d3..0000000000000 --- a/clang/test/ARCMT/remove-statements.m +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface myController : NSObject --(id)test:(id)x; -@end - -#define MY_MACRO1(x) -#define MY_MACRO2(x) (void)x - -@implementation myController --(id) test:(id) x { - [[x retain] release]; - return [[x retain] autorelease]; -} - --(void)dealloc -{ - id array, array_already_empty; - for (id element in array_already_empty) { - } - - [array release]; - ; - - int b, b_array_already_empty; - if (b) - [array release]; - if (b_array_already_empty) ; - - if (b) { - [array release]; - } - if (b_array_already_empty) { - } - - if (b) - MY_MACRO1(array); - if (b) - MY_MACRO2(array); -} -@end diff --git a/clang/test/ARCMT/remove-statements.m.result b/clang/test/ARCMT/remove-statements.m.result deleted file mode 100644 index 6a4ea08b8c95b..0000000000000 --- a/clang/test/ARCMT/remove-statements.m.result +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface myController : NSObject --(id)test:(id)x; -@end - -#define MY_MACRO1(x) -#define MY_MACRO2(x) (void)x - -@implementation myController --(id) test:(id) x { - return x; -} - --(void)dealloc -{ - id array, array_already_empty; - for (id element in array_already_empty) { - } - - ; - - int b, b_array_already_empty; - if (b_array_already_empty) ; - - if (b_array_already_empty) { - } - - if (b) - MY_MACRO1(array); - if (b) - MY_MACRO2(array); -} -@end diff --git a/clang/test/ARCMT/retains.m b/clang/test/ARCMT/retains.m deleted file mode 100644 index a38efe1596403..0000000000000 --- a/clang/test/ARCMT/retains.m +++ /dev/null @@ -1,71 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -id IhaveSideEffect(void); - -@interface Foo : NSObject { - id bar; -} -@property (retain) id bar; --(id)test:(id)obj; --(id)something; -@end - -#define Something_Macro(key, comment) \ - [[Foo new] something] - -@implementation Foo - -@synthesize bar; - --(id)something { return (id)0; } - --(id)test:(id)obj { - id x = self.bar; - [x retain]; - self.bar = obj; - if (obj) - [obj retain]; - - [Something_Macro(@"foo", "@bar") retain]; - - [IhaveSideEffect() retain]; - - [[self something] retain]; - - [[self retain] something]; - - [[IhaveSideEffect() retain] release]; - [[x retain] release]; - // do stuff with x; - [x release]; - return [self retain]; -} - -- (id)test1 { - id x=0; - ([x retain]); - return ((([x retain]))); -} -@end - -id foo (Foo *p) { - p = [p retain]; - return ([p retain]); -} - -void block_tests(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = [p retain]; - return bar; - }; - IB(); - } - return [p retain]; - }; -} diff --git a/clang/test/ARCMT/retains.m.result b/clang/test/ARCMT/retains.m.result deleted file mode 100644 index cd3bb3848fcec..0000000000000 --- a/clang/test/ARCMT/retains.m.result +++ /dev/null @@ -1,65 +0,0 @@ -// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -id IhaveSideEffect(void); - -@interface Foo : NSObject { - id bar; -} -@property (strong) id bar; --(id)test:(id)obj; --(id)something; -@end - -#define Something_Macro(key, comment) \ - [[Foo new] something] - -@implementation Foo - -@synthesize bar; - --(id)something { return (id)0; } - --(id)test:(id)obj { - id x = self.bar; - self.bar = obj; - - Something_Macro(@"foo", "@bar"); - - IhaveSideEffect(); - - [self something]; - - [self something]; - - IhaveSideEffect(); - // do stuff with x; - return self; -} - -- (id)test1 { - id x=0; - return (((x))); -} -@end - -id foo (Foo *p) { - p = p; - return (p); -} - -void block_tests(Foo *p) { - id (^B)(void) = ^(void) { - if (p) { - id (^IB)(void) = ^(void) { - id bar = p; - return bar; - }; - IB(); - } - return p; - }; -} diff --git a/clang/test/ARCMT/rewrite-block-var.m b/clang/test/ARCMT/rewrite-block-var.m deleted file mode 100644 index eb3c5b6535971..0000000000000 --- a/clang/test/ARCMT/rewrite-block-var.m +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -fobjc-arc -x objective-c -fobjc-runtime-has-weak %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fblocks -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject --(Foo *)something; -@end - -void bar(void (^block)(void)); - -void test1(Foo *p) { - __block Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); -} - -void test2(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - x = [p something]; - }); -} - -void test3(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - [x something]; - }); - bar(^{ - x = 0; - }); -} - -void test4(Foo *p) { - __block Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); - bar(^{ - [x something]; - }); -} diff --git a/clang/test/ARCMT/rewrite-block-var.m.result b/clang/test/ARCMT/rewrite-block-var.m.result deleted file mode 100644 index cf5718fbd7f5d..0000000000000 --- a/clang/test/ARCMT/rewrite-block-var.m.result +++ /dev/null @@ -1,45 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -fobjc-arc -x objective-c -fobjc-runtime-has-weak %s.result -// RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fblocks -fsyntax-only %s > %t -// RUN: diff %t %s.result - -#include "Common.h" - -@interface Foo : NSObject --(Foo *)something; -@end - -void bar(void (^block)(void)); - -void test1(Foo *p) { - __weak Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); -} - -void test2(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - x = [p something]; - }); -} - -void test3(Foo *p) { - __block Foo *x; // __block used as output variable. - bar(^{ - [x something]; - }); - bar(^{ - x = 0; - }); -} - -void test4(Foo *p) { - __weak Foo *x = p; // __block used just to break cycle. - bar(^{ - [x something]; - }); - bar(^{ - [x something]; - }); -} diff --git a/clang/test/ARCMT/safe-arc-assign.m b/clang/test/ARCMT/safe-arc-assign.m deleted file mode 100644 index 4a0a575794e16..0000000000000 --- a/clang/test/ARCMT/safe-arc-assign.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -void test12(id collection) { - for (id x in collection) { - x = 0; - x = 0; - } - - for (__strong id x in collection) { - x = 0; - } -} diff --git a/clang/test/ARCMT/safe-arc-assign.m.result b/clang/test/ARCMT/safe-arc-assign.m.result deleted file mode 100644 index c25955ea7d1c9..0000000000000 --- a/clang/test/ARCMT/safe-arc-assign.m.result +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t -// RUN: diff %t %s.result - -void test12(id collection) { - for (__strong id x in collection) { - x = 0; - x = 0; - } - - for (__strong id x in collection) { - x = 0; - } -} diff --git a/clang/test/ARCMT/verify.m b/clang/test/ARCMT/verify.m deleted file mode 100644 index 7d245fe80575e..0000000000000 --- a/clang/test/ARCMT/verify.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clang_cc1 -arcmt-action=check -verify %s -// RUN: not %clang_cc1 -arcmt-action=check -verify %t.invalid 2>&1 | FileCheck %s - -#if 0 -// expected-error {{should be ignored}} -#endif - -#error should not be ignored -// expected-error@-1 {{should not be ignored}} - -#error -// expected-error@-1 {{}} - -// CHECK: error: no expected directives found: consider use of 'expected-no-diagnostics' -// CHECK-NEXT: error: 'expected-error' diagnostics seen but not expected: -// CHECK-NEXT: (frontend): error reading '{{.*}}verify.m.tmp.invalid' -// CHECK-NEXT: 2 errors generated. diff --git a/clang/test/ARCMT/with-arc-mode-modify.m b/clang/test/ARCMT/with-arc-mode-modify.m deleted file mode 100644 index beff6784bbbb0..0000000000000 --- a/clang/test/ARCMT/with-arc-mode-modify.m +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -fsyntax-only -fobjc-arc -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -@protocol NSObject -- (oneway void)release; -@end - -void test1(id p) { - [p release]; -} diff --git a/clang/test/ARCMT/with-arc-mode-modify.m.result b/clang/test/ARCMT/with-arc-mode-modify.m.result deleted file mode 100644 index 685226db86541..0000000000000 --- a/clang/test/ARCMT/with-arc-mode-modify.m.result +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result -// RUN: cat %s > %t -// RUN: %clang_cc1 -arcmt-action=modify -fsyntax-only -fobjc-arc -x objective-c %t -// RUN: diff %t %s.result -// RUN: rm %t - -@protocol NSObject -- (oneway void)release; -@end - -void test1(id p) { -} diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index 7034e8c56bd62..d51b039d40043 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -1272,6 +1272,22 @@ namespace BuiltinMemcpy { return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; } static_assert(test_incomplete_array_type() == 1234); // both-error {{constant}} both-note {{in call}} + + + /// FIXME: memmove needs to support overlapping memory regions. + constexpr bool memmoveOverlapping() { + char s1[] {1, 2, 3}; + __builtin_memmove(s1, s1 + 1, 2 * sizeof(char)); + // Now: 2, 3, 3 + bool Result1 = (s1[0] == 2 && s1[1] == 3 && s1[2]== 3); + + __builtin_memmove(s1 + 1, s1, 2 * sizeof(char)); + // Now: 2, 2, 3 + bool Result2 = (s1[0] == 2 && s1[1] == 2 && s1[2]== 3); + + return Result1 && Result2; + } + static_assert(memmoveOverlapping()); // expected-error {{failed}} } namespace Memcmp { diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp index 268226a7c143e..6f65fa5c7cfd3 100644 --- a/clang/test/AST/ByteCode/cxx20.cpp +++ b/clang/test/AST/ByteCode/cxx20.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fexperimental-new-constant-interpreter -std=c++20 -verify=both,expected -fcxx-exceptions %s +// RUN: %clang_cc1 -fcxx-exceptions -fexperimental-new-constant-interpreter -std=c++20 -verify=both,expected -fcxx-exceptions %s -DNEW_INTERP // RUN: %clang_cc1 -fcxx-exceptions -std=c++20 -verify=both,ref -fcxx-exceptions %s void test_alignas_operand() { @@ -908,3 +908,57 @@ namespace TemporaryInNTTP { // expected-note {{created here}} B<2> j2; /// Ok. } + +namespace LocalDestroy { + /// This is reduced from a libc++ test case. + /// The local f.TI.copied points to the local variable Copied, and we used to + /// destroy Copied before f, causing problems later on when a DeadBlock had a + /// pointer pointing to it that was already destroyed. + struct TrackInitialization { + bool *copied_; + }; + struct TrackingPred : TrackInitialization { + constexpr TrackingPred(bool *copied) : TrackInitialization(copied) {} + }; + struct F { + const TrackingPred &TI; + }; + constexpr int f() { + bool Copied = false; + TrackingPred TI(&Copied); + F f{TI}; + return 1; + } + static_assert(f() == 1); +} + +namespace PseudoDtor { + constexpr int f1() { + using T = int; + int a = 0; + a.~T(); + return a; // both-note {{read of object outside its lifetime}} + } + static_assert(f1() == 0); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + + constexpr int f2() { + using T = int; + int a = 0; + a.~T(); + a = 0; // both-note {{assignment to object outside its lifetime}} + return a; + } + static_assert(f2() == 0); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + +#ifdef NEW_INTERP + /// FIXME: Currently crashes with the current interpreter, see https://github.com/llvm/llvm-project/issues/53741 + constexpr int f3() { + using T = int; + 0 .~T(); + return 0; + } + static_assert(f3() == 0); +#endif +} diff --git a/clang/test/AST/ByteCode/cxx26.cpp b/clang/test/AST/ByteCode/cxx26.cpp index 0b0e2b21e8201..cd6b533065010 100644 --- a/clang/test/AST/ByteCode/cxx26.cpp +++ b/clang/test/AST/ByteCode/cxx26.cpp @@ -1,10 +1,33 @@ // RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=ref,both %s // RUN: %clang_cc1 -std=c++26 -fsyntax-only -fcxx-exceptions -verify=expected,both %s -fexperimental-new-constant-interpreter -// both-no-diagnostics +namespace std { + using size_t = decltype(sizeof(0)); +} namespace VoidCast { constexpr void* p = nullptr; constexpr int* q = static_cast(p); static_assert(q == nullptr); } + +namespace ReplaceableAlloc { + struct F { + static void* operator new(std::size_t n) { + return nullptr; // both-warning {{should not return a null pointer}} + } + }; + + constexpr F *createF() { + return new F(); // both-note {{call to class-specific 'operator new'}} + } + + constexpr bool foo() { + F *f = createF(); // both-note {{in call to}} + + delete f; + return true; + } + static_assert(foo()); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} +} diff --git a/clang/test/AST/ByteCode/cxx2a.cpp b/clang/test/AST/ByteCode/cxx2a.cpp index e478a0ddc4c14..72ef58ca0b1d1 100644 --- a/clang/test/AST/ByteCode/cxx2a.cpp +++ b/clang/test/AST/ByteCode/cxx2a.cpp @@ -139,9 +139,7 @@ namespace TypeId { static_assert(&B2().ti1 == &typeid(B)); static_assert(&B2().ti2 == &typeid(B2)); extern B2 extern_b2; - static_assert(&typeid(extern_b2) == &typeid(B2)); // expected-error {{constant expression}} \ - // expected-note{{typeid applied to object 'extern_b2' whose dynamic type is not constant}} - + static_assert(&typeid(extern_b2) == &typeid(B2)); constexpr B2 b2; constexpr const B &b1 = b2; @@ -170,3 +168,12 @@ namespace TypeId { } static_assert(side_effects()); } + +consteval int f(int i); +constexpr bool test(auto i) { + return f(0) == 0; +} +consteval int f(int i) { + return 2 * i; +} +static_assert(test(42)); diff --git a/clang/test/AST/ByteCode/literals.cpp b/clang/test/AST/ByteCode/literals.cpp index b75ca2b19a969..a80ee7ad84fc7 100644 --- a/clang/test/AST/ByteCode/literals.cpp +++ b/clang/test/AST/ByteCode/literals.cpp @@ -914,12 +914,18 @@ namespace TypeTraits { } #if __cplusplus >= 201402L +namespace SomeNS { + using MyInt = int; +} + constexpr int ignoredDecls() { static_assert(true, ""); struct F { int a; }; enum E { b }; using A = int; typedef int Z; + namespace NewNS = SomeNS; + using NewNS::MyInt; return F{12}.a; } diff --git a/clang/test/AST/ByteCode/neon.c b/clang/test/AST/ByteCode/neon.c new file mode 100644 index 0000000000000..5905d78086039 --- /dev/null +++ b/clang/test/AST/ByteCode/neon.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -disable-O0-optnone -emit-llvm -o - %s -fexperimental-new-constant-interpreter + +// REQUIRES: aarch64-registered-target + +/// This just tests that we're not crashing with a non-primitive vector element type. + +typedef __mfp8 mfloat8_t; +typedef __bf16 bfloat16_t; + +typedef __attribute__((neon_vector_type(8))) mfloat8_t mfloat8x8_t; +typedef __attribute__((neon_vector_type(8))) bfloat16_t bfloat16x8_t; + +typedef __UINT64_TYPE__ fpm_t; +#define __ai static __inline__ __attribute__((__always_inline__, __nodebug__)) +__ai __attribute__((target("fp8,neon"))) bfloat16x8_t vcvt1_bf16_mf8_fpm(mfloat8x8_t __p0, fpm_t __p1) { + bfloat16x8_t __ret; + __ret = (bfloat16x8_t) __builtin_neon_vcvt1_bf16_mf8_fpm(__p0, __p1); + return __ret; +} diff --git a/clang/test/AST/ByteCode/new-delete.cpp b/clang/test/AST/ByteCode/new-delete.cpp index a8f073aa03fc1..e60ff894c9715 100644 --- a/clang/test/AST/ByteCode/new-delete.cpp +++ b/clang/test/AST/ByteCode/new-delete.cpp @@ -268,11 +268,10 @@ namespace NowThrowNew { delete[] p; return result; } - /// This needs support for CXXConstrucExprs with non-constant array sizes. - static_assert(erroneous_array_bound_nothrow2(3)); // expected-error {{not an integral constant expression}} - static_assert(erroneous_array_bound_nothrow2(0));// expected-error {{not an integral constant expression}} - static_assert(erroneous_array_bound_nothrow2(-1) == 0);// expected-error {{not an integral constant expression}} - static_assert(!erroneous_array_bound_nothrow2(1LL << 62));// expected-error {{not an integral constant expression}} + static_assert(erroneous_array_bound_nothrow2(3)); + static_assert(erroneous_array_bound_nothrow2(0)); + static_assert(erroneous_array_bound_nothrow2(-1) == 0); + static_assert(!erroneous_array_bound_nothrow2(1LL << 62)); constexpr bool erroneous_array_bound(long long n) { delete[] new int[n]; // both-note {{array bound -1 is negative}} both-note {{array bound 4611686018427387904 is too large}} @@ -857,6 +856,54 @@ struct SS { }; constexpr unsigned short ssmall = SS(100)[42]; + + +namespace IncompleteArray { + struct A { + int b = 10; + }; + constexpr int test1() { + int n = 5; + int* a = new int[n]; + int c = a[0]; // both-note {{read of uninitialized object}} + delete[] a; + return c; + } + static_assert(test1() == 10); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + + constexpr int test2() { + int n = 0; + int* a = new int[n]; + delete[] a; + return 10; + } + static_assert(test2() == 10); + + /// In this case, the type of the initializer is A[2], while the full size of the + /// allocated array is of course 5. The remaining 3 elements need to be initialized + /// using A's constructor. + constexpr int test3() { + int n = 3; + A* a = new A[n]{5, 1}; + int c = a[0].b + a[1].b + a[2].b; + delete[] a; + return c; + } + static_assert(test3() == (5 + 1 + 10)); + + constexpr int test4() { + auto n = 3; + int *a = new int[n]{12}; + int c = a[0] + a[1]; + delete[] a; + return c; + } + static_assert(test4() == 12); + + +} + #else /// Make sure we reject this prior to C++20 constexpr int a() { // both-error {{never produces a constant expression}} diff --git a/clang/test/AST/ByteCode/unions.cpp b/clang/test/AST/ByteCode/unions.cpp index e90b123c90de0..c6b5e34810f05 100644 --- a/clang/test/AST/ByteCode/unions.cpp +++ b/clang/test/AST/ByteCode/unions.cpp @@ -402,7 +402,6 @@ namespace UnionInBase { static_assert(return_uninit().a.x == 2); } -/// FIXME: Our diagnostic here is a little off. namespace One { struct A { long x; }; @@ -421,4 +420,69 @@ namespace One { // both-note {{constinit}} } +namespace CopyAssign { + union A { + int a; + int b; + }; + + constexpr int f() { + A a{12}; + A b{13}; + + b.b = 32; + b = a ; + return b.a; + } + static_assert(f()== 12); + + + constexpr int f2() { + A a{12}; + A b{13}; + + b.b = 32; + b = a ; + return b.b; // both-note {{read of member 'b' of union with active member 'a'}} + } + static_assert(f2() == 12); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} +} + +namespace MoveAssign { + union A { + int a; + int b; + }; + + constexpr int f() { + A b{13}; + + b = A{12} ; + return b.a; + } + static_assert(f()== 12); +} + +namespace IFD { + template + struct Optional { + struct { + union { + char null_state; + T val; + }; + }; + constexpr Optional() : null_state(){} + }; + + constexpr bool test() + { + Optional opt{}; + Optional opt2{}; + opt = opt2; + return true; + } + static_assert(test()); +} #endif diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index db3f2d405e686..11be67d45a14c 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -1,222 +1,222 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ -// RUN: -DRESOURCE=StructuredBuffer %s | FileCheck -DRESOURCE=StructuredBuffer \ -// RUN: -check-prefix=EMPTY %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ -// RUN: -DRESOURCE=StructuredBuffer %s | FileCheck -DRESOURCE=StructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-SUBSCRIPT,CHECK-LOAD %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ -// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \ -// RUN: -check-prefix=EMPTY %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ -// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-COUNTER,CHECK-LOAD %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ -// RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \ -// RUN: -check-prefix=EMPTY %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ -// RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-APPEND %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ -// RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ -// RUN: -check-prefix=EMPTY %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ -// RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-CONSUME %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ -// RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \ -// RUN: -check-prefix=EMPTY %s -// -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ -// RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT,CHECK-LOAD %s - -// This test tests two different AST generations for each structured buffer. -// The "EMPTY" test mode verifies the AST generated by forward declaration -// of the HLSL types which happens on initializing the HLSL external AST with -// an AST Context. - -// The non-empty mode has a use that requires the resource type be complete, -// which results in the AST being populated by the external AST source. That -// case covers the full implementation of the template declaration and the -// instantiated specialization. - -// EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <> implicit [[RESOURCE]] -// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <> typename depth 0 index 0 element_type -// EMPTY-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <> 'bool' Concept 0x{{[0-9A-Fa-f]+}} '__is_structured_resource_element_compatible' -// EMPTY-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> -// EMPTY-NEXT: TemplateArgument type 'type-parameter-0-0' -// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 -// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' -// EMPTY-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' -// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 -// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' -// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit class [[RESOURCE]] -// EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final - -// There should be no more occurrences of [[RESOURCE]] -// EMPTY-NOT: {{[^[:alnum:]]}}[[RESOURCE]] - -#ifndef EMPTY - -RESOURCE Buffer; - -#endif - -// CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <> implicit [[RESOURCE]] -// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <> typename depth 0 index 0 element_type -// CHECK-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <> 'bool' Concept 0x{{[0-9A-Fa-f]+}} '__is_structured_resource_element_compatible' -// CHECK-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> -// CHECK-NEXT: TemplateArgument type 'type-parameter-0-0' -// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 -// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' -// CHECK-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' -// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 -// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' -// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit class [[RESOURCE]] definition - -// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final -// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit __handle '__hlsl_resource_t -// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] -// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit RawBuffer - -// CHECK-SUBSCRIPT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'const element_type &(unsigned int) const' -// CHECK-SUBSCRIPT-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' -// CHECK-SUBSCRIPT-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-SUBSCRIPT-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-SUBSCRIPT-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow -// CHECK-SUBSCRIPT-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' -// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' -// CHECK-SUBSCRIPT-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::resource_class( -// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SUBSCRIPT-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} -// CHECK-SUBSCRIPT-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'const [[RESOURCE]]' lvalue implicit this -// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' -// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline - -// CHECK-SUBSCRIPT-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'element_type &(unsigned int)' -// CHECK-SUBSCRIPT-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' -// CHECK-SUBSCRIPT-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-SUBSCRIPT-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-SUBSCRIPT-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow -// CHECK-SUBSCRIPT-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' -// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' -// CHECK-SUBSCRIPT-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::resource_class( -// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SUBSCRIPT-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} -// CHECK-SUBSCRIPT-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this -// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' -// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline - -// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'const element_type &(unsigned int) const' -// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'element_type &(unsigned int)' - -// CHECK-LOAD: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Load 'element_type (unsigned int)' -// CHECK-LOAD-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' -// CHECK-LOAD-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-LOAD-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-LOAD-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow -// CHECK-LOAD-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' -// CHECK-LOAD-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' -// CHECK-LOAD-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-LOAD-SAME{LITERAL}: [[hlsl::resource_class( -// CHECK-LOAD-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-LOAD-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} -// CHECK-LOAD-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this -// CHECK-LOAD-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' -// CHECK-LOAD-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline - -// CHECK-COUNTER: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> IncrementCounter 'unsigned int ()' -// CHECK-COUNTER-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-COUNTER-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-COUNTER-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' -// CHECK-COUNTER-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' -// CHECK-COUNTER-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle -// CHECK-COUNTER-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'RWStructuredBuffer' lvalue implicit this -// CHECK-COUNTER-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' 1 -// CHECK-COUNTER-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline - -// CHECK-COUNTER-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> DecrementCounter 'unsigned int ()' -// CHECK-COUNTER-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-COUNTER-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-COUNTER-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' -// CHECK-COUNTER-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' -// CHECK-COUNTER-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle -// CHECK-COUNTER-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'RWStructuredBuffer' lvalue implicit this -// CHECK-COUNTER-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' -1 -// CHECK-COUNTER-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline - -// CHECK-APPEND: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Append 'void (element_type)' -// CHECK-APPEND-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> value 'element_type' -// CHECK-APPEND-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-APPEND-NEXT: BinaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' '=' -// CHECK-APPEND-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow -// CHECK-APPEND-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' -// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' -// CHECK-APPEND-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle -// CHECK-APPEND-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this -// CHECK-APPEND-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' -// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' -// CHECK-APPEND-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle -// CHECK-APPEND-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this -// CHECK-APPEND-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' 1 -// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type' ParmVar 0x{{[0-9A-Fa-f]+}} 'value' 'element_type' - -// CHECK-CONSUME: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Consume 'element_type ()' -// CHECK-CONSUME-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-CONSUME-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> -// CHECK-CONSUME-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow -// CHECK-CONSUME-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' -// CHECK-CONSUME-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' -// CHECK-CONSUME-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle -// CHECK-CONSUME-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this -// CHECK-CONSUME-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' -// CHECK-CONSUME-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' -// CHECK-CONSUME-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t -// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle -// CHECK-CONSUME-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this -// CHECK-CONSUME-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' -1 - -// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> class [[RESOURCE]] definition - -// CHECK: TemplateArgument type 'float' -// CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float' -// CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final -// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit __handle '__hlsl_resource_t -// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] -// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] -// CHECK-ROV-SAME{LITERAL}: [[hlsl::is_rov]] -// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] -// CHECK-SAME{LITERAL}: [[hlsl::contained_type(float)]] -// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit RawBuffer +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=StructuredBuffer %s | FileCheck -DRESOURCE=StructuredBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=StructuredBuffer %s | FileCheck -DRESOURCE=StructuredBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-SUBSCRIPT,CHECK-LOAD %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=RWStructuredBuffer %s | FileCheck -DRESOURCE=RWStructuredBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-SUBSCRIPT,CHECK-COUNTER,CHECK-LOAD %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-APPEND %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-CONSUME %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-ROV,CHECK-SUBSCRIPT,CHECK-LOAD %s + +// This test tests two different AST generations for each structured buffer. +// The "EMPTY" test mode verifies the AST generated by forward declaration +// of the HLSL types which happens on initializing the HLSL external AST with +// an AST Context. + +// The non-empty mode has a use that requires the resource type be complete, +// which results in the AST being populated by the external AST source. That +// case covers the full implementation of the template declaration and the +// instantiated specialization. + +// EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <> implicit [[RESOURCE]] +// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <> typename depth 0 index 0 element_type +// EMPTY-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <> 'bool' Concept 0x{{[0-9A-Fa-f]+}} '__is_structured_resource_element_compatible' +// EMPTY-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> +// EMPTY-NEXT: TemplateArgument type 'type-parameter-0-0' +// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} depth 0 index 0 +// EMPTY-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' +// EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' +// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit class [[RESOURCE]] +// EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final + +// There should be no more occurrences of [[RESOURCE]] +// EMPTY-NOT: {{[^[:alnum:]]}}[[RESOURCE]] + +#ifndef EMPTY + +RESOURCE Buffer; + +#endif + +// CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <> implicit [[RESOURCE]] +// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <> typename depth 0 index 0 element_type +// CHECK-NEXT: ConceptSpecializationExpr 0x{{[0-9A-Fa-f]+}} <> 'bool' Concept 0x{{[0-9A-Fa-f]+}} '__is_structured_resource_element_compatible' +// CHECK-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> +// CHECK-NEXT: TemplateArgument type 'type-parameter-0-0' +// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} depth 0 index 0 +// CHECK-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' +// CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' +// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit class [[RESOURCE]] definition + +// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final +// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit __handle '__hlsl_resource_t +// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit RawBuffer + +// CHECK-SUBSCRIPT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'const element_type &(unsigned int) const' +// CHECK-SUBSCRIPT-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' +// CHECK-SUBSCRIPT-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-SUBSCRIPT-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-SUBSCRIPT-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-SUBSCRIPT-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-SUBSCRIPT-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::resource_class( +// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SUBSCRIPT-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} +// CHECK-SUBSCRIPT-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'const [[RESOURCE]]' lvalue implicit this +// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' +// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline + +// CHECK-SUBSCRIPT-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'element_type &(unsigned int)' +// CHECK-SUBSCRIPT-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' +// CHECK-SUBSCRIPT-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-SUBSCRIPT-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-SUBSCRIPT-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-SUBSCRIPT-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-SUBSCRIPT-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::resource_class( +// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SUBSCRIPT-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} +// CHECK-SUBSCRIPT-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-SUBSCRIPT-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' +// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline + +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'const element_type &(unsigned int) const' +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'element_type &(unsigned int)' + +// CHECK-LOAD: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Load 'element_type (unsigned int)' +// CHECK-LOAD-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' +// CHECK-LOAD-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-LOAD-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-LOAD-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-LOAD-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-LOAD-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-LOAD-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-LOAD-SAME{LITERAL}: [[hlsl::resource_class( +// CHECK-LOAD-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-LOAD-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} +// CHECK-LOAD-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-LOAD-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' +// CHECK-LOAD-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline + +// CHECK-COUNTER: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> IncrementCounter 'unsigned int ()' +// CHECK-COUNTER-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-COUNTER-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-COUNTER-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' +// CHECK-COUNTER-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' +// CHECK-COUNTER-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-COUNTER-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'RWStructuredBuffer' lvalue implicit this +// CHECK-COUNTER-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' 1 +// CHECK-COUNTER-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline + +// CHECK-COUNTER-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> DecrementCounter 'unsigned int ()' +// CHECK-COUNTER-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-COUNTER-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-COUNTER-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' +// CHECK-COUNTER-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' +// CHECK-COUNTER-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-COUNTER-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> 'RWStructuredBuffer' lvalue implicit this +// CHECK-COUNTER-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' -1 +// CHECK-COUNTER-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline + +// CHECK-APPEND: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Append 'void (element_type)' +// CHECK-APPEND-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> value 'element_type' +// CHECK-APPEND-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-APPEND-NEXT: BinaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' '=' +// CHECK-APPEND-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-APPEND-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-APPEND-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-APPEND-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-APPEND-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' +// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' +// CHECK-APPEND-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-APPEND-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-APPEND-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' 1 +// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type' ParmVar 0x{{[0-9A-Fa-f]+}} 'value' 'element_type' + +// CHECK-CONSUME: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Consume 'element_type ()' +// CHECK-CONSUME-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-CONSUME-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-CONSUME-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-CONSUME-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-CONSUME-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-CONSUME-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-CONSUME-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-CONSUME-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' +// CHECK-CONSUME-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' +// CHECK-CONSUME-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-CONSUME-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-CONSUME-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' -1 + +// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> class [[RESOURCE]] definition + +// CHECK: TemplateArgument type 'float' +// CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float' +// CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final +// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit __handle '__hlsl_resource_t +// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-ROV-SAME{LITERAL}: [[hlsl::is_rov]] +// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(float)]] +// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit RawBuffer diff --git a/clang/test/AST/HLSL/TypdefArrayParam.hlsl b/clang/test/AST/HLSL/TypdefArrayParam.hlsl new file mode 100644 index 0000000000000..c6ae168f84064 --- /dev/null +++ b/clang/test/AST/HLSL/TypdefArrayParam.hlsl @@ -0,0 +1,57 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -x hlsl -ast-dump %s | FileCheck %s + +typedef uint4 uint32_t4; +typedef uint32_t4 uint32_t8[2]; + +// CHECK-LABEL: FunctionDecl {{.*}} used Accumulate 'uint32_t (uint32_t4[2])' +// CHECK-NEXT: ParmVarDecl {{.*}} used V 'uint32_t4[2]' +uint32_t Accumulate(uint32_t8 V) { + uint32_t4 SumVec = V[0] + V[1]; + return SumVec.x + SumVec.y + SumVec.z + SumVec.w; +} + +// CHECK-LABEL: FunctionDecl {{.*}} used InOutAccu 'void (inout uint32_t4[2])' +// CHECK-NEXT: ParmVarDecl {{.*}} used V 'uint32_t4[2]' +// CHECK-NEXT: HLSLParamModifierAttr {{.*}} inout +void InOutAccu(inout uint32_t8 V) { + uint32_t4 SumVec = V[0] + V[1]; + V[0] = SumVec; +} + +// CHECK-LABEL: call1 +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout uint32_t4[2])' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (inout uint32_t4[2])' lvalue Function {{.*}} 'InOutAccu' 'void (inout uint32_t4[2])' +// CHECK-NEXT: HLSLOutArgExpr {{.*}} 'uint32_t4[2]' lvalue inout +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue Var {{.*}} 'B' 'uint32_t8':'uint32_t4[2]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'uint32_t4[2]' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint32_t4[2]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue Var {{.*}} 'B' 'uint32_t8':'uint32_t4[2]' +// CHECK-NEXT: BinaryOperator {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue '=' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue Var {{.*}} 'B' 'uint32_t8':'uint32_t4[2]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint32_t4[2]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'uint32_t4[2]' lvalue +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint32_t4[2]' +// CHECK-NEXT: OpaqueValueExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} 'uint32_t8':'uint32_t4[2]' lvalue Var {{.*}} 'B' 'uint32_t8':'uint32_t4[2]' +void call1() { + uint32_t4 A = {1,2,3,4}; + uint32_t8 B = {A,A}; + InOutAccu(B); +} + +// CHECK-LABEL: call2 +// CHECK: VarDecl {{.*}} D 'uint32_t':'unsigned int' cinit +// CHECK-NEXT: CallExpr {{.*}} 'uint32_t':'unsigned int' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint32_t (*)(uint32_t4[2])' +// CHECK-NEXT: DeclRefExpr {{.*}} 'uint32_t (uint32_t4[2])' lvalue Function {{.*}} 'Accumulate' 'uint32_t (uint32_t4[2])' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'uint4[2]' +// CHECK-NEXT: DeclRefExpr {{.*}} 'uint4[2]' lvalue Var {{.*}} 'C' 'uint4[2]' +void call2() { + uint4 A = {1,2,3,4}; + uint4 C[2] = {A,A}; + uint32_t D = Accumulate(C); +} diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index d6dfb0caba5d9..406ff07d0cf62 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -23,7 +23,7 @@ // EMPTY-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> // EMPTY-NEXT: TemplateArgument type 'type-parameter-0-0' // EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 -// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' +// EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} depth 0 index 0 // EMPTY-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' // EMPTY-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 // EMPTY-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' @@ -45,7 +45,7 @@ RESOURCE Buffer; // CHECK-NEXT: ImplicitConceptSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> // CHECK-NEXT: TemplateArgument type 'type-parameter-0-0' // CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'type-parameter-0-0' dependent depth 0 index 0 -// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} '' +// CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} depth 0 index 0 // CHECK-NEXT: TemplateArgument type 'element_type':'type-parameter-0-0' // CHECK-NEXT: TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'element_type' dependent depth 0 index 0 // CHECK-NEXT: TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'element_type' diff --git a/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl b/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl deleted file mode 100644 index 0bff3ae144037..0000000000000 --- a/clang/test/AST/HLSL/ast-dump-comment-cbuffer-tbuffer.hlsl +++ /dev/null @@ -1,62 +0,0 @@ -// RUN: %clang_cc1 -Wdocumentation -ast-dump=json -x hlsl -triple dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefix=JSON -// RUN: %clang_cc1 -Wdocumentation -ast-dump -x hlsl -triple dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefix=AST - -// JSON:"kind": "HLSLBufferDecl", -// JSON:"name": "A", -// JSON-NEXT:"bufferKind": "cbuffer", -// JSON:"kind": "TextComment", -// JSON:"text": " CBuffer decl." - -/// CBuffer decl. -cbuffer A { - // JSON: "kind": "VarDecl", - // JSON: "name": "a", - // JSON: "qualType": "float" - float a; - // JSON: "kind": "VarDecl", - // JSON: "name": "b", - // JSON: "qualType": "int" - int b; -} - -// JSON:"kind": "HLSLBufferDecl", -// JSON:"name": "B", -// JSON-NEXT:"bufferKind": "tbuffer", -// JSON:"kind": "TextComment", -// JSON:"text": " TBuffer decl." - -/// TBuffer decl. -tbuffer B { - // JSON: "kind": "VarDecl", - // JSON: "name": "c", - // JSON: "qualType": "float" - float c; - // JSON: "kind": "VarDecl", - // JSON: "name": "d", - // JSON: "qualType": "int" - int d; -} - -// AST: HLSLBufferDecl {{.*}} line:11:9 cbuffer A -// AST-NEXT: HLSLResourceClassAttr {{.*}} Implicit CBuffer -// AST-NEXT: HLSLResourceAttr {{.*}} Implicit CBuffer -// AST-NEXT: FullComment -// AST-NEXT: ParagraphComment -// AST-NEXT: TextComment {{.*}} Text=" CBuffer decl." -// AST-NEXT: VarDecl {{.*}} a 'float' -// AST-NEXT: VarDecl {{.*}} b 'int' -// AST-NEXT: CXXRecordDecl {{.*}} implicit class __layout_A definition -// AST: FieldDecl {{.*}} a 'float' -// AST-NEXT: FieldDecl {{.*}} b 'int' - -// AST-NEXT: HLSLBufferDecl {{.*}} line:29:9 tbuffer B -// AST-NEXT: HLSLResourceClassAttr {{.*}} Implicit SRV -// AST-NEXT: HLSLResourceAttr {{.*}} Implicit TBuffer -// AST-NEXT: FullComment -// AST-NEXT: ParagraphComment -// AST-NEXT: TextComment {{.*}} Text=" TBuffer decl." -// AST-NEXT: VarDecl {{.*}} c 'float' -// AST-NEXT: VarDecl {{.*}} d 'int' -// AST-NEXT: CXXRecordDecl {{.*}} implicit class __layout_B definition -// AST: FieldDecl {{.*}} c 'float' -// AST-NEXT: FieldDecl {{.*}} d 'int' diff --git a/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl b/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl new file mode 100644 index 0000000000000..eca2ed0211d1b --- /dev/null +++ b/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -Wdocumentation -ast-dump=json -x hlsl -triple dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefix=JSON +// RUN: %clang_cc1 -Wdocumentation -ast-dump -x hlsl -triple dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefix=AST + +// JSON:"kind": "HLSLBufferDecl", +// JSON:"name": "A", +// JSON-NEXT:"bufferKind": "cbuffer", +// JSON:"kind": "TextComment", +// JSON:"text": " CBuffer decl." + +/// CBuffer decl. +cbuffer A { + // JSON: "kind": "VarDecl", + // JSON: "name": "a", + // JSON: "qualType": "hlsl_constant float" + float a; + // JSON: "kind": "VarDecl", + // JSON: "name": "b", + // JSON: "qualType": "hlsl_constant int" + int b; +} + +// AST: HLSLBufferDecl {{.*}} line:11:9 cbuffer A +// AST-NEXT: HLSLResourceClassAttr {{.*}} Implicit CBuffer +// AST-NEXT: HLSLResourceAttr {{.*}} Implicit CBuffer +// AST-NEXT: FullComment +// AST-NEXT: ParagraphComment +// AST-NEXT: TextComment {{.*}} Text=" CBuffer decl." +// AST-NEXT: VarDecl {{.*}} a 'hlsl_constant float' +// AST-NEXT: VarDecl {{.*}} b 'hlsl_constant int' diff --git a/clang/test/AST/HLSL/cbuffer.hlsl b/clang/test/AST/HLSL/cbuffer.hlsl index 721abb290f163..9946fda2355b2 100644 --- a/clang/test/AST/HLSL/cbuffer.hlsl +++ b/clang/test/AST/HLSL/cbuffer.hlsl @@ -48,94 +48,108 @@ struct TwoFloats { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} col:9 used a1 'float' + // CHECK: VarDecl {{.*}} used a1 'hlsl_constant float' float a1; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB definition - // CHECK: FieldDecl {{.*}} a1 'float' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} a1 'float' } -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __layout_CB), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __cblayout_CB), ""); // Check that buffer layout struct does not include resources or empty types -// CHECK: HLSLBufferDecl {{.*}} line:62:9 cbuffer CB +// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} col:9 used a2 'float' + // CHECK: VarDecl {{.*}} used a2 'hlsl_constant float' float a2; - // CHECK: VarDecl {{.*}} col:19 b2 'RWBuffer':'hlsl::RWBuffer' + // CHECK: VarDecl {{.*}} b2 'RWBuffer':'hlsl::RWBuffer' RWBuffer b2; - // CHECK: VarDecl {{.*}} col:15 c2 'EmptyStruct' + // CHECK: VarDecl {{.*}} c2 'EmptyStruct' EmptyStruct c2; - // CHECK: VarDecl {{.*}} col:9 d2 'float[0]' + // CHECK: VarDecl {{.*}} d2 'float[0]' float d2[0]; - // CHECK: VarDecl {{.*}} col:9 e2 'float' + // CHECK: VarDecl {{.*}} f2 'RWBuffer[2]' + RWBuffer f2[2]; + // CHECK: VarDecl {{.*}} g2 'groupshared float' + groupshared float g2; + // CHECK: VarDecl {{.*}} h2 '__hlsl_resource_t' + __hlsl_resource_t h2; + // CHECK: VarDecl {{.*}} e2 'hlsl_constant float' float e2; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_1 definition - // CHECK: FieldDecl {{.*}} a2 'float' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_1 definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} a2 'float' // CHECK-NEXT: FieldDecl {{.*}} e2 'float' } -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __layout_CB_1), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __cblayout_CB_1), ""); // Check that layout struct is created for B and the empty struct C is removed -// CHECK: HLSLBufferDecl {{.*}} line:83:9 cbuffer CB +// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} col:5 used s1 'A' + // CHECK: VarDecl {{.*}} used s1 'hlsl_constant A' A s1; - // CHECK: VarDecl {{.*}} col:5 s2 'B' + // CHECK: VarDecl {{.*}} s2 'hlsl_constant B' B s2; - // CHECK: VarDecl {{.*}} col:12 s3 'CTypedef':'C + // CHECK: VarDecl {{.*}} s3 'CTypedef':'C' CTypedef s3; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_2 definition - // CHECK: FieldDecl {{.*}} s1 'A' - // CHECK: FieldDecl {{.*}} s2 '__layout_B' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_2 definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} s1 'A' + // CHECK-NEXT: FieldDecl {{.*}} s2 '__cblayout_B' } -// CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_B definition -// CHECK: FieldDecl {{.*}} a 'float' +// CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_B definition +// CHECK: PackedAttr +// CHECK-NEXT: FieldDecl {{.*}} a 'float' -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __layout_B), ""); -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __layout_CB_2), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __cblayout_B), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __cblayout_CB_2), ""); // check that layout struct is created for D because of its base struct -// CHECK: HLSLBufferDecl {{.*}} line:104:9 cbuffer CB +// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} s4 'D' + // CHECK: VarDecl {{.*}} s4 'hlsl_constant D' D s4; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_3 definition - // CHECK: FieldDecl {{.*}} s4 '__layout_D' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_3 definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} s4 '__cblayout_D' } - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_D definition - // CHECK: public '__layout_B' - // CHECK: FieldDecl {{.*}} b 'float' -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __layout_D), ""); -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __layout_CB_3), ""); + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_D definition + // CHECK: public '__cblayout_B' + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} b 'float' +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __cblayout_D), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __cblayout_CB_3), ""); // check that layout struct is created for E because because its base struct // is empty and should be eliminated, and BTypedef should reuse the previously -// defined '__layout_B' -// CHECK: HLSLBufferDecl {{.*}} line:122:9 cbuffer CB +// defined '__cblayout_B' +// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} s5 'E' + // CHECK: VarDecl {{.*}} s5 'hlsl_constant E' E s5; - // CHECK: VarDecl {{.*}} s6 'BTypedef':'B' + // CHECK: VarDecl {{.*}} s6 'hlsl_constant BTypedef':'hlsl_constant B' BTypedef s6; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_4 definition - // CHECK: FieldDecl {{.*}} s5 '__layout_E' - // CHECK: FieldDecl {{.*}} s6 '__layout_B' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_4 definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} s5 '__cblayout_E' + // CHECK-NEXT: FieldDecl {{.*}} s6 '__cblayout_B' } - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_E definition - // CHECK: FieldDecl {{.*}} c 'float' - // CHECK-NOT: CXXRecordDecl {{.*}} class __layout_B definition -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __layout_E), ""); -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __layout_CB_4), ""); +// CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_E definition +// CHECK: PackedAttr +// CHECK-NEXT: FieldDecl {{.*}} c 'float' +// CHECK-NOT: CXXRecordDecl {{.*}} struct __cblayout_B definition +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __cblayout_E), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __cblayout_CB_4), ""); // check that this produces empty layout struct -// CHECK: HLSLBufferDecl {{.*}} line:141:9 cbuffer CB +// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { @@ -149,27 +163,30 @@ cbuffer CB { RWBuffer Buf; // CHECK: VarDecl {{.*}} ea 'EmptyArrayTypedef':'float[10][0]' EmptyArrayTypedef ea; - // CHECK: CXXRecordDecl {{.*}} implicit class __layout_CB_5 definition + // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_CB_5 definition + // CHECK: PackedAttr // CHECK-NOT: FieldDecl } // check host layout struct with compatible base struct -// CHECK: HLSLBufferDecl {{.*}} line:160:9 cbuffer CB +// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { - // CHECK: VarDecl {{.*}} s8 'F' + // CHECK: VarDecl {{.*}} s8 'hlsl_constant F' F s8; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_6 definition - // CHECK: FieldDecl {{.*}} s8 '__layout_F' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_6 definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} s8 '__cblayout_F' } - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_F definition - // CHECK: public 'A' -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __layout_F), ""); -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __layout_CB_6), ""); +// CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_F definition +// CHECK: public 'A' +// CHECK: PackedAttr +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __cblayout_F), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __cblayout_CB_6), ""); // anonymous structs -// CHECK: HLSLBufferDecl {{.*}} line:175:9 cbuffer CB +// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB { @@ -182,7 +199,7 @@ cbuffer CB { // CHECK: FieldDecl {{.*}} f 'RWBuffer':'hlsl::RWBuffer' RWBuffer f; } s9; - // CHECK: VarDecl {{.*}} s9 'struct (unnamed struct at {{.*}}cbuffer.hlsl:177:3 + // CHECK: VarDecl {{.*}} s9 'hlsl_constant struct (unnamed struct at {{.*}}cbuffer.hlsl:[[# @LINE - 8]]:3 // CHECK: CXXRecordDecl {{.*}} struct definition struct { // CHECK: FieldDecl {{.*}} g 'float' @@ -190,18 +207,21 @@ cbuffer CB { // CHECK: FieldDecl {{.*}} f 'RWBuffer':'hlsl::RWBuffer' RWBuffer f; } s10; - // CHECK: VarDecl {{.*}} s10 'struct (unnamed struct at {{.*}}cbuffer.hlsl:187:3 - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_anon definition - // CHECK: FieldDecl {{.*}} e 'float' - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_anon_1 definition - // CHECK: FieldDecl {{.*}} g 'float' - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_7 definition - // CHECK: FieldDecl {{.*}} s9 '__layout_anon' - // CHECK: FieldDecl {{.*}} s10 '__layout_anon_1' + // CHECK: VarDecl {{.*}} s10 'hlsl_constant struct (unnamed struct at {{.*}}cbuffer.hlsl:[[# @LINE - 6]]:3 + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_anon definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} e 'float' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_anon_1 definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} g 'float' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_7 definition + // CHECK: PackedAttr + // CHECK-NEXT: FieldDecl {{.*}} s9 '__cblayout_anon' + // CHECK-NEXT: FieldDecl {{.*}} s10 '__cblayout_anon_1' } -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __layout_anon), ""); -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __layout_anon_1), ""); -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __layout_CB_7), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __cblayout_anon), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, __cblayout_anon_1), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, __cblayout_CB_7), ""); // Add uses for the constant buffer declarations so they are not optimized away export float foo() { diff --git a/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl b/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl index 4b1bbea736f85..09596eda90b6a 100644 --- a/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl +++ b/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl @@ -19,10 +19,10 @@ namespace NS1 { int b; EmptyStruct es; }; - // CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition + // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition // CHECK: FieldDecl {{.*}} b 'int' }; - // CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition + // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition // CHECK: FieldDecl {{.*}} a 'float' } @@ -35,18 +35,18 @@ struct Foo { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB1 { - // CHECK: VarDecl {{.*}} foo1 'Foo' + // CHECK: VarDecl {{.*}} foo1 'hlsl_constant Foo' Foo foo1; - // CHECK: VarDecl {{.*}} foo2 'NS1::Foo' + // CHECK: VarDecl {{.*}} foo2 'hlsl_constant NS1::Foo' NS1::Foo foo2; - // CHECK: VarDecl {{.*}} foo3 'NS1::Bar::Foo' + // CHECK: VarDecl {{.*}} foo3 'hlsl_constant NS1::Bar::Foo' NS1::Bar::Foo foo3; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB1 definition - // CHECK: FieldDecl {{.*}} foo1 '__layout_Foo' - // CHECK: FieldDecl {{.*}} foo2 'NS1::__layout_Foo' - // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__layout_Foo' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB1 definition + // CHECK: FieldDecl {{.*}} foo1 '__cblayout_Foo' + // CHECK: FieldDecl {{.*}} foo2 'NS1::__cblayout_Foo' + // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__cblayout_Foo' } -// CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition +// CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition // CHECK: FieldDecl {{.*}} c 'double' struct CB1ExpectedShape { @@ -54,7 +54,7 @@ struct CB1ExpectedShape { float a2; int a; }; -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB1ExpectedShape, __layout_CB1), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB1ExpectedShape, __cblayout_CB1), ""); namespace NS2 { struct Foo { @@ -65,21 +65,21 @@ namespace NS2 { // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer cbuffer CB2 { - // CHECK: VarDecl {{.*}} foo0 '::Foo':'Foo' + // CHECK: VarDecl {{.*}} foo0 'hlsl_constant ::Foo':'hlsl_constant Foo' ::Foo foo0; - // CHECK: VarDecl {{.*}} foo1 'Foo':'NS2::Foo' + // CHECK: VarDecl {{.*}} foo1 'hlsl_constant Foo':'hlsl_constant NS2::Foo' Foo foo1; - // CHECK: VarDecl {{.*}} foo2 'NS1::Foo' + // CHECK: VarDecl {{.*}} foo2 'hlsl_constant NS1::Foo' NS1::Foo foo2; - // CHECK: VarDecl {{.*}} foo3 'NS1::Bar::Foo' + // CHECK: VarDecl {{.*}} foo3 'hlsl_constant NS1::Bar::Foo' NS1::Bar::Foo foo3; - // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB2 definition - // CHECK: FieldDecl {{.*}} foo0 '__layout_Foo' - // CHECK: FieldDecl {{.*}} foo1 'NS2::__layout_Foo' - // CHECK: FieldDecl {{.*}} foo2 'NS1::__layout_Foo' - // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__layout_Foo' + // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB2 definition + // CHECK: FieldDecl {{.*}} foo0 '__cblayout_Foo' + // CHECK: FieldDecl {{.*}} foo1 'NS2::__cblayout_Foo' + // CHECK: FieldDecl {{.*}} foo2 'NS1::__cblayout_Foo' + // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__cblayout_Foo' } - // CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition + // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition // CHECK: FieldDecl {{.*}} d 'float[4]' } @@ -89,7 +89,7 @@ struct CB2ExpectedShape { float a2; int a; }; -_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB2ExpectedShape, NS2::__layout_CB2), ""); +_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB2ExpectedShape, NS2::__cblayout_CB2), ""); // Add uses for the constant buffer declarations so they are not optimized away // CHECK: ExportDecl diff --git a/clang/test/AST/HLSL/packoffset.hlsl b/clang/test/AST/HLSL/packoffset.hlsl index 9c928bd6d922e..a9bb90bb386f9 100644 --- a/clang/test/AST/HLSL/packoffset.hlsl +++ b/clang/test/AST/HLSL/packoffset.hlsl @@ -6,13 +6,13 @@ cbuffer A { // CHECK-NEXT:-HLSLResourceClassAttr {{.*}} <> Implicit CBuffer // CHECK-NEXT:-HLSLResourceAttr {{.*}} <> Implicit CBuffer - // CHECK-NEXT: VarDecl {{.*}} A1 'float4' + // CHECK-NEXT: VarDecl {{.*}} A1 'hlsl_constant float4' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 0 float4 A1 : packoffset(c); - // CHECK-NEXT: VarDecl {{.*}} col:11 A2 'float' + // CHECK-NEXT: VarDecl {{.*}} col:11 A2 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 0 float A2 : packoffset(c1); - // CHECK-NEXT: VarDecl {{.*}} col:11 A3 'float' + // CHECK-NEXT: VarDecl {{.*}} col:11 A3 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 1 float A3 : packoffset(c1.y); } @@ -20,13 +20,13 @@ cbuffer A // CHECK: HLSLBufferDecl {{.*}} cbuffer B cbuffer B { - // CHECK: VarDecl {{.*}} B0 'float' + // CHECK: VarDecl {{.*}} B0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 1 float B0 : packoffset(c0.g); - // CHECK-NEXT: VarDecl {{.*}} B1 'double' + // CHECK-NEXT: VarDecl {{.*}} B1 'hlsl_constant double' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 2 double B1 : packoffset(c0.b); - // CHECK-NEXT: VarDecl {{.*}} B2 'half' + // CHECK-NEXT: VarDecl {{.*}} B2 'hlsl_constant half' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 0 half B2 : packoffset(c0.r); } @@ -34,13 +34,13 @@ cbuffer B // CHECK: HLSLBufferDecl {{.*}} cbuffer C cbuffer C { - // CHECK: VarDecl {{.*}} C0 'float' + // CHECK: VarDecl {{.*}} C0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 float C0 : packoffset(c0.y); - // CHECK-NEXT: VarDecl {{.*}} C1 'float2' + // CHECK-NEXT: VarDecl {{.*}} C1 'hlsl_constant float2' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 2 float2 C1 : packoffset(c0.z); - // CHECK-NEXT: VarDecl {{.*}} C2 'half' + // CHECK-NEXT: VarDecl {{.*}} C2 'hlsl_constant half' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 half C2 : packoffset(c0.x); } @@ -49,16 +49,16 @@ cbuffer C // CHECK: HLSLBufferDecl {{.*}} cbuffer D cbuffer D { - // CHECK: VarDecl {{.*}} D0 'float' + // CHECK: VarDecl {{.*}} D0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 1 float D0 : packoffset(c0.y); - // CHECK-NEXT: VarDecl {{.*}} D1 'float[2]' + // CHECK-NEXT: VarDecl {{.*}} D1 'hlsl_constant float[2]' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 1 0 float D1[2] : packoffset(c1.x); - // CHECK-NEXT: VarDecl {{.*}} D2 'half3' + // CHECK-NEXT: VarDecl {{.*}} D2 'hlsl_constant half3' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 2 1 half3 D2 : packoffset(c2.y); - // CHECK-NEXT: VarDecl {{.*}} D3 'double' + // CHECK-NEXT: VarDecl {{.*}} D3 'hlsl_constant double' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 2 double D3 : packoffset(c0.z); } @@ -71,13 +71,13 @@ struct ST { // CHECK: HLSLBufferDecl {{.*}} cbuffer S cbuffer S { - // CHECK: VarDecl {{.*}} S0 'float' + // CHECK: VarDecl {{.*}} S0 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 1 float S0 : packoffset(c0.y); - // CHECK: VarDecl {{.*}} S1 'ST' + // CHECK: VarDecl {{.*}} S1 'hlsl_constant ST' // CHECK: HLSLPackOffsetAttr {{.*}} 1 0 ST S1 : packoffset(c1); - // CHECK: VarDecl {{.*}} S2 'double2' + // CHECK: VarDecl {{.*}} S2 'hlsl_constant double2' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 2 0 double2 S2 : packoffset(c2); } @@ -90,13 +90,13 @@ struct ST2 { // CHECK: HLSLBufferDecl {{.*}} cbuffer S2 cbuffer S2 { - // CHECK: VarDecl {{.*}} S20 'float' + // CHECK: VarDecl {{.*}} S20 'hlsl_constant float' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 0 3 float S20 : packoffset(c0.a); - // CHECK: VarDecl {{.*}} S21 'ST2' + // CHECK: VarDecl {{.*}} S21 'hlsl_constant ST2' // CHECK: HLSLPackOffsetAttr {{.*}} 1 0 ST2 S21 : packoffset(c1); - // CHECK: VarDecl {{.*}} S22 'half' + // CHECK: VarDecl {{.*}} S22 'hlsl_constant half' // CHECK-NEXT: HLSLPackOffsetAttr {{.*}} 3 1 half S22 : packoffset(c3.y); } diff --git a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl index 3eabbb1f8ae22..754948931ee53 100644 --- a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl +++ b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl @@ -20,15 +20,15 @@ float foo() { // CHECK: HLSLBufferDecl {{.*}} line:7:9 imported cbuffer A // CHECK-NEXT: HLSLResourceClassAttr {{.*}} Implicit CBuffer // CHECK-NEXT: HLSLResourceAttr {{.*}} Implicit CBuffer -// CHECK-NEXT: VarDecl 0x[[A:[0-9a-f]+]] {{.*}} imported used a 'float' -// CHECK-NEXT: CXXRecordDecl {{.*}} imported implicit class __layout_A definition +// CHECK-NEXT: VarDecl 0x[[A:[0-9a-f]+]] {{.*}} imported used a 'hlsl_constant float' +// CHECK-NEXT: CXXRecordDecl {{.*}} imported implicit struct __cblayout_A definition // CHECK: FieldDecl {{.*}} imported a 'float' // CHECK: HLSLBufferDecl {{.*}} line:11:9 imported tbuffer B // CHECK-NEXT: HLSLResourceClassAttr {{.*}} Implicit SRV // CHECK-NEXT: HLSLResourceAttr {{.*}} Implicit TBuffer -// CHECK-NEXT: VarDecl 0x[[B:[0-9a-f]+]] {{.*}} imported used b 'float' -// CHECK-NEXT: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} imported implicit class __layout_B definition +// CHECK-NEXT: VarDecl 0x[[B:[0-9a-f]+]] {{.*}} imported used b 'hlsl_constant float' +// CHECK-NEXT: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} imported implicit struct __cblayout_B definition // CHECK: FieldDecl 0x{{[0-9a-f]+}} {{.*}} imported b 'float' // CHECK-NEXT: FunctionDecl {{.*}} line:15:7 imported foo 'float ()' @@ -36,6 +36,6 @@ float foo() { // CHECK-NEXT: ReturnStmt {{.*}} // CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' -// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue Var 0x[[A]] 'a' 'float' +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl_constant float' lvalue Var 0x[[A]] 'a' 'hlsl_constant float' // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' -// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue Var 0x[[B]] 'b' 'float' +// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl_constant float' lvalue Var 0x[[B]] 'b' 'hlsl_constant float' diff --git a/clang/test/AST/HLSL/resource_binding_attr.hlsl b/clang/test/AST/HLSL/resource_binding_attr.hlsl index 13957ad3c1fcc..6fac903f75e18 100644 --- a/clang/test/AST/HLSL/resource_binding_attr.hlsl +++ b/clang/test/AST/HLSL/resource_binding_attr.hlsl @@ -4,7 +4,7 @@ // CHECK-NEXT:HLSLResourceClassAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit CBuffer // CHECK-NEXT:HLSLResourceAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit CBuffer // CHECK-NEXT:HLSLResourceBindingAttr 0x{{[0-9a-f]+}} "b3" "space2" -// CHECK-NEXT:VarDecl 0x[[A:[0-9a-f]+]] {{.*}} col:9 used a 'float' +// CHECK-NEXT:VarDecl 0x[[A:[0-9a-f]+]] {{.*}} col:9 used a 'hlsl_constant float' cbuffer CB : register(b3, space2) { float a; } @@ -13,7 +13,7 @@ cbuffer CB : register(b3, space2) { // CHECK-NEXT:HLSLResourceClassAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit SRV // CHECK-NEXT:HLSLResourceAttr 0x[[CB:[0-9a-f]+]] {{.*}} Implicit TBuffer // CHECK-NEXT:HLSLResourceBindingAttr 0x{{[0-9a-f]+}} "t2" "space1" -// CHECK-NEXT:VarDecl 0x[[B:[0-9a-f]+]] {{.*}} col:9 used b 'float' +// CHECK-NEXT:VarDecl 0x[[B:[0-9a-f]+]] {{.*}} col:9 used b 'hlsl_constant float' tbuffer TB : register(t2, space1) { float b; } @@ -21,9 +21,9 @@ tbuffer TB : register(t2, space1) { float foo() { // CHECK: BinaryOperator 0x{{[0-9a-f]+}} 'float' '+' // CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-f]+}} 'float' -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} 'float' lvalue Var 0x[[A]] 'a' 'float' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} 'hlsl_constant float' lvalue Var 0x[[A]] 'a' 'hlsl_constant float' // CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-f]+}} 'float' -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} 'float' lvalue Var 0x[[B]] 'b' 'float' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-f]+}} 'hlsl_constant float' lvalue Var 0x[[B]] 'b' 'hlsl_constant float' return a + b; } diff --git a/clang/test/AST/ast-dump-APValue-lvalue.cpp b/clang/test/AST/ast-dump-APValue-lvalue.cpp new file mode 100644 index 0000000000000..224caddb3eabe --- /dev/null +++ b/clang/test/AST/ast-dump-APValue-lvalue.cpp @@ -0,0 +1,50 @@ +// Test without serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -ast-dump %s -ast-dump-filter Test \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s +// +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \ +// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --match-full-lines %s + +int i; +struct S { + int i; + int ii; +}; +S s; + +struct F { + char padding[12]; + S s; +}; +F f; + +void Test(int (&arr)[10]) { + constexpr int *pi = &i; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} pi 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=0, HasPath=1, PathLength=0, Path=() + + constexpr int *psi = &s.i; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} psi 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=0, HasPath=1, PathLength=1, Path=({{.*}}) + + constexpr int *psii = &s.ii; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} psii 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=4, HasPath=1, PathLength=1, Path=({{.*}}) + + constexpr int *pf = &f.s.ii; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} pf 'int *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=16, HasPath=1, PathLength=2, Path=({{.*}}, {{.*}}) + + constexpr char *pc = &f.padding[2]; + // CHECK: | `-VarDecl {{.*}} col:{{.*}} pc 'char *const' constexpr cinit + // CHECK-NEXT: | |-value: LValue Base=VarDecl {{.*}}, Null=0, Offset=2, HasPath=1, PathLength=2, Path=({{.*}}, 2) + + constexpr const int *n = nullptr; + // CHECK: `-VarDecl {{.*}} col:{{.*}} n 'const int *const' constexpr cinit + // CHECK-NEXT: |-value: LValue Base=null, Null=1, Offset=0, HasPath=1, PathLength=0, Path=() +} diff --git a/clang/test/AST/ast-dump-APValue-todo.cpp b/clang/test/AST/ast-dump-APValue-todo.cpp index 78cc9cf36c73c..acaa82ba53b6f 100644 --- a/clang/test/AST/ast-dump-APValue-todo.cpp +++ b/clang/test/AST/ast-dump-APValue-todo.cpp @@ -16,10 +16,6 @@ struct S { }; void Test() { - constexpr int *pi = &i; - // CHECK: | `-VarDecl {{.*}} col:{{.*}} pi 'int *const' constexpr cinit - // CHECK-NEXT: | |-value: LValue - constexpr int(S::*pmi) = &S::i; // CHECK: `-VarDecl {{.*}} col:{{.*}} pmi 'int (S::*const)' constexpr cinit // CHECK-NEXT: |-value: MemberPointer diff --git a/clang/test/AST/ast-dump-binding-pack.cpp b/clang/test/AST/ast-dump-binding-pack.cpp new file mode 100644 index 0000000000000..81c75a1268730 --- /dev/null +++ b/clang/test/AST/ast-dump-binding-pack.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_cc1 -ast-dump -std=c++26 %s | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -std=c++26 -emit-pch -o %t %s +// RUN: %clang_cc1 %s -std=c++26 -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +template +void foo() { + int arr[4] = {1, 2, 3, 4}; + auto [binding_1, ...binding_rest, binding_4] = arr; + int arr_2[] = {binding_rest...}; +}; + +// CHECK-LABEL: FunctionTemplateDecl {{.*}} foo +// CHECK-LABEL: BindingDecl {{.*}} binding_1 +// CHECK-NEXT: ArraySubscriptExpr {{.*}} +// CHECK-NEXT: ImplicitCastExpr +// CHECK-NEXT: DeclRefExpr {{.*}} +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 0 +// CHECK-NOT: BindingDecl +// CHECK-LABEL: BindingDecl {{.*}} binding_rest +// CHECK-NEXT: ResolvedUnexpandedPackExpr +// CHECK-NEXT: DeclRefExpr {{.*}} lvalue Binding {{.*}} 'binding_rest' +// CHECK-NEXT: DeclRefExpr {{.*}} lvalue Binding {{.*}} 'binding_rest' +// CHECK-NOT: BindingDecl +// CHECK-LABEL: BindingDecl {{.*}} binding_4 +// CHECK-NEXT: ArraySubscriptExpr +// CHECK-NEXT: ImplicitCastExpr {{.*}} +// CHECK-NEXT: DeclRefExpr {{.*}} lvalue Decomposition {{.*}} +// CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3 +// CHECK-NOT: BindingDecl +// CHECK-LABEL: VarDecl {{.*}} arr_2 +// CHECK-NEXT: InitListExpr +// CHECK-NEXT: PackExpansionExpr {{.*}} '' lvalue +// CHECK-NEXT: DeclRefExpr {{.*}} lvalue Binding {{.*}} 'binding_rest' + +struct tag_t { }; +template +void bar() { + auto [...empty_binding_pack] = tag_t{}; + static_assert(sizeof...(empty_binding_pack) == 0); +}; + +// CHECK-LABEL: FunctionTemplateDecl {{.*}} bar +// CHECK-NOT: BindingDecl +// CHECK-LABEL: BindingDecl {{.*}} empty_binding_pack +// CHECK-NEXT: ResolvedUnexpandedPackExpr +// CHECK-NOT: DeclRefExpr {{.*}} 'empty_binding_pack' +// CHECK-NOT: BindingDecl +// CHECK: DeclStmt + +struct int_pair { int x; int y; }; +template +void baz() { + auto [binding_1, binding_2, ...empty_binding_pack] = T{}; + static_assert(sizeof...(empty_binding_pack) == 0); +}; + +void(*f)() = baz; + +// CHECK-LABEL: FunctionDecl {{.*}} baz {{.*}} implicit_instantiation +// CHECK-NEXT: TemplateArgument type 'int_pair' +// CHECK: BindingDecl {{.*}} binding_1 +// CHECK: BindingDecl {{.*}} binding_2 +// CHECK-NOT: BindingDecl +// CHECK-LABEL: BindingDecl {{.*}} empty_binding_pack +// CHECK-NEXT: ResolvedUnexpandedPackExpr +// CHECK-NOT: DeclRefExpr {{.*}} 'empty_binding_pack' +// CHECK-NOT: BindingDecl +// CHECK: DeclStmt +#endif diff --git a/clang/test/AST/ast-dump-comment.cpp b/clang/test/AST/ast-dump-comment.cpp index 9798295b420f9..40c3edb62821b 100644 --- a/clang/test/AST/ast-dump-comment.cpp +++ b/clang/test/AST/ast-dump-comment.cpp @@ -91,6 +91,19 @@ int Test_HTMLTagComment; // CHECK-NEXT: TextComment{{.*}} Text=" " // CHECK-NEXT: HTMLStartTagComment{{.*}} Name="br" SelfClosing +/// Aaab +int Test_HTMLTagMultilineBCPL; +// CHECK: VarDecl{{.*}}Test_HTMLTagMultilineBCPL +// CHECK-NEXT: FullComment +// CHECK-NEXT: ParagraphComment +// CHECK-NEXT: TextComment{{.*}} Text=" " +// CHECK-NEXT: HTMLStartTagComment{{.*}} Name="a" Attrs: "href="foo" +// CHECK-NEXT: TextComment{{.*}} Text="Aaa" +// CHECK-NEXT: HTMLEndTagComment{{.*}} Name="a" +// CHECK-NEXT: TextComment{{.*}} Text="b" + /// \verbatim /// Aaa /// \endverbatim diff --git a/clang/test/AST/ast-dump-decl.c b/clang/test/AST/ast-dump-decl.c index 28b58c8eb648c..683df50f7e91c 100644 --- a/clang/test/AST/ast-dump-decl.c +++ b/clang/test/AST/ast-dump-decl.c @@ -121,7 +121,7 @@ struct testIndirectFieldDecl { }; }; // CHECK: IndirectFieldDecl{{.*}} TestIndirectFieldDecl 'int' -// CHECK-NEXT: Field{{.*}} '' +// CHECK-NEXT: Field{{.*}} field_index 0 // CHECK-NEXT: Field{{.*}} 'TestIndirectFieldDecl' // FIXME: It would be nice to dump the enum and its enumerators. diff --git a/clang/test/AST/ast-dump-records.c b/clang/test/AST/ast-dump-records.c index c0fbac67bc491..f4a540f3fa872 100644 --- a/clang/test/AST/ast-dump-records.c +++ b/clang/test/AST/ast-dump-records.c @@ -58,10 +58,10 @@ struct C { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'union C::(anonymous at {{.*}}:[[@LINE-7]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit c 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union C::(anonymous at {{.*}}:[[@LINE-9]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'union C::(anonymous at {{.*}}:[[@LINE-9]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:11 implicit d 'float' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union C::(anonymous at {{.*}}:[[@LINE-12]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'union C::(anonymous at {{.*}}:[[@LINE-12]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' struct { @@ -72,10 +72,10 @@ struct C { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'struct C::(anonymous at {{.*}}:[[@LINE-6]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit e 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct C::(anonymous at {{.*}}:[[@LINE-8]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'struct C::(anonymous at {{.*}}:[[@LINE-8]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:12 implicit f 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct C::(anonymous at {{.*}}:[[@LINE-11]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'struct C::(anonymous at {{.*}}:[[@LINE-11]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' }; @@ -141,10 +141,10 @@ union G { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'union G::(anonymous at {{.*}}:[[@LINE-7]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit c 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union G::(anonymous at {{.*}}:[[@LINE-9]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'union G::(anonymous at {{.*}}:[[@LINE-9]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:11 implicit d 'float' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'union G::(anonymous at {{.*}}:[[@LINE-12]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'union G::(anonymous at {{.*}}:[[@LINE-12]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' struct { @@ -155,10 +155,10 @@ union G { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'struct G::(anonymous at {{.*}}:[[@LINE-6]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit e 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct G::(anonymous at {{.*}}:[[@LINE-8]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'struct G::(anonymous at {{.*}}:[[@LINE-8]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:12 implicit f 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'struct G::(anonymous at {{.*}}:[[@LINE-11]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'struct G::(anonymous at {{.*}}:[[@LINE-11]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' }; diff --git a/clang/test/AST/ast-dump-records.cpp b/clang/test/AST/ast-dump-records.cpp index bfd8892698d4b..e9b37b73002dd 100644 --- a/clang/test/AST/ast-dump-records.cpp +++ b/clang/test/AST/ast-dump-records.cpp @@ -90,10 +90,10 @@ struct C { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'C::(anonymous union at {{.*}}:[[@LINE-14]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit c 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous union at {{.*}}:[[@LINE-16]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'C::(anonymous union at {{.*}}:[[@LINE-16]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:11 implicit d 'float' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous union at {{.*}}:[[@LINE-19]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'C::(anonymous union at {{.*}}:[[@LINE-19]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' struct { @@ -111,10 +111,10 @@ struct C { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'C::(anonymous struct at {{.*}}:[[@LINE-13]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit e 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous struct at {{.*}}:[[@LINE-15]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'C::(anonymous struct at {{.*}}:[[@LINE-15]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:12 implicit f 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'C::(anonymous struct at {{.*}}:[[@LINE-18]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'C::(anonymous struct at {{.*}}:[[@LINE-18]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' }; @@ -223,10 +223,10 @@ union G { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'G::(anonymous union at {{.*}}:[[@LINE-15]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit c 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous union at {{.*}}:[[@LINE-17]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'G::(anonymous union at {{.*}}:[[@LINE-17]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'c' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:11 implicit d 'float' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous union at {{.*}}:[[@LINE-20]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 1 'G::(anonymous union at {{.*}}:[[@LINE-20]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'd' 'float' struct { @@ -245,10 +245,10 @@ union G { }; // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} col:3 implicit 'G::(anonymous struct at {{.*}}:[[@LINE-14]]:3)' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:9 implicit e 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous struct at {{.*}}:[[@LINE-16]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'G::(anonymous struct at {{.*}}:[[@LINE-16]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'e' 'int' // CHECK-NEXT: IndirectFieldDecl 0x{{[^ ]*}} col:12 implicit f 'int' - // CHECK-NEXT: Field 0x{{[^ ]*}} '' 'G::(anonymous struct at {{.*}}:[[@LINE-19]]:3)' + // CHECK-NEXT: Field 0x{{[^ ]*}} field_index 2 'G::(anonymous struct at {{.*}}:[[@LINE-19]]:3)' // CHECK-NEXT: Field 0x{{[^ ]*}} 'f' 'int' }; diff --git a/clang/test/AST/ast-dump-templates.cpp b/clang/test/AST/ast-dump-templates.cpp index 9fcafbcbcc46b..86af8c50f3174 100644 --- a/clang/test/AST/ast-dump-templates.cpp +++ b/clang/test/AST/ast-dump-templates.cpp @@ -1,7 +1,15 @@ -// RUN: %clang_cc1 -std=c++1z -ast-print %s > %t +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump=json %s | FileCheck --check-prefix=JSON %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-print %s > %t // RUN: FileCheck < %t %s -check-prefix=CHECK1 // RUN: FileCheck < %t %s -check-prefix=CHECK2 -// RUN: %clang_cc1 -std=c++1z -ast-dump %s | FileCheck --check-prefix=DUMP %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump %s | FileCheck --check-prefix=DUMP %s + +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -emit-pch -o %t %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -x c++ -std=c++17 -include-pch %t \ +// RUN: -ast-dump-all /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace --check-prefix=DUMP %s template struct foo { @@ -118,3 +126,6038 @@ void func() { // DUMP-NEXT: `-TemplateTypeParm {{.*}} 'Key' } } + +namespace test7 { + template class TT> struct A {}; + template class B {}; + template struct A; +// DUMP-LABEL: NamespaceDecl {{.*}} test7{{$}} +// DUMP: ClassTemplateSpecializationDecl {{.*}} struct A definition explicit_instantiation_definition strict-pack-match{{$}} +} // namespce test7 + +// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py + + +// JSON-NOT: {{^}}Dumping +// JSON: "kind": "TranslationUnitDecl", +// JSON-NEXT: "loc": {}, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": {}, +// JSON-NEXT: "end": {} +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TypedefDecl", +// JSON-NEXT: "loc": {}, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": {}, +// JSON-NEXT: "end": {} +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "__int128_t", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "__int128" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BuiltinType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "__int128" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TypedefDecl", +// JSON-NEXT: "loc": {}, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": {}, +// JSON-NEXT: "end": {} +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "__uint128_t", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "unsigned __int128" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BuiltinType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "unsigned __int128" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TypedefDecl", +// JSON-NEXT: "loc": {}, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": {}, +// JSON-NEXT: "end": {} +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "__NSConstantString", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "__NSConstantString_tag" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "RecordType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "__NSConstantString_tag" +// JSON-NEXT: }, +// JSON-NEXT: "decl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "name": "__NSConstantString_tag" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TypedefDecl", +// JSON-NEXT: "loc": {}, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": {}, +// JSON-NEXT: "end": {} +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "__builtin_ms_va_list", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "char *" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "PointerType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "char *" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BuiltinType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "char" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TypedefDecl", +// JSON-NEXT: "loc": {}, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": {}, +// JSON-NEXT: "end": {} +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "__builtin_va_list", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "__va_list_tag[1]" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ConstantArrayType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "__va_list_tag[1]" +// JSON-NEXT: }, +// JSON-NEXT: "size": 1, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "RecordType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "__va_list_tag" +// JSON-NEXT: }, +// JSON-NEXT: "decl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "name": "__va_list_tag" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "file": "{{.*}}", +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 765, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 879, +// JSON-NEXT: "line": 19, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 779, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 775, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 779, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "X", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 791, +// JSON-NEXT: "col": 27, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 782, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 791, +// JSON-NEXT: "col": 27, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "Y", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 1 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 798, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 794, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "Z", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 2, +// JSON-NEXT: "defaultArg": { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "isExpr": true +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isExpr": true, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "5" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 805, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 879, +// JSON-NEXT: "line": 19, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "nonTrivial": true, +// JSON-NEXT: "userProvided": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasUserDeclaredConstructor": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 805, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FieldDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 824, +// JSON-NEXT: "line": 16, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 820, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 824, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "constant", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXConstructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 836, +// JSON-NEXT: "line": 17, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 836, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 843, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 842, +// JSON-NEXT: "col": 9, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 843, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMethodDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 849, +// JSON-NEXT: "line": 18, +// JSON-NEXT: "col": 5, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 847, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 877, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "getSum", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "Y ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 858, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 877, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ReturnStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 860, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 874, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXUnresolvedConstructExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 867, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 874, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "Y" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BinaryOperator", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "opcode": "+", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclRefExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "referencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "name": "X", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclRefExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "referencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "name": "Z", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 765, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 879, +// JSON-NEXT: "line": 19, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "canPassInRegisters": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "nonTrivial": true, +// JSON-NEXT: "userProvided": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasUserDeclaredConstructor": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 5 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BuiltinType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 5 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 805, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FieldDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 824, +// JSON-NEXT: "line": 16, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 820, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 824, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "constant", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXConstructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 836, +// JSON-NEXT: "line": 17, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 836, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 843, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi5EiLi5EEC1Ev", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 842, +// JSON-NEXT: "col": 9, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 843, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMethodDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 849, +// JSON-NEXT: "line": 18, +// JSON-NEXT: "col": 5, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 847, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 877, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "getSum", +// JSON-NEXT: "mangledName": "_ZN3fooILi5EiLi5EE6getSumEv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 858, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 877, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ReturnStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 860, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 874, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXFunctionalCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 867, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 874, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "NoOp", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BinaryOperator", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "opcode": "+", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "SubstNonTypeTemplateParmExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 779, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 775, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 779, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "X", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "line": 18, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "5" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "SubstNonTypeTemplateParmExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 798, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 794, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "Z", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 2, +// JSON-NEXT: "defaultArg": { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "isExpr": true +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isExpr": true, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "5" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "line": 18, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "5" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXConstructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi5EiLi5EEC1ERKS0_", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (const foo<5, int> &)" +// JSON-NEXT: }, +// JSON-NEXT: "inline": true, +// JSON-NEXT: "constexpr": true, +// JSON-NEXT: "explicitlyDefaulted": "default", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "const foo<5, int> &" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXConstructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi5EiLi5EEC1EOS0_", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (foo<5, int> &&)" +// JSON-NEXT: }, +// JSON-NEXT: "inline": true, +// JSON-NEXT: "constexpr": true, +// JSON-NEXT: "explicitlyDefaulted": "default", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "foo<5, int> &&" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXDestructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "~foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi5EiLi5EED1Ev", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void () noexcept" +// JSON-NEXT: }, +// JSON-NEXT: "inline": true, +// JSON-NEXT: "explicitlyDefaulted": "default" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 765, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 879, +// JSON-NEXT: "line": 19, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "canPassInRegisters": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "nonTrivial": true, +// JSON-NEXT: "userProvided": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasUserDeclaredConstructor": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 2 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BuiltinType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 3 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 805, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FieldDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 824, +// JSON-NEXT: "line": 16, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 820, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 824, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "constant", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXConstructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 836, +// JSON-NEXT: "line": 17, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 836, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 843, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi2EdLi3EEC1Ev", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 842, +// JSON-NEXT: "col": 9, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 843, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMethodDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 849, +// JSON-NEXT: "line": 18, +// JSON-NEXT: "col": 5, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 847, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 877, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "getSum", +// JSON-NEXT: "mangledName": "_ZN3fooILi2EdLi3EE6getSumEv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 858, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 877, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ReturnStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 860, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 874, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXFunctionalCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 867, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 874, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "NoOp", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ImplicitCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "IntegralToFloating", +// JSON-NEXT: "isPartOfExplicitCast": true, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BinaryOperator", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "opcode": "+", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "SubstNonTypeTemplateParmExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 779, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 775, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 779, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "X", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "line": 18, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 869, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "2" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "SubstNonTypeTemplateParmExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 798, +// JSON-NEXT: "line": 14, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 794, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "Z", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 2, +// JSON-NEXT: "defaultArg": { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "isExpr": true +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isExpr": true, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 802, +// JSON-NEXT: "col": 38, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "5" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "line": 18, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 873, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "3" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXConstructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "line": 15, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi2EdLi3EEC1ERKS0_", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (const foo<2, double, 3> &)" +// JSON-NEXT: }, +// JSON-NEXT: "inline": true, +// JSON-NEXT: "constexpr": true, +// JSON-NEXT: "explicitlyDefaulted": "default", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "const foo<2, double, 3> &" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXConstructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi2EdLi3EEC1EOS0_", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (foo<2, double, 3> &&)" +// JSON-NEXT: }, +// JSON-NEXT: "inline": true, +// JSON-NEXT: "constexpr": true, +// JSON-NEXT: "explicitlyDefaulted": "default", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "foo<2, double, 3> &&" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXDestructorDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 812, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "~foo", +// JSON-NEXT: "mangledName": "_ZN3fooILi2EdLi3EED1Ev", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void () noexcept" +// JSON-NEXT: }, +// JSON-NEXT: "inline": true, +// JSON-NEXT: "explicitlyDefaulted": "default" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 914, +// JSON-NEXT: "line": 22, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 883, +// JSON-NEXT: "line": 21, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 937, +// JSON-NEXT: "line": 24, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "bar", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 897, +// JSON-NEXT: "line": 21, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 893, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 897, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 909, +// JSON-NEXT: "col": 27, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 900, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 909, +// JSON-NEXT: "col": 27, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "B", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 1 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 914, +// JSON-NEXT: "line": 22, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 912, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 937, +// JSON-NEXT: "line": 24, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "bar", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "B ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 920, +// JSON-NEXT: "line": 22, +// JSON-NEXT: "col": 9, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 937, +// JSON-NEXT: "line": 24, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ReturnStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 924, +// JSON-NEXT: "line": 23, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 934, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXUnresolvedConstructExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 931, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 934, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "B" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclRefExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 933, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 933, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "referencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "name": "A", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 914, +// JSON-NEXT: "line": 22, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 912, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 937, +// JSON-NEXT: "line": 24, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "bar", +// JSON-NEXT: "mangledName": "_Z3barILi5EiET0_v", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 5 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BuiltinType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 920, +// JSON-NEXT: "line": 22, +// JSON-NEXT: "col": 9, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 937, +// JSON-NEXT: "line": 24, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ReturnStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 924, +// JSON-NEXT: "line": 23, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 934, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXFunctionalCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 931, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 934, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "NoOp", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "SubstNonTypeTemplateParmExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 933, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 933, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 897, +// JSON-NEXT: "line": 21, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 893, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 897, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 933, +// JSON-NEXT: "line": 23, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 933, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "5" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 945, +// JSON-NEXT: "line": 26, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 940, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1055, +// JSON-NEXT: "line": 30, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "baz", +// JSON-NEXT: "mangledName": "_Z3bazv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 951, +// JSON-NEXT: "line": 26, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1055, +// JSON-NEXT: "line": 30, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 955, +// JSON-NEXT: "line": 27, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 976, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 959, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 955, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 975, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "x", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "init": "c", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CallExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 963, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 975, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ImplicitCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 963, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 973, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int (*)()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "FunctionToPointerDecay", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclRefExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 963, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 973, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int ()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "lvalue", +// JSON-NEXT: "referencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "name": "bar", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int ()" +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "foundReferencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "name": "bar" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 980, +// JSON-NEXT: "line": 28, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1010, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 984, +// JSON-NEXT: "col": 7, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 980, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1009, +// JSON-NEXT: "col": 32, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "y", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "init": "c", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ExprWithCleanups", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 988, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1009, +// JSON-NEXT: "col": 32, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMemberCallExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 988, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1009, +// JSON-NEXT: "col": 32, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "MemberExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 988, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1002, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "name": "getSum", +// JSON-NEXT: "isArrow": false, +// JSON-NEXT: "referencedMemberDecl": "0x{{.*}}", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "MaterializeTemporaryExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 988, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1000, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "foo<5, int>" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "xvalue", +// JSON-NEXT: "storageDuration": "full expression", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXTemporaryObjectExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 988, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1000, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "foo<5, int>" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "ctorType": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "hadMultipleCandidates": true, +// JSON-NEXT: "constructionKind": "complete" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1014, +// JSON-NEXT: "line": 29, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1053, +// JSON-NEXT: "col": 42, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1021, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1014, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1052, +// JSON-NEXT: "col": 41, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "z", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double" +// JSON-NEXT: }, +// JSON-NEXT: "init": "c", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ExprWithCleanups", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1025, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1052, +// JSON-NEXT: "col": 41, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMemberCallExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1025, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1052, +// JSON-NEXT: "col": 41, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "double" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "MemberExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1025, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1045, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "name": "getSum", +// JSON-NEXT: "isArrow": false, +// JSON-NEXT: "referencedMemberDecl": "0x{{.*}}", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "MaterializeTemporaryExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1025, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1043, +// JSON-NEXT: "col": 32, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "foo<2, double, 3>" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "xvalue", +// JSON-NEXT: "storageDuration": "full expression", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXTemporaryObjectExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1025, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1043, +// JSON-NEXT: "col": 32, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "foo<2, double, 3>" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "ctorType": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "hadMultipleCandidates": true, +// JSON-NEXT: "constructionKind": "complete" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1856, +// JSON-NEXT: "line": 52, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1824, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1896, +// JSON-NEXT: "line": 54, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1846, +// JSON-NEXT: "line": 52, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1834, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1846, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "T", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0, +// JSON-NEXT: "isParameterPack": true +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1856, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1849, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1896, +// JSON-NEXT: "line": 54, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1856, +// JSON-NEXT: "line": 52, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1849, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1856, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1890, +// JSON-NEXT: "line": 53, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1862, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1893, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "B", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1877, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1872, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1880, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "x", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "T[3]..." +// JSON-NEXT: }, +// JSON-NEXT: "depth": 1, +// JSON-NEXT: "index": 0, +// JSON-NEXT: "isParameterPack": true +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1890, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1883, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1893, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "B", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 1890, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1883, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 1890, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "B", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2016, +// JSON-NEXT: "line": 58, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1986, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2038, +// JSON-NEXT: "line": 60, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2008, +// JSON-NEXT: "line": 58, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 1996, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2008, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "T", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0, +// JSON-NEXT: "isParameterPack": true +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2016, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2011, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2038, +// JSON-NEXT: "line": 60, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2020, +// JSON-NEXT: "line": 58, +// JSON-NEXT: "col": 35, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2038, +// JSON-NEXT: "line": 60, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2024, +// JSON-NEXT: "line": 59, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2036, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2035, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2024, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2035, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "a", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "A" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NamespaceDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2051, +// JSON-NEXT: "line": 62, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2041, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 9 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2240, +// JSON-NEXT: "line": 71, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "test2", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2064, +// JSON-NEXT: "line": 63, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2059, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2072, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "func", +// JSON-NEXT: "mangledName": "_ZN5test24funcEi", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (int)" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2072, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2069, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2069, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2080, +// JSON-NEXT: "line": 64, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2075, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2090, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "func", +// JSON-NEXT: "mangledName": "_ZN5test24funcEf", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (float)" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2090, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2085, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2085, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "float" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2119, +// JSON-NEXT: "line": 66, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2093, +// JSON-NEXT: "line": 65, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2141, +// JSON-NEXT: "line": 68, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "tmpl", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2111, +// JSON-NEXT: "line": 65, +// JSON-NEXT: "col": 19, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2102, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2111, +// JSON-NEXT: "col": 19, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "T", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2119, +// JSON-NEXT: "line": 66, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2114, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2141, +// JSON-NEXT: "line": 68, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "tmpl", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2126, +// JSON-NEXT: "line": 66, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2141, +// JSON-NEXT: "line": 68, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CallExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2130, +// JSON-NEXT: "line": 67, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2138, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "UnresolvedLookupExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2130, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2130, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "lvalue", +// JSON-NEXT: "usesADL": true, +// JSON-NEXT: "name": "func", +// JSON-NEXT: "lookups": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "name": "func", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (float)" +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "name": "func", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (int)" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXUnresolvedConstructExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2135, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2137, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "T" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NamespaceDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2253, +// JSON-NEXT: "line": 73, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2243, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 9 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2387, +// JSON-NEXT: "line": 77, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "test3", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "line": 74, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2263, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2294, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2281, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2272, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2281, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "T", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2284, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2294, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2284, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2263, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2294, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "BuiltinType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2263, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2281, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2272, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2281, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "T", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXDeductionGuideDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "auto () -> A" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2263, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2281, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2272, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2281, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "T", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXDeductionGuideDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "auto (A) -> A" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2291, +// JSON-NEXT: "col": 31, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "A" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2320, +// JSON-NEXT: "line": 75, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2299, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2333, +// JSON-NEXT: "col": 37, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2317, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2308, +// JSON-NEXT: "col": 12, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2317, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "T", +// JSON-NEXT: "tagUsed": "typename", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXDeductionGuideDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2320, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2320, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2333, +// JSON-NEXT: "col": 37, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "auto (T) -> A" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ParmVarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2323, +// JSON-NEXT: "col": 27, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2322, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2322, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "T" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NamespaceDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2400, +// JSON-NEXT: "line": 79, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2390, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 9 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3297, +// JSON-NEXT: "line": 103, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "test4", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "line": 81, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2408, +// JSON-NEXT: "line": 80, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2471, +// JSON-NEXT: "line": 83, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2427, +// JSON-NEXT: "line": 80, +// JSON-NEXT: "col": 20, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2418, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2427, +// JSON-NEXT: "col": 20, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "X", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "unsigned int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2435, +// JSON-NEXT: "col": 28, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2430, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2435, +// JSON-NEXT: "col": 28, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "auto" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 1 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "line": 81, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2438, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2471, +// JSON-NEXT: "line": 83, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "line": 81, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2438, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMethodDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2465, +// JSON-NEXT: "line": 82, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 2 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2453, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2468, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "fn", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "storageClass": "static" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "line": 81, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2408, +// JSON-NEXT: "line": 80, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2471, +// JSON-NEXT: "line": 83, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "canPassInRegisters": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "line": 81, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2438, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMethodDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2465, +// JSON-NEXT: "line": 82, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 2 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2453, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2468, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "fn", +// JSON-NEXT: "mangledName": "_ZN5test43fooILj0ELl0EE2fnEv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "storageClass": "static" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "name": "foo" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2846, +// JSON-NEXT: "line": 92, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2841, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2879, +// JSON-NEXT: "line": 94, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "test", +// JSON-NEXT: "mangledName": "_ZN5test44testEv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2853, +// JSON-NEXT: "line": 92, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2879, +// JSON-NEXT: "line": 94, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CallExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2857, +// JSON-NEXT: "line": 93, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2876, +// JSON-NEXT: "col": 22, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ImplicitCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2857, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2873, +// JSON-NEXT: "col": 19, +// JSON-NEXT: "tokLen": 2 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (*)()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "FunctionToPointerDecay", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclRefExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2857, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2873, +// JSON-NEXT: "col": 19, +// JSON-NEXT: "tokLen": 2 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "lvalue", +// JSON-NEXT: "referencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMethodDecl", +// JSON-NEXT: "name": "fn", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3281, +// JSON-NEXT: "line": 102, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3265, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3294, +// JSON-NEXT: "col": 30, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "canPassInRegisters": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 1 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "line": 81, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2438, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2445, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "foo", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXMethodDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 2465, +// JSON-NEXT: "line": 82, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 2 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 2453, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 2468, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "fn", +// JSON-NEXT: "mangledName": "_ZN5test43fooILj1ELl0EE2fnEv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "storageClass": "static" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NamespaceDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3310, +// JSON-NEXT: "line": 105, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3300, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 9 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3632, +// JSON-NEXT: "line": 114, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "test5", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3338, +// JSON-NEXT: "line": 106, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3318, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3343, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3331, +// JSON-NEXT: "col": 14, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3327, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3327, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "long" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3338, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3333, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3343, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3342, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3343, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3338, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3333, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3343, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "mangledName": "_ZN5test51fILl0EEEvv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3342, +// JSON-NEXT: "col": 25, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3343, +// JSON-NEXT: "col": 26, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3352, +// JSON-NEXT: "line": 107, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3345, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3362, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "p", +// JSON-NEXT: "mangledName": "_ZN5test51pE", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (*)()" +// JSON-NEXT: }, +// JSON-NEXT: "init": "c", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ImplicitCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3359, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3362, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (*)()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "FunctionToPointerDecay", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclRefExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3359, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3362, +// JSON-NEXT: "col": 18, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "lvalue", +// JSON-NEXT: "referencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "name": "f", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "foundReferencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "name": "f" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3393, +// JSON-NEXT: "line": 108, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3365, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3398, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NonTypeTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3383, +// JSON-NEXT: "col": 19, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3374, +// JSON-NEXT: "col": 10, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3385, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "unsigned int" +// JSON-NEXT: }, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0, +// JSON-NEXT: "defaultArg": { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "isExpr": true +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3385, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3385, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isExpr": true, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "IntegerLiteral", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3385, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3385, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "int" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": "0" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3393, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3388, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3398, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3397, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3398, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3393, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3388, +// JSON-NEXT: "col": 24, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3398, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isUsed": true, +// JSON-NEXT: "name": "f", +// JSON-NEXT: "mangledName": "_ZN5test51fILj0EEEvv", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "value": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3397, +// JSON-NEXT: "col": 33, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3398, +// JSON-NEXT: "col": 34, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3407, +// JSON-NEXT: "line": 109, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3400, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3416, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "q", +// JSON-NEXT: "mangledName": "_ZN5test51qE", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (*)()" +// JSON-NEXT: }, +// JSON-NEXT: "init": "c", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ImplicitCastExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3414, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3416, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void (*)()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "castKind": "FunctionToPointerDecay", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "DeclRefExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3414, +// JSON-NEXT: "col": 15, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3416, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "lvalue", +// JSON-NEXT: "referencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "name": "f", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "foundReferencedDecl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "name": "f" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NamespaceDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3645, +// JSON-NEXT: "line": 116, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3635, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 9 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4000, +// JSON-NEXT: "line": 128, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "test6", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3687, +// JSON-NEXT: "line": 118, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3653, +// JSON-NEXT: "line": 117, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3691, +// JSON-NEXT: "line": 118, +// JSON-NEXT: "col": 20, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "C", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3669, +// JSON-NEXT: "line": 117, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3663, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3669, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "D", +// JSON-NEXT: "tagUsed": "class", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3687, +// JSON-NEXT: "line": 118, +// JSON-NEXT: "col": 16, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3672, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 9 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3691, +// JSON-NEXT: "col": 20, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "C", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "const bool" +// JSON-NEXT: }, +// JSON-NEXT: "constexpr": true, +// JSON-NEXT: "init": "c", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXBoolLiteralExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3691, +// JSON-NEXT: "col": 20, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3691, +// JSON-NEXT: "col": 20, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "bool" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "prvalue", +// JSON-NEXT: "value": true +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3724, +// JSON-NEXT: "line": 121, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3698, +// JSON-NEXT: "line": 120, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3998, +// JSON-NEXT: "line": 127, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "func", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3714, +// JSON-NEXT: "line": 120, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3708, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3714, +// JSON-NEXT: "col": 17, +// JSON-NEXT: "tokLen": 3 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isReferenced": true, +// JSON-NEXT: "name": "Key", +// JSON-NEXT: "tagUsed": "class", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0 +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "FunctionDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 3724, +// JSON-NEXT: "line": 121, +// JSON-NEXT: "col": 6, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3719, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 4 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3998, +// JSON-NEXT: "line": 127, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "func", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "void ()" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CompoundStmt", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3731, +// JSON-NEXT: "line": 121, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3998, +// JSON-NEXT: "line": 127, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "UnresolvedLookupExpr", +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 3735, +// JSON-NEXT: "line": 122, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 3740, +// JSON-NEXT: "col": 8, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "" +// JSON-NEXT: }, +// JSON-NEXT: "valueCategory": "lvalue", +// JSON-NEXT: "usesADL": false, +// JSON-NEXT: "name": "C", +// JSON-NEXT: "lookups": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "VarTemplateDecl", +// JSON-NEXT: "name": "C" +// JSON-NEXT: } +// JSON-NEXT: ], +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "Key" +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmType", +// JSON-NEXT: "type": { +// JSON-NEXT: "qualType": "Key" +// JSON-NEXT: }, +// JSON-NEXT: "isDependent": true, +// JSON-NEXT: "isInstantiationDependent": true, +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0, +// JSON-NEXT: "decl": { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "name": "Key" +// JSON-NEXT: } +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "NamespaceDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4013, +// JSON-NEXT: "line": 130, +// JSON-NEXT: "col": 11, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4003, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 9 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4308, +// JSON-NEXT: "line": 136, +// JSON-NEXT: "col": 1, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "test7", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4066, +// JSON-NEXT: "line": 131, +// JSON-NEXT: "col": 46, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4023, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4069, +// JSON-NEXT: "col": 49, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTemplateParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4055, +// JSON-NEXT: "col": 35, +// JSON-NEXT: "tokLen": 2 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4033, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4055, +// JSON-NEXT: "col": 35, +// JSON-NEXT: "tokLen": 2 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "TT", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4047, +// JSON-NEXT: "col": 27, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4042, +// JSON-NEXT: "col": 22, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4042, +// JSON-NEXT: "col": 22, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "tagUsed": "class", +// JSON-NEXT: "depth": 1, +// JSON-NEXT: "index": 0 +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4066, +// JSON-NEXT: "col": 46, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4059, +// JSON-NEXT: "col": 39, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4069, +// JSON-NEXT: "col": 49, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4066, +// JSON-NEXT: "col": 46, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4059, +// JSON-NEXT: "col": 39, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4066, +// JSON-NEXT: "col": 46, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "name": "A" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4100, +// JSON-NEXT: "line": 132, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4074, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4103, +// JSON-NEXT: "col": 32, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "B", +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "TemplateTypeParmDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4092, +// JSON-NEXT: "col": 21, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4084, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4084, +// JSON-NEXT: "col": 13, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "tagUsed": "class", +// JSON-NEXT: "depth": 0, +// JSON-NEXT: "index": 0, +// JSON-NEXT: "isParameterPack": true +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4100, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4094, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4103, +// JSON-NEXT: "col": 32, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "B", +// JSON-NEXT: "tagUsed": "class", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4100, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4094, +// JSON-NEXT: "col": 23, +// JSON-NEXT: "tokLen": 5 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4100, +// JSON-NEXT: "col": 29, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "B", +// JSON-NEXT: "tagUsed": "class" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "ClassTemplateSpecializationDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4124, +// JSON-NEXT: "line": 133, +// JSON-NEXT: "col": 19, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4108, +// JSON-NEXT: "col": 3, +// JSON-NEXT: "tokLen": 8 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4127, +// JSON-NEXT: "col": 22, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct", +// JSON-NEXT: "completeDefinition": true, +// JSON-NEXT: "strict-pack-match": true, +// JSON-NEXT: "definitionData": { +// JSON-NEXT: "canConstDefaultInit": true, +// JSON-NEXT: "canPassInRegisters": true, +// JSON-NEXT: "copyAssign": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "copyCtor": { +// JSON-NEXT: "hasConstParam": true, +// JSON-NEXT: "implicitHasConstParam": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "defaultCtor": { +// JSON-NEXT: "defaultedIsConstexpr": true, +// JSON-NEXT: "exists": true, +// JSON-NEXT: "isConstexpr": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "dtor": { +// JSON-NEXT: "irrelevant": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "hasConstexprNonCopyMoveConstructor": true, +// JSON-NEXT: "isAggregate": true, +// JSON-NEXT: "isEmpty": true, +// JSON-NEXT: "isLiteral": true, +// JSON-NEXT: "isPOD": true, +// JSON-NEXT: "isStandardLayout": true, +// JSON-NEXT: "isTrivial": true, +// JSON-NEXT: "isTriviallyCopyable": true, +// JSON-NEXT: "moveAssign": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: }, +// JSON-NEXT: "moveCtor": { +// JSON-NEXT: "exists": true, +// JSON-NEXT: "needsImplicit": true, +// JSON-NEXT: "simple": true, +// JSON-NEXT: "trivial": true +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "inner": [ +// JSON-NEXT: { +// JSON-NEXT: "kind": "TemplateArgument" +// JSON-NEXT: }, +// JSON-NEXT: { +// JSON-NEXT: "id": "0x{{.*}}", +// JSON-NEXT: "kind": "CXXRecordDecl", +// JSON-NEXT: "loc": { +// JSON-NEXT: "offset": 4066, +// JSON-NEXT: "line": 131, +// JSON-NEXT: "col": 46, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: }, +// JSON-NEXT: "range": { +// JSON-NEXT: "begin": { +// JSON-NEXT: "offset": 4059, +// JSON-NEXT: "col": 39, +// JSON-NEXT: "tokLen": 6 +// JSON-NEXT: }, +// JSON-NEXT: "end": { +// JSON-NEXT: "offset": 4066, +// JSON-NEXT: "col": 46, +// JSON-NEXT: "tokLen": 1 +// JSON-NEXT: } +// JSON-NEXT: }, +// JSON-NEXT: "isImplicit": true, +// JSON-NEXT: "name": "A", +// JSON-NEXT: "tagUsed": "struct" +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } +// JSON-NEXT: ] +// JSON-NEXT: } diff --git a/clang/test/AST/ast-print-openacc-atomic-construct.cpp b/clang/test/AST/ast-print-openacc-atomic-construct.cpp new file mode 100644 index 0000000000000..572f2ea4842d8 --- /dev/null +++ b/clang/test/AST/ast-print-openacc-atomic-construct.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fopenacc -ast-print %s -o - | FileCheck %s + +void foo(int v, int x) { +// CHECK: #pragma acc atomic read +// CHECK-NEXT: v = x; +#pragma acc atomic read + v = x; +// CHECK-NEXT: pragma acc atomic write +// CHECK-NEXT: v = x + 1; +#pragma acc atomic write + v = x + 1; +// CHECK-NEXT: pragma acc atomic update +// CHECK-NEXT: x++; +#pragma acc atomic update + x++; +// CHECK-NEXT: pragma acc atomic +// CHECK-NEXT: x--; +#pragma acc atomic + x--; +// CHECK-NEXT: pragma acc atomic capture +// CHECK-NEXT: v = x++; +#pragma acc atomic capture + v = x++; + +// CHECK-NEXT: #pragma acc atomic capture +// CHECK-NEXT: { +// CHECK-NEXT: x--; +// CHECK-NEXT: v = x; +// CHECK-NEXT: } +#pragma acc atomic capture + { x--; v = x; } + +} diff --git a/clang/test/AST/attr-counted-by-late-parsed-struct-ptrs.c b/clang/test/AST/attr-counted-by-late-parsed-struct-ptrs.c index a585a45eeff03..f9772db8b6554 100644 --- a/clang/test/AST/attr-counted-by-late-parsed-struct-ptrs.c +++ b/clang/test/AST/attr-counted-by-late-parsed-struct-ptrs.c @@ -31,7 +31,7 @@ struct on_pointer_anon_count { // CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' // CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' -// CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' +// CHECK-NEXT: |-Field {{.*}} field_index 1 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-Field {{.*}} 'count' 'int' //============================================================================== diff --git a/clang/test/AST/attr-counted-by-or-null-late-parsed-struct-ptrs.c b/clang/test/AST/attr-counted-by-or-null-late-parsed-struct-ptrs.c index 975c0a0231943..59b866dae720d 100644 --- a/clang/test/AST/attr-counted-by-or-null-late-parsed-struct-ptrs.c +++ b/clang/test/AST/attr-counted-by-or-null-late-parsed-struct-ptrs.c @@ -31,7 +31,7 @@ struct on_pointer_anon_count { // CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' // CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' -// CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' +// CHECK-NEXT: |-Field {{.*}} field_index 1 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-Field {{.*}} 'count' 'int' //============================================================================== diff --git a/clang/test/AST/attr-counted-by-or-null-struct-ptrs.c b/clang/test/AST/attr-counted-by-or-null-struct-ptrs.c index 075f583784fe1..d42547003f0b3 100644 --- a/clang/test/AST/attr-counted-by-or-null-struct-ptrs.c +++ b/clang/test/AST/attr-counted-by-or-null-struct-ptrs.c @@ -26,7 +26,7 @@ struct on_member_pointer_complete_ty { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by_or_null(count)':'struct size_known *' struct on_pointer_anon_buf { int count; @@ -94,7 +94,7 @@ struct on_nested_pointer_outer { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by_or_null(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by_or_null(count)':'struct size_known *' struct on_pointer_anon_buf_ty_pos { int count; @@ -108,7 +108,7 @@ struct on_pointer_anon_buf_ty_pos { // CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' // CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' -// CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' +// CHECK-NEXT: | |-Field {{.+}} field_index 0 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' // CHECK-NEXT: | `-Field {{.+}} 'count' 'int' struct on_pointer_anon_count_ty_pos { struct { diff --git a/clang/test/AST/attr-counted-by-struct-ptrs.c b/clang/test/AST/attr-counted-by-struct-ptrs.c index 0c05258234143..afef9c8c3b95d 100644 --- a/clang/test/AST/attr-counted-by-struct-ptrs.c +++ b/clang/test/AST/attr-counted-by-struct-ptrs.c @@ -26,7 +26,7 @@ struct on_member_pointer_complete_ty { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by(count)':'struct size_known *' struct on_pointer_anon_buf { int count; @@ -94,7 +94,7 @@ struct on_nested_pointer_outer { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __counted_by(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __counted_by(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __counted_by(count)':'struct size_known *' struct on_pointer_anon_buf_ty_pos { int count; @@ -108,7 +108,7 @@ struct on_pointer_anon_buf_ty_pos { // CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' // CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' -// CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' +// CHECK-NEXT: | |-Field {{.+}} field_index 0 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' // CHECK-NEXT: | `-Field {{.+}} 'count' 'int' struct on_pointer_anon_count_ty_pos { struct { diff --git a/clang/test/AST/attr-print-emit.cpp b/clang/test/AST/attr-print-emit.cpp index a9bca6778d0f1..77826f8f9af09 100644 --- a/clang/test/AST/attr-print-emit.cpp +++ b/clang/test/AST/attr-print-emit.cpp @@ -91,3 +91,8 @@ ANNOTATE_ATTR NONNULL_ATTR void fn_non_null_annotated_attr(int *) __attribute__( [[gnu::nonnull(1)]] [[gnu::always_inline]] void cxx11_attr(int*) ANNOTATE_ATTR; // CHECK: {{\[\[}}gnu::nonnull(1)]] {{\[\[}}gnu::always_inline]] void cxx11_attr(int *) __attribute__((annotate("Annotated"))); + +struct Foo; + +// CHECK: void as_member_fn_ptr(int *(Foo::*member)(int) __attribute__((alloc_size(1)))); +void as_member_fn_ptr(int* (Foo::*member)(int) __attribute__((alloc_size(1)))); diff --git a/clang/test/AST/attr-sized-by-late-parsed-struct-ptrs.c b/clang/test/AST/attr-sized-by-late-parsed-struct-ptrs.c index b58caf608bf97..411b333f37989 100644 --- a/clang/test/AST/attr-sized-by-late-parsed-struct-ptrs.c +++ b/clang/test/AST/attr-sized-by-late-parsed-struct-ptrs.c @@ -31,7 +31,7 @@ struct on_pointer_anon_count { // CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' // CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' -// CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' +// CHECK-NEXT: |-Field {{.*}} field_index 1 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-Field {{.*}} 'count' 'int' //============================================================================== diff --git a/clang/test/AST/attr-sized-by-or-null-late-parsed-struct-ptrs.c b/clang/test/AST/attr-sized-by-or-null-late-parsed-struct-ptrs.c index d55a42ac0fb94..ae89360e17493 100644 --- a/clang/test/AST/attr-sized-by-or-null-late-parsed-struct-ptrs.c +++ b/clang/test/AST/attr-sized-by-or-null-late-parsed-struct-ptrs.c @@ -31,7 +31,7 @@ struct on_pointer_anon_count { // CHECK-NEXT: | `-FieldDecl {{.*}} count 'int' // CHECK-NEXT: |-FieldDecl {{.*}} implicit 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-IndirectFieldDecl {{.*}} implicit referenced count 'int' -// CHECK-NEXT: |-Field {{.*}} '' 'struct on_pointer_anon_count::(anonymous at {{.*}})' +// CHECK-NEXT: |-Field {{.*}} field_index 1 'struct on_pointer_anon_count::(anonymous at {{.*}})' // CHECK-NEXT: `-Field {{.*}} 'count' 'int' //============================================================================== diff --git a/clang/test/AST/attr-sized-by-or-null-struct-ptrs.c b/clang/test/AST/attr-sized-by-or-null-struct-ptrs.c index 73b8a71f23503..7273280e4b60c 100644 --- a/clang/test/AST/attr-sized-by-or-null-struct-ptrs.c +++ b/clang/test/AST/attr-sized-by-or-null-struct-ptrs.c @@ -26,7 +26,7 @@ struct on_member_pointer_complete_ty { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by_or_null(count)':'struct size_known *' struct on_pointer_anon_buf { int count; @@ -94,7 +94,7 @@ struct on_nested_pointer_outer { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by_or_null(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by_or_null(count)':'struct size_known *' struct on_pointer_anon_buf_ty_pos { int count; @@ -108,7 +108,7 @@ struct on_pointer_anon_buf_ty_pos { // CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' // CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' -// CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' +// CHECK-NEXT: | |-Field {{.+}} field_index 0 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' // CHECK-NEXT: | `-Field {{.+}} 'count' 'int' struct on_pointer_anon_count_ty_pos { struct { diff --git a/clang/test/AST/attr-sized-by-struct-ptrs.c b/clang/test/AST/attr-sized-by-struct-ptrs.c index 7f7e3dfea2ac7..738eaf8cbf36b 100644 --- a/clang/test/AST/attr-sized-by-struct-ptrs.c +++ b/clang/test/AST/attr-sized-by-struct-ptrs.c @@ -26,7 +26,7 @@ struct on_member_pointer_complete_ty { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf::(anonymous at [[ANON_STRUCT_PATH]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by(count)':'struct size_known *' struct on_pointer_anon_buf { int count; @@ -94,7 +94,7 @@ struct on_nested_pointer_outer { // CHECK-NEXT: | `-FieldDecl {{.+}} buf 'struct size_known * __sized_by(count)':'struct size_known *' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2:.+]])' // CHECK-NEXT: `-IndirectFieldDecl {{.+}} implicit buf 'struct size_known * __sized_by(count)':'struct size_known *' -// CHECK-NEXT: |-Field {{.+}} '' 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' +// CHECK-NEXT: |-Field {{.+}} field_index 1 'struct on_pointer_anon_buf_ty_pos::(anonymous at [[ANON_STRUCT_PATH2]])' // CHECK-NEXT: `-Field {{.+}} 'buf' 'struct size_known * __sized_by(count)':'struct size_known *' struct on_pointer_anon_buf_ty_pos { int count; @@ -108,7 +108,7 @@ struct on_pointer_anon_buf_ty_pos { // CHECK-NEXT: | `-FieldDecl {{.+}} count 'int' // CHECK-NEXT: |-FieldDecl {{.+}} implicit 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3:.+]])' // CHECK-NEXT: |-IndirectFieldDecl {{.+}} implicit referenced count 'int' -// CHECK-NEXT: | |-Field {{.+}} '' 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' +// CHECK-NEXT: | |-Field {{.+}} field_index 0 'struct on_pointer_anon_count_ty_pos::(anonymous at [[ANON_STRUCT_PATH3]])' // CHECK-NEXT: | `-Field {{.+}} 'count' 'int' struct on_pointer_anon_count_ty_pos { struct { diff --git a/clang/test/AST/gen_ast_dump_json_test.py b/clang/test/AST/gen_ast_dump_json_test.py index 301d60e479dbf..39b8eaadbad32 100644 --- a/clang/test/AST/gen_ast_dump_json_test.py +++ b/clang/test/AST/gen_ast_dump_json_test.py @@ -83,6 +83,12 @@ def main(): action="store", default="", ) + parser.add_argument( + "--prefix", + help="The FileCheck prefix", + action="store", + default="CHECK", + ) update_or_generate_group = parser.add_mutually_exclusive_group() update_or_generate_group.add_argument( "--update", help="Update the file in-place", action="store_true" @@ -113,11 +119,18 @@ def main(): cmdline_opts=args.opts, do_update=args.update, force_update=args.update_manual, + prefix=args.prefix, ) def process_file( - source_file, clang_binary, cmdline_filters, cmdline_opts, do_update, force_update + source_file, + clang_binary, + cmdline_filters, + cmdline_opts, + do_update, + force_update, + prefix, ): note_firstline = ( "// NOTE: CHECK lines have been autogenerated by " "gen_ast_dump_json_test.py" @@ -227,14 +240,14 @@ def process_file( for out_ast in out_asts: append_str = json.dumps(out_ast, indent=1, ensure_ascii=False) out_str = "\n\n" - out_str += "// CHECK-NOT: {{^}}Dumping\n" + out_str += f"// {prefix}-NOT: {{{{^}}}}Dumping\n" index = 0 for append_line in append_str.splitlines()[2:]: if index == 0: - out_str += "// CHECK: %s\n" % (append_line.rstrip()) + out_str += f"// {prefix}: %s\n" % (append_line.rstrip()) index += 1 else: - out_str += "// CHECK-NEXT: %s\n" % (append_line.rstrip()) + out_str += f"// {prefix}-NEXT: %s\n" % (append_line.rstrip()) f.write(out_str) f.flush() diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp index 215238a7fcf07..8da415a818a82 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp @@ -31,6 +31,7 @@ class Foo { public: Foo(); void bar(); + RefCountable& obj1() const { return m_obj1; } private: const Ref m_obj1; @@ -41,6 +42,7 @@ void Foo::bar() { m_obj1->method(); m_obj2->method(); // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + obj1().method(); } } // namespace call_args_const_ref_member @@ -100,6 +102,7 @@ class Foo { public: Foo(); void bar(); + RefCountable& obj1() { return m_obj1; } private: const UniqueRef m_obj1; @@ -110,6 +113,7 @@ void Foo::bar() { m_obj1->method(); m_obj2->method(); // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + obj1().method(); } } // namespace call_args_const_unique_ref diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h index 85397c2d25951..a1f0cc8b046b9 100644 --- a/clang/test/Analysis/Checkers/WebKit/mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h @@ -289,6 +289,7 @@ class UniqueRef { u.t = nullptr; } T &get() const { return *t; } + operator T&() const { return *t; } T *operator->() const { return t; } UniqueRef &operator=(T &) { return *this; } }; diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp index 2173245bc7af3..4f4a960282253 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp @@ -63,6 +63,19 @@ template Function adopt(Detail::Callab return Function(impl, Function::Adopt); } +template +class HashMap { +public: + HashMap(); + HashMap([[clang::noescape]] const Function&); + void ensure(const KeyType&, [[clang::noescape]] const Function&); + bool operator+([[clang::noescape]] const Function&) const; + static void ifAny(HashMap, [[clang::noescape]] const Function&); + +private: + ValueType* m_table { nullptr }; +}; + } // namespace WTF struct A { @@ -252,13 +265,40 @@ struct RefCountableWithLambdaCapturingThis { call(lambda); } - void method_captures_this_with_guardian_refPtr() { + void method_captures_this_with_guardian_refptr() { auto lambda = [this, protectedThis = RefPtr { &*this }]() { nonTrivial(); }; call(lambda); } + void forEach(const WTF::Function&); + void method_captures_this_with_lambda_with_no_escape() { + auto run = [&]([[clang::noescape]] const WTF::Function& func) { + forEach(func); + }; + run([&](RefCountable&) { + nonTrivial(); + }); + } + + static void callLambda([[clang::noescape]] const WTF::Function()>&); + void method_captures_this_in_template_method() { + RefCountable* obj = make_obj(); + WTF::HashMap> nextMap; + nextMap.ensure(3, [&] { + return obj->next(); + }); + nextMap+[&] { + return obj->next(); + }; + WTF::HashMap>::ifAny(nextMap, [&](auto& item) -> bool { + return item->next() && obj->next(); + }); + callLambda([&]() -> RefPtr { + return obj->next(); + }); + } }; struct NonRefCountableWithLambdaCapturingThis { diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp index d654d963a4fae..ffeecbf87c451 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp @@ -368,6 +368,11 @@ class RefCounted { } RefPtr trivial66() { return children[0]; } Ref trivial67() { return *children[0]; } + struct point { + double x; + double y; + }; + void trivial68() { point pt = { 1.0 }; } static RefCounted& singleton() { static RefCounted s_RefCounted; @@ -554,6 +559,7 @@ class UnrelatedClass { getFieldTrivial().trivial65(); // no-warning getFieldTrivial().trivial66()->trivial6(); // no-warning getFieldTrivial().trivial67()->trivial6(); // no-warning + getFieldTrivial().trivial68(); // no-warning RefCounted::singleton().trivial18(); // no-warning RefCounted::singleton().someFunction(); // no-warning diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm index 9ad1880e9d118..08319016023e3 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm @@ -1,11 +1,14 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s -// expected-no-diagnostics #import "mock-types.h" #import "mock-system-header.h" #import "../../Inputs/system-header-simulator-for-objc-dealloc.h" -@interface Foo : NSObject +@interface Foo : NSObject { + const Ref _obj1; + const RefPtr _obj2; + Ref _obj3; +} @property (nonatomic, readonly) RefPtr countable; @@ -17,6 +20,11 @@ @implementation Foo - (void)execute { self._protectedRefCountable->method(); + _obj1->method(); + _obj1.get().method(); + (*_obj2).method(); + _obj3->method(); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} } - (RefPtr)_protectedRefCountable { @@ -30,6 +38,7 @@ - (void)execute { void ref() const; void deref() const; Ref copy() const; + void method(); }; @interface WrapperObj : NSObject diff --git a/clang/test/Analysis/Inputs/ctu-test-import-failure-import.cpp b/clang/test/Analysis/Inputs/ctu-test-import-failure-import.cpp new file mode 100644 index 0000000000000..ffe860870a214 --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-test-import-failure-import.cpp @@ -0,0 +1,52 @@ +namespace std { +inline namespace __cxx11 { +template +class basic_string; +} +template class basic_istream; +template struct __get_first_arg; +struct allocator_traits { + using type = __get_first_arg; +}; +} // namespace std +namespace std { +inline namespace __cxx11 { +template class basic_string { + allocator_traits _M_allocated_capacity; + void _M_assign(); +}; +} // namespace __cxx11 +} // namespace std +namespace std { +template void operator!=(_Alloc, _CharT); +template +basic_istream<_CharT, _Traits> &getline(basic_istream<_CharT, _Traits> &, + basic_string<_CharT, _Traits, _Alloc> &, + _CharT); +} // namespace std +namespace std { +template +void basic_string<_CharT, _Traits, _Alloc>::_M_assign() { + this != 0; +} +template +basic_istream<_CharT, _Traits> &getline(basic_istream<_CharT, _Traits> &, + basic_string<_CharT, _Traits, _Alloc> &, + _CharT) {} +} // namespace std +struct CommandLineOptionDefinition { + void *OutAddress; +}; +struct CommandLineCommand { + CommandLineOptionDefinition Options; +}; +namespace CommandLine { +extern const CommandLineCommand RootCommands[]; +extern const int RootExamples[]; +} // namespace CommandLine +using utf8 = char; +using u8string = std::basic_string; +u8string _rct2DataPath; +CommandLineOptionDefinition StandardOptions{&_rct2DataPath}; +const CommandLineCommand CommandLine::RootCommands[]{StandardOptions}; +const int CommandLine::RootExamples[]{}; diff --git a/clang/test/Analysis/Inputs/ctu-test-import-failure-import.cpp.externalDefMap.ast-dump.txt b/clang/test/Analysis/Inputs/ctu-test-import-failure-import.cpp.externalDefMap.ast-dump.txt new file mode 100644 index 0000000000000..6ffb3795d3e36 --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-test-import-failure-import.cpp.externalDefMap.ast-dump.txt @@ -0,0 +1,5 @@ +47:c:@N@std@S@allocator_traits@F@allocator_traits# ctu-test-import-failure-import.cpp.ast +29:c:@N@CommandLine@RootCommands ctu-test-import-failure-import.cpp.ast +55:c:@N@std@N@__cxx11@ST>3#T#T#T@basic_string@F@_M_assign# ctu-test-import-failure-import.cpp.ast +97:c:@S@CommandLineOptionDefinition@F@CommandLineOptionDefinition#&1$@S@CommandLineOptionDefinition# ctu-test-import-failure-import.cpp.ast +29:c:@N@CommandLine@RootExamples ctu-test-import-failure-import.cpp.ast \ No newline at end of file diff --git a/clang/test/Analysis/NewDelete-checker-test.cpp b/clang/test/Analysis/NewDelete-checker-test.cpp index 21b4cf817b5df..06754f669b1e6 100644 --- a/clang/test/Analysis/NewDelete-checker-test.cpp +++ b/clang/test/Analysis/NewDelete-checker-test.cpp @@ -441,3 +441,31 @@ void testLeakBecauseNTTPIsNotDeallocation() { void* p = ::operator new(10); deallocate_via_nttp(p); } // leak-warning{{Potential leak of memory pointed to by 'p'}} + +namespace optional_union { + template + class unique_ptr { + T *q; + public: + unique_ptr() : q(new T) {} + ~unique_ptr() { + delete q; + } + }; + + union custom_union_t { + unique_ptr present; + char notpresent; + custom_union_t() : present(unique_ptr()) {} + ~custom_union_t() {} + }; + + void testUnionCorrect() { + custom_union_t a; + a.present.~unique_ptr(); + } + + void testUnionLeak() { + custom_union_t a; + } // leak-warning{{Potential leak of memory pointed to by 'a.present.q'}} +} diff --git a/clang/test/Analysis/anonymous-decls.cpp b/clang/test/Analysis/anonymous-decls.cpp new file mode 100644 index 0000000000000..211184523aa51 --- /dev/null +++ b/clang/test/Analysis/anonymous-decls.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++20 %s 2>&1 | FileCheck %s + +struct A { + static A a; + char b; + friend bool operator==(A, A) = default; +}; +bool _ = A() == A::a; + +// FIXME: steps 1 and 5 show anonymous function parameters are +// not handled correctly. + +// CHECK-LABEL: bool operator==(A, A) noexcept = default +// CHECK-NEXT: [B2 (ENTRY)] +// CHECK-NEXT: Succs (1): B1 +// CHECK: [B1] +// CHECK-NEXT: 1: function-parameter-0-0 +// CHECK-NEXT: 2: [B1.1].b +// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, LValueToRValue, char) +// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, IntegralCast, int) +// CHECK-NEXT: 5: function-parameter-0-1 +// CHECK-NEXT: 6: [B1.5].b +// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, LValueToRValue, char) +// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, IntegralCast, int) +// CHECK-NEXT: 9: [B1.4] == [B1.8] +// CHECK-NEXT: 10: return [B1.9]; +// CHECK-NEXT: Preds (1): B2 +// CHECK-NEXT: Succs (1): B0 +// CHECK: [B0 (EXIT)] +// CHECK-NEXT: Preds (1): B1 + +namespace std { +template struct iterator_traits; +template struct pair; +template struct iterator_traits<_Tp *> { + typedef _Tp &reference; +}; +template struct tuple_element; +template struct tuple_size; +template struct tuple_size> { + static const int value = 2; +}; +template struct tuple_element<0, pair<_T1, _T2>> { + using type = _T1; +}; +template struct tuple_element<1, pair<_T1, _T2>> { + using type = _T2; +}; +template +tuple_element<_Ip, pair<_T1, _T2>>::type get(pair<_T1, _T2> &); +struct __wrap_iter { + iterator_traits *>::reference operator*(); + void operator++(); +}; +bool operator!=(__wrap_iter, __wrap_iter); +struct vector { + __wrap_iter begin(); + __wrap_iter end(); +}; +} // namespace std +int main() { + std::vector v; + for (auto &[a, b] : v) + ; +} + +// FIXME: On steps 8 and 14, a decomposition is referred by name, which they never have. + +// CHECK-LABEL: int main() +// CHECK: [B3] +// CHECK-NEXT: 1: operator* +// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, FunctionToPointerDecay, iterator_traits *>::reference (*)(void)) +// CHECK-NEXT: 3: __begin1 +// CHECK-NEXT: 4: * [B3.3] (OperatorCall) +// CHECK-NEXT: 5: auto &; +// CHECK-NEXT: 6: get<0UL> +// CHECK-NEXT: 7: [B3.6] (ImplicitCastExpr, FunctionToPointerDecay, typename tuple_element<0L, pair >::type (*)(pair &)) +// CHECK-NEXT: 8: decomposition-a-b +// CHECK-NEXT: 9: [B3.7]([B3.8]) +// CHECK-NEXT: 10: [B3.9] +// CHECK-NEXT: 11: std::tuple_element<0, std::pair>::type a = get<0UL>(decomposition-a-b); +// CHECK-NEXT: 12: get<1UL> +// CHECK-NEXT: 13: [B3.12] (ImplicitCastExpr, FunctionToPointerDecay, typename tuple_element<1L, pair >::type (*)(pair &)) +// CHECK-NEXT: 14: decomposition-a-b +// CHECK-NEXT: 15: [B3.13]([B3.14]) +// CHECK-NEXT: 16: [B3.15] +// CHECK-NEXT: 17: std::tuple_element<1, std::pair>::type b = get<1UL>(decomposition-a-b); +// CHECK-NEXT: Preds (1): B1 +// CHECK-NEXT: Succs (1): B2 diff --git a/clang/test/Analysis/array-bound-v2-constraint-check.c b/clang/test/Analysis/array-bound-v2-constraint-check.c deleted file mode 100644 index 91f748e655ce2..0000000000000 --- a/clang/test/Analysis/array-bound-v2-constraint-check.c +++ /dev/null @@ -1,112 +0,0 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,alpha.security.ArrayBoundV2,debug.ExprInspection \ -// RUN: -analyzer-config eagerly-assume=false -verify %s - -void clang_analyzer_eval(int); -void clang_analyzer_printState(void); - -typedef typeof(sizeof(int)) size_t; -const char a[] = "abcd"; // extent: 5 bytes - -void symbolic_size_t_and_int0(size_t len) { - (void)a[len + 1]; // no-warning - // We infered that the 'len' must be in a specific range to make the previous indexing valid. - // len: [0,3] - clang_analyzer_eval(len <= 3); // expected-warning {{TRUE}} - clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} -} - -void symbolic_size_t_and_int1(size_t len) { - (void)a[len]; // no-warning - // len: [0,4] - clang_analyzer_eval(len <= 4); // expected-warning {{TRUE}} - clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} -} - -void symbolic_size_t_and_int2(size_t len) { - (void)a[len - 1]; // no-warning - // len: [1,5] - clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} - clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} -} - -void symbolic_uint_and_int0(unsigned len) { - (void)a[len + 1]; // no-warning - // len: [0,3] - clang_analyzer_eval(0 <= len && len <= 3); // expected-warning {{TRUE}} - clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} -} - -void symbolic_uint_and_int1(unsigned len) { - (void)a[len]; // no-warning - // len: [0,4] - clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} - clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} -} -void symbolic_uint_and_int2(unsigned len) { - (void)a[len - 1]; // no-warning - // len: [1,5] - clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} - clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} -} - -void symbolic_int_and_int0(int len) { - (void)a[len + 1]; // no-warning - // len: [-1,3] - clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} - clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} -} -void symbolic_int_and_int1(int len) { - (void)a[len]; // no-warning - // len: [0,4] - clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} - clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} -} -void symbolic_int_and_int2(int len) { - (void)a[len - 1]; // no-warning - // len: [1,5] - clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} - clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} -} - -void symbolic_longlong_and_int0(long long len) { - (void)a[len + 1]; // no-warning - // len: [-1,3] - clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} - clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} -} - -void *malloc(size_t); -void free(void *); -void symbolic_longlong_and_int0_dynamic_extent(long long len) { - char *b = malloc(5); - (void)b[len + 1]; // no-warning - // len: [-1,3] - clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} - clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} - free(b); -} - -void symbolic_longlong_and_int1(long long len) { - (void)a[len]; // no-warning - // len: [0,4] - clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} - clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} -} - -void symbolic_longlong_and_int2(long long len) { - (void)a[len - 1]; // no-warning - // len: [1,5] - clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} - clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} - clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} -} diff --git a/clang/test/Analysis/bugfix-124477.m b/clang/test/Analysis/bugfix-124477.m new file mode 100644 index 0000000000000..80820f4c93444 --- /dev/null +++ b/clang/test/Analysis/bugfix-124477.m @@ -0,0 +1,39 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,apiModeling,nullability.NullableDereferenced,nullability.NullabilityBase -x objective-c %s +/* + This test is reduced from a static analyzer crash. The bug causing + the crash is explained in #124477. It can only be triggered in some + rare cases so please do not modify this reproducer. +*/ + +#pragma clang assume_nonnull begin +# 15 "some-sys-header.h" 1 3 +@class NSArray, NSObject; + +@interface Base +@property (readonly, copy) NSArray *array; +@end + +#pragma clang assume_nonnull end +# 8 "this-file.m" 2 + + +@interface Test : Base + +@property (readwrite, copy, nullable) NSObject *label; +@property (readwrite, strong, nullable) Test * field; + +- (void)f; + +@end + +@implementation Test +- (void)f +{ + NSObject * X; + + for (NSObject *ele in self.field.array) {} + self.label = X; +} +@end + + diff --git a/clang/test/Analysis/copy-elision.cpp b/clang/test/Analysis/copy-elision.cpp index cd941854fc7f1..e69f52f351f1b 100644 --- a/clang/test/Analysis/copy-elision.cpp +++ b/clang/test/Analysis/copy-elision.cpp @@ -154,20 +154,26 @@ class ClassWithoutDestructor { void push() { v.push(this); } }; +// Two warnings on no-elide: arg v holds the address of the temporary, and we +// are returning an object which holds v which holds the address of the temporary ClassWithoutDestructor make1(AddressVector &v) { - return ClassWithoutDestructor(v); + return ClassWithoutDestructor(v); // no-elide-warning{{Address of stack memory associated with temporary object of type 'ClassWithoutDestructor' returned to caller}} // no-elide-warning@-1 {{Address of stack memory associated with temporary \ object of type 'ClassWithoutDestructor' is still \ referred to by the caller variable 'v' upon returning to the caller}} } +// Two warnings on no-elide: arg v holds the address of the temporary, and we +// are returning an object which holds v which holds the address of the temporary ClassWithoutDestructor make2(AddressVector &v) { - return make1(v); + return make1(v); // no-elide-warning{{Address of stack memory associated with temporary object of type 'ClassWithoutDestructor' returned to caller}} // no-elide-warning@-1 {{Address of stack memory associated with temporary \ object of type 'ClassWithoutDestructor' is still \ referred to by the caller variable 'v' upon returning to the caller}} } +// Two warnings on no-elide: arg v holds the address of the temporary, and we +// are returning an object which holds v which holds the address of the temporary ClassWithoutDestructor make3(AddressVector &v) { - return make2(v); + return make2(v); // no-elide-warning{{Address of stack memory associated with temporary object of type 'ClassWithoutDestructor' returned to caller}} // no-elide-warning@-1 {{Address of stack memory associated with temporary \ object of type 'ClassWithoutDestructor' is still \ referred to by the caller variable 'v' upon returning to the caller}} @@ -298,21 +304,26 @@ to by the caller variable 'v' upon returning to the caller}} #endif } - +// Two warnings on no-elide: arg v holds the address of the temporary, and we +// are returning an object which holds v which holds the address of the temporary ClassWithDestructor make1(AddressVector &v) { - return ClassWithDestructor(v); + return ClassWithDestructor(v); // no-elide-warning{{Address of stack memory associated with temporary object of type 'ClassWithDestructor' returned to caller}} // no-elide-warning@-1 {{Address of stack memory associated with temporary \ object of type 'ClassWithDestructor' is still referred \ to by the caller variable 'v' upon returning to the caller}} } +// Two warnings on no-elide: arg v holds the address of the temporary, and we +// are returning an object which holds v which holds the address of the temporary ClassWithDestructor make2(AddressVector &v) { - return make1(v); + return make1(v); // no-elide-warning{{Address of stack memory associated with temporary object of type 'ClassWithDestructor' returned to caller}} // no-elide-warning@-1 {{Address of stack memory associated with temporary \ object of type 'ClassWithDestructor' is still referred \ to by the caller variable 'v' upon returning to the caller}} } +// Two warnings on no-elide: arg v holds the address of the temporary, and we +// are returning an object which holds v which holds the address of the temporary ClassWithDestructor make3(AddressVector &v) { - return make2(v); + return make2(v); // no-elide-warning{{Address of stack memory associated with temporary object of type 'ClassWithDestructor' returned to caller}} // no-elide-warning@-1 {{Address of stack memory associated with temporary \ object of type 'ClassWithDestructor' is still referred \ to by the caller variable 'v' upon returning to the caller}} diff --git a/clang/test/Analysis/ctu-test-import-failure.cpp b/clang/test/Analysis/ctu-test-import-failure.cpp new file mode 100644 index 0000000000000..2295a66538fc9 --- /dev/null +++ b/clang/test/Analysis/ctu-test-import-failure.cpp @@ -0,0 +1,34 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: mkdir -p %t/ctudir +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++17 \ +// RUN: -emit-pch -o %t/ctudir/ctu-test-import-failure-import.cpp.ast %S/Inputs/ctu-test-import-failure-import.cpp +// RUN: cp %S/Inputs/ctu-test-import-failure-import.cpp.externalDefMap.ast-dump.txt %t/ctudir/externalDefMap.txt +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -std=c++17 -analyze \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-config experimental-enable-naive-ctu-analysis=true \ +// RUN: -analyzer-config ctu-dir=%t/ctudir \ +// RUN: -verify %s + +// Check that importing this code does not cause crash. +// Import intentionally fails because mismatch of '__get_first_arg'. + +namespace std { +inline namespace __cxx11 {} +template class basic_istream; +struct __get_first_arg; +inline namespace __cxx11 { +template class basic_string; +} +template +basic_istream<_CharT, _Traits> &getline(basic_istream<_CharT, _Traits> &, + basic_string<_CharT, _Traits, _Alloc> &, + _CharT) {} +} // namespace std +namespace CommandLine { +extern const int RootExamples[]; +} + +// expected-warning@Inputs/ctu-test-import-failure-import.cpp:14{{incompatible definitions}} +// expected-warning@Inputs/ctu-test-import-failure-import.cpp:14{{incompatible definitions}} +// expected-note@Inputs/ctu-test-import-failure-import.cpp:14{{no corresponding field here}} +// expected-note@Inputs/ctu-test-import-failure-import.cpp:14{{no corresponding field here}} diff --git a/clang/test/Analysis/dtor-union.cpp b/clang/test/Analysis/dtor-union.cpp new file mode 100644 index 0000000000000..dac366e6f9df8 --- /dev/null +++ b/clang/test/Analysis/dtor-union.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++11 %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++17 %s + +void clang_analyzer_eval(bool); + +struct InlineDtor { + static int cnt; + static int dtorCalled; + ~InlineDtor() { + ++dtorCalled; + } +}; + +int InlineDtor::cnt = 0; +int InlineDtor::dtorCalled = 0; + +void testUnionDtor() { + static int unionDtorCalled; + InlineDtor::cnt = 0; + InlineDtor::dtorCalled = 0; + unionDtorCalled = 0; + { + union UnionDtor { + InlineDtor kind1; + char kind2; + ~UnionDtor() { unionDtorCalled++; } + }; + UnionDtor u1{.kind1{}}; + UnionDtor u2{.kind2{}}; + auto u3 = new UnionDtor{.kind1{}}; + auto u4 = new UnionDtor{.kind2{}}; + delete u3; + delete u4; + } + + clang_analyzer_eval(unionDtorCalled == 4); // expected-warning {{TRUE}} + clang_analyzer_eval(InlineDtor::dtorCalled == 0); // expected-warning {{TRUE}} +} diff --git a/clang/test/Analysis/ftime-trace-bind.cpp b/clang/test/Analysis/ftime-trace-bind.cpp new file mode 100644 index 0000000000000..de121e4316e03 --- /dev/null +++ b/clang/test/Analysis/ftime-trace-bind.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core %s -ftime-trace=%t.raw.json -ftime-trace-granularity=0 -verify +// RUN: %python -c 'import json, sys; print(json.dumps(json.load(sys.stdin), indent=4))' < %t.raw.json > %t.formatted.json +// RUN: FileCheck --input-file=%t.formatted.json --check-prefix=CHECK %s + +// CHECK: "name": "RegionStoreManager::bindArray", +// CHECK-NEXT: "args": { +// +// The below does not necessarily follow immediately, +// depending on what parts of the array are initialized first. +// +// CHECK: "detail": "'arr[0][1]'" +// CHECK-NEXT: } +// +// CHECK: "detail": "'arr[0]'" +// CHECK-NEXT: } +// +// CHECK: "detail": "'arr'" +// CHECK-NEXT: } + +int f() { + int arr[2][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}; + return arr[1][0][1]; +} +// expected-no-diagnostics diff --git a/clang/test/Analysis/ftime-trace-removeDead.cpp b/clang/test/Analysis/ftime-trace-removeDead.cpp new file mode 100644 index 0000000000000..2ffd2ec45908c --- /dev/null +++ b/clang/test/Analysis/ftime-trace-removeDead.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core %s -ftime-trace=%t.raw.json -ftime-trace-granularity=0 -verify +// RUN: %python -c 'import json, sys; print(json.dumps(json.load(sys.stdin), indent=4))' < %t.raw.json > %t.formatted.json +// RUN: FileCheck --input-file=%t.formatted.json --check-prefix=CHECK %s + +// The trace file is rather large, but it should contain at least one scope for removeDead: +// +// CHECK: "name": "ExprEngine::removeDead" + +bool coin(); +int f() { + int x = 0; + int y = 0; + while (coin()) { + x = 1; + } + return x / y; // expected-warning{{Division by zero}} +} diff --git a/clang/test/Analysis/ftime-trace.cpp b/clang/test/Analysis/ftime-trace.cpp new file mode 100644 index 0000000000000..2c369a9bf781e --- /dev/null +++ b/clang/test/Analysis/ftime-trace.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core %s -ftime-trace=%t.raw.json -ftime-trace-granularity=0 -verify +// RUN: %python -c 'import json, sys; print(json.dumps(json.load(sys.stdin), indent=4))' < %t.raw.json > %t.formatted.json +// RUN: FileCheck --input-file=%t.formatted.json --check-prefix=CHECK %s + +// The trace file is rather large, but it should contain at least the duration of the analysis of 'f': +// +// CHECK: "name": "HandleCode f", +// CHECK-NEXT: "args": { +// CHECK-NEXT: "detail": "f()", +// CHECK-NEXT: "file": "{{.+}}ftime-trace.cpp", +// CHECK-NEXT: "line": {{[0-9]+}} +// CHECK-NEXT: } + +// If any reports are found, "flushing" their equivalence class (EQC) is a separate action: +// +// CHECK: "name": "Flushing EQC Division by zero", +// CHECK-NEXT: "args": { +// CHECK-NEXT: "detail": "core.DivideZero", +// CHECK-NEXT: "file": "{{.+}}ftime-trace.cpp", +// CHECK-NEXT: "line": {{[0-9]+}} +// CHECK-NEXT: } + +// The trace also contains durations of each step, but they are so short that they are not reliably present +// in each run. However, they are also aggregated into Total *, for example: +// +// CHECK: "name": "Total Loc PostStmt", +// CHECK-NEXT: "args": { +// CHECK-NEXT: "count": {{[0-9]+}}, +// CHECK-NEXT: "avg ms": {{[0-9]+}} +// CHECK-NEXT: } + +// Additionally, the trace lists checker hook points (again, relying on totals here): +// +// CHECK: "name": "Total CheckerManager::runCheckersForStmt (Pre)", +// CHECK-NEXT: "args": { +// CHECK-NEXT: "count": {{[0-9]+}}, +// CHECK-NEXT: "avg ms": {{[0-9]+}} +// CHECK-NEXT: } + +// Finally, each checker call back is also present: +// +// CHECK: "name": "Total Stmt:core.DivideZero", +// CHECK-NEXT: "args": { +// CHECK-NEXT: "count": {{[0-9]+}}, +// CHECK-NEXT: "avg ms": {{[0-9]+}} +// CHECK-NEXT: } + +bool coin(); +int f() { + int x = 0; + int y = 0; + while (coin()) { + x = 1; + } + return x / y; // expected-warning{{Division by zero}} +} diff --git a/clang/test/Analysis/index-type.c b/clang/test/Analysis/index-type.c index 997d45c1e5aba..818806c4aff3b 100644 --- a/clang/test/Analysis/index-type.c +++ b/clang/test/Analysis/index-type.c @@ -1,5 +1,5 @@ -// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -Wno-implicit-function-declaration -verify %s -// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -Wno-implicit-function-declaration -DM32 -verify %s +// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,security.ArrayBound -Wno-implicit-function-declaration -verify %s +// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,security.ArrayBound -Wno-implicit-function-declaration -DM32 -verify %s // expected-no-diagnostics #define UINT_MAX (~0u) diff --git a/clang/test/Analysis/live-stmts.cpp b/clang/test/Analysis/live-stmts.cpp index c60f522588e39..33b8d59305d3d 100644 --- a/clang/test/Analysis/live-stmts.cpp +++ b/clang/test/Analysis/live-stmts.cpp @@ -1,3 +1,6 @@ +// Flaky on aarch64: http://llvm.org/PR126619 +// UNSUPPORTED: target=aarch64{{.*}} + // RUN: %clang_analyze_cc1 -w -analyzer-checker=debug.DumpLiveExprs %s 2>&1\ // RUN: | FileCheck %s diff --git a/clang/test/Analysis/misc-ps-region-store.m b/clang/test/Analysis/misc-ps-region-store.m index a882e7eb0dc90..bd8b3350ba6da 100644 --- a/clang/test/Analysis/misc-ps-region-store.m +++ b/clang/test/Analysis/misc-ps-region-store.m @@ -1,5 +1,5 @@ -// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -verify -fblocks -Wno-objc-root-class -Wno-strict-prototypes -Wno-error=implicit-function-declaration %s -// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -verify -fblocks -Wno-objc-root-class -Wno-strict-prototypes -Wno-error=implicit-function-declaration %s +// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,security.ArrayBound -verify -fblocks -Wno-objc-root-class -Wno-strict-prototypes -Wno-error=implicit-function-declaration %s +// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,security.ArrayBound -verify -fblocks -Wno-objc-root-class -Wno-strict-prototypes -Wno-error=implicit-function-declaration %s typedef long unsigned int size_t; void *memcpy(void *, const void *, size_t); @@ -928,7 +928,7 @@ void pr6288_pos(int z) { int *px[1]; int i; for (i = 0; i < z; i++) - px[i] = &x[i]; // expected-warning{{Access out-of-bound array element (buffer overflow)}} + px[i] = &x[i]; // expected-warning{{Out of bound access to memory after the end of 'px'}} *(px[0]) = 0; // expected-warning{{Dereference of undefined pointer value}} } @@ -976,12 +976,17 @@ - (void) rdar7817800_baz { } @end -// PR 6036 - This test case triggered a crash inside StoreManager::CastRegion because the size -// of 'unsigned long (*)[0]' is 0. +// PR 6036 - This test case triggered a crash inside StoreManager::CastRegion +// because the size of 'unsigned long (*)[0]' is 0. +// NOTE: This old crash was probably triggered via the old alpha checker +// `alpha.security.ArrayBound` (which was logic that's different from the +// current `security.ArrayBound`). Although that code was removed, it's worth +// to keep this testcase as a generic example of a zero-sized type. struct pr6036_a { int pr6036_b; }; struct pr6036_c; void u132monitk (struct pr6036_c *pr6036_d) { - (void) ((struct pr6036_a *) (unsigned long (*)[0]) ((char *) pr6036_d - 1))->pr6036_b; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}} + (void) ((struct pr6036_a *) (unsigned long (*)[0]) ((char *) pr6036_d - 1))->pr6036_b; + // expected-warning@-1 {{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}} } // ?-expressions used as a base of a member expression should be treated as an lvalue diff --git a/clang/test/Analysis/no-outofbounds.c b/clang/test/Analysis/no-outofbounds.c deleted file mode 100644 index 15155729067e9..0000000000000 --- a/clang/test/Analysis/no-outofbounds.c +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,alpha.unix,alpha.security.ArrayBound -verify %s -// expected-no-diagnostics - -//===----------------------------------------------------------------------===// -// This file tests cases where we should not flag out-of-bounds warnings. -//===----------------------------------------------------------------------===// - -void f(void) { - long x = 0; - char *y = (char*) &x; - char c = y[0] + y[1] + y[2]; // no-warning - short *z = (short*) &x; - short s = z[0] + z[1]; // no-warning -} - -void g(void) { - int a[2]; - char *b = (char*)a; - b[3] = 'c'; // no-warning -} - -typedef typeof(sizeof(int)) size_t; -void *malloc(size_t); -void free(void *); - -void field(void) { - struct vec { size_t len; int data[0]; }; - struct vec *a = malloc(sizeof(struct vec) + 10*sizeof(int)); - a->len = 10; - a->data[1] = 5; // no-warning - free(a); -} diff --git a/clang/test/Analysis/null-deref-path-notes.cpp b/clang/test/Analysis/null-deref-path-notes.cpp index c7b0619e297b3..a37bbfe41a2c7 100644 --- a/clang/test/Analysis/null-deref-path-notes.cpp +++ b/clang/test/Analysis/null-deref-path-notes.cpp @@ -23,3 +23,38 @@ void c::f(B &g, int &i) { f(h, b); // expected-note{{Calling 'c::f'}} } } + +namespace GH124975 { +void no_crash_in_br_visitors(int *p) { + if (p) {} + // expected-note@-1 {{Assuming 'p' is null}} + // expected-note@-2 {{Taking false branch}} + + extern bool ExternLocalCoin; + // expected-note@+2 {{Assuming 'ExternLocalCoin' is false}} + // expected-note@+1 {{Taking false branch}} + if (ExternLocalCoin) + return; + + *p = 4; + // expected-warning@-1 {{Dereference of null pointer (loaded from variable 'p')}} + // expected-note@-2 {{Dereference of null pointer (loaded from variable 'p')}} +} + +// Thread local variables are implicitly static, so let's test them too. +void thread_local_alternative(int *p) { + if (p) {} + // expected-note@-1 {{Assuming 'p' is null}} + // expected-note@-2 {{Taking false branch}} + + thread_local bool ThreadLocalCoin; + // expected-note@+2 {{'ThreadLocalCoin' is false}} + // expected-note@+1 {{Taking false branch}} + if (ThreadLocalCoin) + return; + + *p = 4; + // expected-warning@-1 {{Dereference of null pointer (loaded from variable 'p')}} + // expected-note@-2 {{Dereference of null pointer (loaded from variable 'p')}} +} +} // namespace GH124975 diff --git a/clang/test/Analysis/out-of-bounds-constraint-check.c b/clang/test/Analysis/out-of-bounds-constraint-check.c new file mode 100644 index 0000000000000..df48c8c170713 --- /dev/null +++ b/clang/test/Analysis/out-of-bounds-constraint-check.c @@ -0,0 +1,112 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,security.ArrayBound,debug.ExprInspection \ +// RUN: -analyzer-config eagerly-assume=false -verify %s + +void clang_analyzer_eval(int); +void clang_analyzer_printState(void); + +typedef typeof(sizeof(int)) size_t; +const char a[] = "abcd"; // extent: 5 bytes + +void symbolic_size_t_and_int0(size_t len) { + (void)a[len + 1]; // no-warning + // We infered that the 'len' must be in a specific range to make the previous indexing valid. + // len: [0,3] + clang_analyzer_eval(len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} +} + +void symbolic_size_t_and_int1(size_t len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} + +void symbolic_size_t_and_int2(size_t len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} + +void symbolic_uint_and_int0(unsigned len) { + (void)a[len + 1]; // no-warning + // len: [0,3] + clang_analyzer_eval(0 <= len && len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} +} + +void symbolic_uint_and_int1(unsigned len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} +void symbolic_uint_and_int2(unsigned len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} + +void symbolic_int_and_int0(int len) { + (void)a[len + 1]; // no-warning + // len: [-1,3] + clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} +} +void symbolic_int_and_int1(int len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} +void symbolic_int_and_int2(int len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} + +void symbolic_longlong_and_int0(long long len) { + (void)a[len + 1]; // no-warning + // len: [-1,3] + clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} +} + +void *malloc(size_t); +void free(void *); +void symbolic_longlong_and_int0_dynamic_extent(long long len) { + char *b = malloc(5); + (void)b[len + 1]; // no-warning + // len: [-1,3] + clang_analyzer_eval(-1 <= len && len <= 3); // expected-warning {{TRUE}} + clang_analyzer_eval(0 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 2); // expected-warning {{UNKNOWN}} + free(b); +} + +void symbolic_longlong_and_int1(long long len) { + (void)a[len]; // no-warning + // len: [0,4] + clang_analyzer_eval(0 <= len && len <= 4); // expected-warning {{TRUE}} + clang_analyzer_eval(1 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 3); // expected-warning {{UNKNOWN}} +} + +void symbolic_longlong_and_int2(long long len) { + (void)a[len - 1]; // no-warning + // len: [1,5] + clang_analyzer_eval(1 <= len && len <= 5); // expected-warning {{TRUE}} + clang_analyzer_eval(2 <= len); // expected-warning {{UNKNOWN}} + clang_analyzer_eval(len <= 4); // expected-warning {{UNKNOWN}} +} diff --git a/clang/test/Analysis/out-of-bounds-diagnostics.c b/clang/test/Analysis/out-of-bounds-diagnostics.c index 65bc28f58276f..524fa4e2aaaf7 100644 --- a/clang/test/Analysis/out-of-bounds-diagnostics.c +++ b/clang/test/Analysis/out-of-bounds-diagnostics.c @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-output=text \ -// RUN: -analyzer-checker=core,alpha.security.ArrayBoundV2,unix.Malloc,optin.taint -verify %s +// RUN: -analyzer-checker=core,security.ArrayBound,unix.Malloc,optin.taint -verify %s int TenElements[10]; @@ -231,7 +231,16 @@ int arrayOfStructsArrow(void) { // expected-note@-2 {{Access of 'itemArray' at index 35, while it holds only 20 'struct item' elements}} } +char convertedScalar(long long var) { + char *p = ((char*)&var); + (void) p[3]; // no-warning + return p[13]; + // expected-warning@-1 {{Out of bound access to memory after the end of 'var'}} + // expected-note@-2 {{Access of 'var' at index 13, while it holds only 8 'char' elements}} +} + short convertedArray(void) { + (void) ((short*)TenElements)[17]; // no-warning return ((short*)TenElements)[47]; // expected-warning@-1 {{Out of bound access to memory after the end of 'TenElements'}} // expected-note@-2 {{Access of 'TenElements' at index 47, while it holds only 20 'short' elements}} @@ -268,23 +277,41 @@ int intFromStringDivisible(void) { typedef __typeof(sizeof(int)) size_t; void *malloc(size_t size); +void free(void *mem); int *mallocRegion(void) { int *mem = (int*)malloc(2*sizeof(int)); + mem[1] = 48; // no-warning + mem[3] = -2; // expected-warning@-1 {{Out of bound access to memory after the end of the heap area}} // expected-note@-2 {{Access of the heap area at index 3, while it holds only 2 'int' elements}} return mem; } +typedef struct { size_t len; int data[0]; } vec_t; + +void mallocFlexibleArray(void) { + vec_t *v = malloc(sizeof(vec_t) + 10 * sizeof(int)); + v->len = 10; + v->data[1] = 5; // no-warning + v->data[11] = 99; + // TODO: Here ideally we would expect + // {{Out of bound access to memory after the end of the heap area}} + // {{Access of the heap area at index 11, while it holds only 10 'int' elements}} + // but the analyzer cannot (yet) deduce the size of the flexible array member + // from the size of the whole allocated area. + free(v); +} + int *custom_calloc(size_t a, size_t b) { size_t res; return __builtin_mul_overflow(a, b, &res) ? 0 : malloc(res); } -int *mallocRegionOverflow(void) { +int *mallocMulOverflow(void) { int *mem = (int*)custom_calloc(10, sizeof(int)); mem[20] = 10; diff --git a/clang/test/Analysis/out-of-bounds-new.cpp b/clang/test/Analysis/out-of-bounds-new.cpp index f541bdf810d79..4e5442422bff4 100644 --- a/clang/test/Analysis/out-of-bounds-new.cpp +++ b/clang/test/Analysis/out-of-bounds-new.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s +// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,security.ArrayBound -verify %s // Tests doing an out-of-bounds access after the end of an array using: // - constant integer index diff --git a/clang/test/Analysis/out-of-bounds-notes.c b/clang/test/Analysis/out-of-bounds-notes.c index 391089b6a35d8..7256beb7e893e 100644 --- a/clang/test/Analysis/out-of-bounds-notes.c +++ b/clang/test/Analysis/out-of-bounds-notes.c @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-output=text \ -// RUN: -analyzer-checker=core,alpha.security.ArrayBoundV2,unix.Malloc,optin.taint -verify %s +// RUN: -analyzer-checker=core,security.ArrayBound,unix.Malloc,optin.taint -verify %s int TenElements[10]; diff --git a/clang/test/Analysis/out-of-bounds.c b/clang/test/Analysis/out-of-bounds.c index 1f771c2b3bd13..923797200d0b4 100644 --- a/clang/test/Analysis/out-of-bounds.c +++ b/clang/test/Analysis/out-of-bounds.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection -verify %s +// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,security.ArrayBound,debug.ExprInspection -verify %s void clang_analyzer_eval(int); @@ -153,7 +153,7 @@ void test_assume_after_access(unsigned long x) { int *get_symbolic(void); void test_underflow_symbolic(void) { int *buf = get_symbolic(); - buf[-1] = 0; // no-warning; + buf[-1] = 0; // no-warning } // But warn if we understand the internal memory layout of a symbolic region. diff --git a/clang/test/Analysis/outofbound-notwork.c b/clang/test/Analysis/outofbound-notwork.c index cf2239cee1301..1318c07bbf2a8 100644 --- a/clang/test/Analysis/outofbound-notwork.c +++ b/clang/test/Analysis/outofbound-notwork.c @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBound -verify %s +// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,security.ArrayBound -verify %s // XFAIL: * // Once we better handle modeling of sizes of VLAs, we can pull this back @@ -9,7 +9,7 @@ void sizeof_vla(int a) { char x[a]; int y[sizeof(x)]; y[4] = 4; // no-warning - y[5] = 5; // expected-warning{{out-of-bound}} + y[5] = 5; // expected-warning{{Out of bounds access}} } } @@ -18,7 +18,7 @@ void sizeof_vla_2(int a) { char x[a]; int y[sizeof(x) / sizeof(char)]; y[4] = 4; // no-warning - y[5] = 5; // expected-warning{{out-of-bound}} + y[5] = 5; // expected-warning{{Out of bounds access}} } } @@ -27,6 +27,6 @@ void sizeof_vla_3(int a) { char x[a]; int y[sizeof(*&*&*&x)]; y[4] = 4; // no-warning - y[5] = 5; // expected-warning{{out-of-bound}} + y[5] = 5; // expected-warning{{Out of bounds access}} } } diff --git a/clang/test/Analysis/outofbound.c b/clang/test/Analysis/outofbound.c index 009cf33f61309..d3d8ff2b2f0ed 100644 --- a/clang/test/Analysis/outofbound.c +++ b/clang/test/Analysis/outofbound.c @@ -1,7 +1,7 @@ // RUN: %clang_analyze_cc1 -Wno-array-bounds -verify %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix \ -// RUN: -analyzer-checker=alpha.security.ArrayBound \ +// RUN: -analyzer-checker=security.ArrayBound \ // RUN: -analyzer-config unix.DynamicMemoryModeling:Optimistic=true typedef __typeof(sizeof(int)) size_t; @@ -11,12 +11,12 @@ void *calloc(size_t, size_t); char f1(void) { char* s = "abcd"; char c = s[4]; // no-warning - return s[5] + c; // expected-warning{{Access out-of-bound array element (buffer overflow)}} + return s[5] + c; // expected-warning{{Out of bound access to memory after}} } void f2(void) { int *p = malloc(12); - p[3] = 4; // expected-warning{{Access out-of-bound array element (buffer overflow)}} + p[3] = 4; // expected-warning{{Out of bound access to memory after}} } struct three_words { @@ -31,7 +31,7 @@ void f3(void) { struct three_words a, *p; p = &a; p[0] = a; // no-warning - p[1] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}} + p[1] = a; // expected-warning{{Out of bound access to memory after}} } void f4(void) { @@ -39,31 +39,33 @@ void f4(void) { struct three_words a, *p = (struct three_words *)&c; p[0] = a; // no-warning p[1] = a; // no-warning - p[2] = a; // expected-warning{{Access out-of-bound array element (buffer overflow)}} + p[2] = a; // should warn + // FIXME: This is an overflow, but currently security.ArrayBound only checks + // that the _beginning_ of the accessed element is within bounds. } void f5(void) { char *p = calloc(2,2); p[3] = '.'; // no-warning - p[4] = '!'; // expected-warning{{out-of-bound}} + p[4] = '!'; // expected-warning{{Out of bound access}} } void f6(void) { char a[2]; int *b = (int*)a; - b[1] = 3; // expected-warning{{out-of-bound}} + b[1] = 3; // expected-warning{{Out of bound access}} } void f7(void) { struct three_words a; - a.c[3] = 1; // expected-warning{{out-of-bound}} + a.c[3] = 1; // expected-warning{{Out of bound access}} } void vla(int a) { if (a == 5) { int x[a]; x[4] = 4; // no-warning - x[5] = 5; // expected-warning{{out-of-bound}} + x[5] = 5; // expected-warning{{Out of bound access}} } } @@ -71,14 +73,14 @@ void alloca_region(int a) { if (a == 5) { char *x = __builtin_alloca(a); x[4] = 4; // no-warning - x[5] = 5; // expected-warning{{out-of-bound}} + x[5] = 5; // expected-warning{{Out of bound access}} } } int symbolic_index(int a) { int x[2] = {1, 2}; if (a == 2) { - return x[a]; // expected-warning{{out-of-bound}} + return x[a]; // expected-warning{{Out of bound access}} } return 0; } @@ -86,7 +88,7 @@ int symbolic_index(int a) { int symbolic_index2(int a) { int x[2] = {1, 2}; if (a < 0) { - return x[a]; // expected-warning{{out-of-bound}} + return x[a]; // expected-warning{{Out of bound access}} } return 0; } @@ -120,7 +122,7 @@ int overflow_binary_search(double in) { } else { eee += 1; } - if (in < ins[eee]) { // expected-warning {{Access out-of-bound array element (buffer overflow)}} + if (in < ins[eee]) { // expected-warning {{Out of bound access}} eee -= 1; } } diff --git a/clang/test/Analysis/rdar-6541136-region.c b/clang/test/Analysis/rdar-6541136-region.c deleted file mode 100644 index f1a3a48a5fe4a..0000000000000 --- a/clang/test/Analysis/rdar-6541136-region.c +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_analyze_cc1 -verify -analyzer-checker=core,alpha.security.ArrayBound %s - -struct tea_cheese { unsigned magic; }; -typedef struct tea_cheese kernel_tea_cheese_t; -extern kernel_tea_cheese_t _wonky_gesticulate_cheese; - -// This test case exercises the ElementRegion::getRValueType() logic. - -void test1( void ) { - kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese; - struct load_wine *cmd = (void*) &wonky[1]; - cmd = cmd; - char *p = (void*) &wonky[1]; - kernel_tea_cheese_t *q = &wonky[1]; - // This test case tests both the RegionStore logic (doesn't crash) and - // the out-of-bounds checking. We don't expect the warning for now since - // out-of-bound checking is temporarily disabled. - kernel_tea_cheese_t r = *q; // expected-warning{{Access out-of-bound array element (buffer overflow)}} -} - -void test1_b( void ) { - kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese; - struct load_wine *cmd = (void*) &wonky[1]; - cmd = cmd; - char *p = (void*) &wonky[1]; - *p = 1; // expected-warning{{Access out-of-bound array element (buffer overflow)}} -} diff --git a/clang/test/Analysis/runtime-regression.c b/clang/test/Analysis/runtime-regression.c index 55988e9df5ee0..9fa0017d5e470 100644 --- a/clang/test/Analysis/runtime-regression.c +++ b/clang/test/Analysis/runtime-regression.c @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 %s \ -// RUN: -analyzer-checker=core,alpha.security.ArrayBoundV2 \ +// RUN: -analyzer-checker=core,security.ArrayBound \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -triple x86_64-unknown-linux-gnu \ // RUN: -verify diff --git a/clang/test/Analysis/stack-addr-ps.cpp b/clang/test/Analysis/stack-addr-ps.cpp index 73e9dbeca460f..bf988d0a16959 100644 --- a/clang/test/Analysis/stack-addr-ps.cpp +++ b/clang/test/Analysis/stack-addr-ps.cpp @@ -90,6 +90,18 @@ int *mf() { return &x; // expected-warning{{Address of stack memory associated with local variable 's1' returned}} expected-warning {{address of stack memory associated with local variable 's1' returned}} } +int *return_assign_expr_leak() { + int x = 1; + int *y; + return y = &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned}} +} + +// Additional diagnostic from -Wreturn-stack-address in the simple case? +int *return_comma_separated_expressions_leak() { + int x = 1; + return (x=14), &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning{{address of stack memory associated with local variable 'x' returned}} +} + void *lf() { label: void *const &x = &&label; // expected-note {{binding reference variable 'x' here}} @@ -152,6 +164,18 @@ namespace rdar13296133 { } } // namespace rdar13296133 +void* ret_cpp_static_cast(short x) { + return static_cast(&x); // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack memory}} +} + +int* ret_cpp_reinterpret_cast(double x) { + return reinterpret_cast(&x); // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack me}} +} + +int* ret_cpp_const_cast(const int x) { + return const_cast(&x); // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack memory}} +} + void write_stack_address_to(char **q) { char local; *q = &local; @@ -178,6 +202,11 @@ void test_copy_elision() { C c1 = make1(); } +C&& return_bind_rvalue_reference_to_temporary() { + return C(); // expected-warning{{Address of stack memory associated with temporary object of type 'C' returned to caller}} + // expected-warning@-1{{returning reference to local temporary object}} -Wreturn-stack-address +} + namespace leaking_via_direct_pointer { void* returned_direct_pointer_top() { int local = 42; @@ -251,7 +280,7 @@ void* lambda_to_context_direct_pointer_uncalled() { int local = 42; p = &local; // no-warning: analyzed only as top-level, ignored explicitly by the checker }; - return new MyFunction(&lambda); + return new MyFunction(&lambda); // expected-warning{{Address of stack memory associated with local variable 'lambda' returned to caller}} } void lambda_to_context_direct_pointer_lifetime_extended() { @@ -340,6 +369,13 @@ void param_ptr_to_ptr_to_ptr_callee(void*** ppp) { **ppp = &local; // expected-warning{{local variable 'local' is still referred to by the caller variable 'pp'}} } +void ***param_ptr_to_ptr_to_ptr_return(void ***ppp) { + int local = 0; + **ppp = &local; + return ppp; + // expected-warning@-1 {{Address of stack memory associated with local variable 'local' is still referred to by the caller variable 'ppp' upon returning to the caller. This will be a dangling reference}} +} + void param_ptr_to_ptr_to_ptr_caller(void** pp) { param_ptr_to_ptr_to_ptr_callee(&pp); } @@ -410,16 +446,16 @@ void** returned_arr_of_ptr_top() { int* p = &local; void** arr = new void*[2]; arr[1] = p; - return arr; -} // no-warning False Negative + return arr; // expected-warning{{Address of stack memory associated with local variable 'local' returned to caller}} +} void** returned_arr_of_ptr_callee() { int local = 42; int* p = &local; void** arr = new void*[2]; arr[1] = p; - return arr; -} // no-warning False Negative + return arr; // expected-warning{{Address of stack memory associated with local variable 'local' returned to caller}} +} void returned_arr_of_ptr_caller() { void** arr = returned_arr_of_ptr_callee(); @@ -466,16 +502,16 @@ void** returned_arr_of_ptr_top(int idx) { int* p = &local; void** arr = new void*[2]; arr[idx] = p; - return arr; -} // no-warning False Negative + return arr; // expected-warning{{Address of stack memory associated with local variable 'local' returned to caller}} +} void** returned_arr_of_ptr_callee(int idx) { int local = 42; int* p = &local; void** arr = new void*[2]; arr[idx] = p; - return arr; -} // no-warning False Negative + return arr; // expected-warning{{Address of stack memory associated with local variable 'local' returned to caller}} +} void returned_arr_of_ptr_caller(int idx) { void** arr = returned_arr_of_ptr_callee(idx); @@ -525,14 +561,25 @@ S returned_struct_with_ptr_top() { int local = 42; S s; s.p = &local; - return s; -} // no-warning False Negative, requires traversing returned LazyCompoundVals + return s; // expected-warning{{Address of stack memory associated with local variable 'local' returned to caller}} +} S returned_struct_with_ptr_callee() { int local = 42; S s; s.p = &local; - return s; // expected-warning{{'local' is still referred to by the caller variable 's'}} + return s; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} expected-warning{{Address of stack memory associated with local variable 'local' is still referred to by the caller variable 's' upon returning to the caller. This will be a dangling reference}} +} + +S leak_through_field_of_returned_object() { + int local = 14; + S s{&local}; + return s; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} +} + +S leak_through_compound_literal() { + int local = 0; + return (S) { &local }; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} } void returned_struct_with_ptr_caller() { @@ -555,6 +602,30 @@ void static_struct_with_ptr() { } } // namespace leaking_via_struct_with_ptr +namespace leaking_via_nested_structs_with_ptr { +struct Inner { + int *ptr; +}; + +struct Outer { + Inner I; +}; + +struct Deriving : public Outer {}; + +Outer leaks_through_nested_objects() { + int local = 0; + Outer O{&local}; + return O; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} +} + +Deriving leaks_through_base_objects() { + int local = 0; + Deriving D{&local}; + return D; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} +} +} // namespace leaking_via_nested_structs_with_ptr + namespace leaking_via_ref_to_struct_with_ptr { struct S { int* p; @@ -613,15 +684,15 @@ S* returned_ptr_to_struct_with_ptr_top() { int local = 42; S* s = new S; s->p = &local; - return s; -} // no-warning False Negative + return s; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} +} S* returned_ptr_to_struct_with_ptr_callee() { int local = 42; S* s = new S; s->p = &local; - return s; -} // no-warning False Negative + return s; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} +} void returned_ptr_to_struct_with_ptr_caller() { S* s = returned_ptr_to_struct_with_ptr_callee(); @@ -676,15 +747,15 @@ S* returned_ptr_to_struct_with_ptr_top() { int local = 42; S* s = new S[2]; s[1].p = &local; - return s; -} // no-warning False Negative + return s; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} +} S* returned_ptr_to_struct_with_ptr_callee() { int local = 42; S* s = new S[2]; s[1].p = &local; - return s; -} // no-warning False Negative + return s; // expected-warning {{Address of stack memory associated with local variable 'local' returned to caller}} +} void returned_ptr_to_struct_with_ptr_caller() { S* s = returned_ptr_to_struct_with_ptr_callee(); @@ -877,3 +948,137 @@ void top_malloc_no_crash_fn() { free(pptr); } } // namespace alloca_region_pointer + +// These all warn with -Wreturn-stack-address also +namespace return_address_of_true_positives { +int* ret_local_addrOf() { + int x = 1; + return &*&x; // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack memory associated with local variable 'x' returned}} +} + +int* ret_local_addrOf_paren() { + int x = 1; + return (&(*(&x))); // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack memory associated with local variable 'x' returned}} +} + +int* ret_local_addrOf_ptr_arith() { + int x = 1; + return &*(&x+1); // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack memory associated with local variable 'x' returned}} +} + +int* ret_local_addrOf_ptr_arith2() { + int x = 1; + return &*(&x+1); // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack memory associated with local variable 'x' returned}} +} + +int* ret_local_field() { + struct { int x; } a; + return &a.x; // expected-warning {{Address of stack memory associated with local variable 'a' returned to caller}} expected-warning {{address of stack memory associated with local variable 'a' returned}} +} + +int& ret_local_field_ref() { + struct { int x; } a; + return a.x; // expected-warning {{Address of stack memory associated with local variable 'a' returned to caller}} expected-warning {{reference to stack memory associated with local variable 'a' returned}} +} +} //namespace return_address_of_true_positives + +namespace true_negatives_return_expressions { +struct Container { int *x; }; + +int test2() { + int x = 14; + return x; // no-warning +} + +void return_void() { + return void(); // no-warning +} + +int return_assign_expr_safe() { + int y, x = 14; + return y = x; // no-warning +} + +int return_comma_separated_expressions_safe() { + int x = 1; + int *y; + return (y=&x), (x=15); // no-warning +} + +int return_comma_separated_expressions_container_safe() { + int x = 1; + Container Other; + return Other = Container{&x}, x = 14; // no-warning +} + +int make_x(); +int return_symbol_safe() { + int x = make_x(); + clang_analyzer_dump(x); // expected-warning-re {{conj_$2{int, {{.+}}}}} + return x; // no-warning +} + +int *return_symbolic_region_safe(int **ptr) { + return *ptr; // no-warning +} + +int *return_arg_ptr(int *arg) { + return arg; // no-warning +} + +// This has a false positive with -Wreturn-stack-address, but CSA should not +// warn on this +int *return_conditional_never_false(int *arg) { + int x = 14; + return true ? arg : &x; // expected-warning {{address of stack memory associated with local variable 'x' returned}} +} + +// This has a false positive with -Wreturn-stack-address, but CSA should not +// warn on this +int *return_conditional_never_true(int *arg) { + int x = 14; + return false ? &x : arg; // expected-warning {{address of stack memory associated with local variable 'x' returned}} +} + +int *return_conditional_path_split(int *arg, bool b) { + int x = 14; + return b ? arg : &x; // expected-warning {{Address of stack memory associated with local variable 'x' returned to caller}} expected-warning {{address of stack memory associated with local variable 'x' returned}} -Wreturn-stack-address +} + +// compare of two symbolic regions +// maybe in some implementation, make_ptr returns interior pointers that are comparable +int *make_ptr(); +bool return_symbolic_exxpression() { + int *a = make_ptr(); + int *b = make_ptr(); + return a < b; // no-warning +} + +int *return_static() { + static int x = 0; + return &x; // no-warning +} + +int* return_cpp_reinterpret_cast_no_warning(long x) { + return reinterpret_cast(x); // no-warning +} +} + +// TODO: The tail call expression tree must not hold a reference to an arg or stack local: +// "The lifetimes of all local variables and function parameters end immediately before the +// [tail] call to the function. This means that it is undefined behaviour to pass a pointer or +// reference to a local variable to the called function, which is not the case without the +// attribute." +// These only warn from -Wreturn-stack-address for now +namespace with_attr_musttail { +void TakesIntAndPtr(int, int *); +void PassAddressOfLocal(int a, int *b) { + int c; + [[clang::musttail]] return TakesIntAndPtr(0, &c); // expected-warning {{address of stack memory associated with local variable 'c' pass\ +ed to musttail function}} False-negative on CSA +} +void PassAddressOfParam(int a, int *b) { + [[clang::musttail]] return TakesIntAndPtr(0, &a); // expected-warning {{address of stack memory associated with parameter 'a' passed to\ + musttail function}} False-negative on CSA +} +} // namespace with_attr_musttail diff --git a/clang/test/Analysis/stackaddrleak.c b/clang/test/Analysis/stackaddrleak.c index 5f508275ba9c8..f8101525401b0 100644 --- a/clang/test/Analysis/stackaddrleak.c +++ b/clang/test/Analysis/stackaddrleak.c @@ -56,3 +56,15 @@ void assignAsBool(void) { int x; b = &x; } // no-warning + +int *f(int* p __attribute__((lifetimebound))); +int *g() { + int i; + return f(&i); // expected-warning {{address of stack memory associated with local variable 'i' returned}} +} + +int *f_no_lifetime_bound(int *p); +int *g_no_lifetime_bound() { + int i = 0; + return f_no_lifetime_bound(&i); // no-warning +} diff --git a/clang/test/Analysis/stackaddrleak.cpp b/clang/test/Analysis/stackaddrleak.cpp index 3daffb35a6cd9..df202a2fee776 100644 --- a/clang/test/Analysis/stackaddrleak.cpp +++ b/clang/test/Analysis/stackaddrleak.cpp @@ -18,7 +18,7 @@ struct myfunction { myfunction create_func() { int n; auto c = [&n] {}; - return c; // expected-warning {{Address of stack memory associated with local variable 'n' is still referred to by a temporary object on the stack upon returning to the caller. This will be a dangling reference}} + return c; // expected-warning {{Address of stack memory associated with local variable 'n' returned to caller}} expected-warning{{Address of stack memory associated with local variable 'n' is still referred to by a temporary object on the stack upon returning to the caller. This will be a dangling reference}} } void gh_66221() { create_func()(); diff --git a/clang/test/Analysis/taint-diagnostic-visitor.c b/clang/test/Analysis/taint-diagnostic-visitor.c index 223df9951fd6b..afe7117db7150 100644 --- a/clang/test/Analysis/taint-diagnostic-visitor.c +++ b/clang/test/Analysis/taint-diagnostic-visitor.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=optin.taint,core,alpha.security.ArrayBoundV2 -analyzer-output=text -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=optin.taint,core,security.ArrayBound -analyzer-output=text -verify %s // This file is for testing enhanced diagnostics produced by the GenericTaintChecker diff --git a/clang/test/Analysis/taint-generic.c b/clang/test/Analysis/taint-generic.c index ad5a99fe8b3a3..3c520612c5d9b 100644 --- a/clang/test/Analysis/taint-generic.c +++ b/clang/test/Analysis/taint-generic.c @@ -3,7 +3,7 @@ // RUN: -analyzer-checker=optin.taint.GenericTaint \ // RUN: -analyzer-checker=optin.taint.TaintedDiv \ // RUN: -analyzer-checker=core \ -// RUN: -analyzer-checker=alpha.security.ArrayBoundV2 \ +// RUN: -analyzer-checker=security.ArrayBound \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -analyzer-config \ // RUN: optin.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml @@ -14,7 +14,7 @@ // RUN: -analyzer-checker=optin.taint.GenericTaint \ // RUN: -analyzer-checker=optin.taint.TaintedDiv \ // RUN: -analyzer-checker=core \ -// RUN: -analyzer-checker=alpha.security.ArrayBoundV2 \ +// RUN: -analyzer-checker=security.ArrayBound \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -analyzer-config \ // RUN: optin.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml diff --git a/clang/test/Analysis/taint-generic.cpp b/clang/test/Analysis/taint-generic.cpp index 881c5baf889f6..8836e1d3d2d98 100644 --- a/clang/test/Analysis/taint-generic.cpp +++ b/clang/test/Analysis/taint-generic.cpp @@ -1,5 +1,5 @@ // RUN: %clang_analyze_cc1 -std=c++11 -Wno-format-security \ -// RUN: -analyzer-checker=core,optin.taint,alpha.security.ArrayBoundV2,debug.ExprInspection \ +// RUN: -analyzer-checker=core,optin.taint,security.ArrayBound,debug.ExprInspection \ // RUN: -analyzer-config optin.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml \ // RUN: -verify %s diff --git a/clang/test/CIR/Lowering/global-var-simple.cpp b/clang/test/CIR/Lowering/global-var-simple.cpp new file mode 100644 index 0000000000000..a5adb4011931a --- /dev/null +++ b/clang/test/CIR/Lowering/global-var-simple.cpp @@ -0,0 +1,102 @@ +// Global variables of intergal types +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s + +// Note: Currently unsupported features include default zero-initialization +// and alignment. The fact that "external" is only printed for globals +// without an initializer is a quirk of the LLVM AsmWriter. + +char c; +// CHECK: @c = external dso_local global i8 + +signed char sc; +// CHECK: @sc = external dso_local global i8 + +unsigned char uc; +// CHECK: @uc = external dso_local global i8 + +short ss; +// CHECK: @ss = external dso_local global i16 + +unsigned short us = 100; +// CHECK: @us = dso_local global i16 100 + +int si = 42; +// CHECK: @si = dso_local global i32 42 + +unsigned ui; +// CHECK: @ui = external dso_local global i32 + +long sl; +// CHECK: @sl = external dso_local global i64 + +unsigned long ul; +// CHECK: @ul = external dso_local global i64 + +long long sll; +// CHECK: @sll = external dso_local global i64 + +unsigned long long ull = 123456; +// CHECK: @ull = dso_local global i64 123456 + +__int128 s128; +// CHECK: @s128 = external dso_local global i128 + +unsigned __int128 u128; +// CHECK: @u128 = external dso_local global i128 + +wchar_t wc; +// CHECK: @wc = external dso_local global i32 + +char8_t c8; +// CHECK: @c8 = external dso_local global i8 + +char16_t c16; +// CHECK: @c16 = external dso_local global i16 + +char32_t c32; +// CHECK: @c32 = external dso_local global i32 + +_BitInt(20) sb20; +// CHECK: @sb20 = external dso_local global i20 + +unsigned _BitInt(48) ub48; +// CHECK: @ub48 = external dso_local global i48 + +_Float16 f16; +// CHECK: @f16 = external dso_local global half + +__bf16 bf16; +// CHECK: @bf16 = external dso_local global bfloat + +float f; +// CHECK: @f = external dso_local global float + +double d = 1.25; +// CHECK: @d = dso_local global double 1.250000e+00 + +long double ld; +// CHECK: @ld = external dso_local global x86_fp80 + +__float128 f128; +// CHECK: @f128 = external dso_local global fp128 + +void *vp; +// CHECK: @vp = external dso_local global ptr{{$}} + +int *ip = 0; +// CHECK: @ip = dso_local global ptr null + +double *dp; +// CHECK: @dp = external dso_local global ptr{{$}} + +char **cpp; +// CHECK: @cpp = external dso_local global ptr{{$}} + +void (*fp)(); +// CHECK: @fp = external dso_local global ptr{{$}} + +int (*fpii)(int) = 0; +// CHECK: @fpii = dso_local global ptr null + +void (*fpvar)(int, ...); +// CHECK: @fpvar = external dso_local global ptr{{$}} diff --git a/clang/test/CIR/Lowering/hello.c b/clang/test/CIR/Lowering/hello.c new file mode 100644 index 0000000000000..ff78b6e6f6a5e --- /dev/null +++ b/clang/test/CIR/Lowering/hello.c @@ -0,0 +1,10 @@ +// Smoke test for ClangIR-to-LLVM IR code generation +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s + +int a; + +// CHECK: @a = external dso_local global i32 + +int b = 2; + +// CHECK: @b = dso_local global i32 2 diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 5369dc92f69e8..b796a51ef600e 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -5,7 +5,6 @@ llvm_canonicalize_cmake_booleans( CLANG_BUILD_EXAMPLES CLANG_BUILT_STANDALONE CLANG_DEFAULT_PIE_ON_LINUX - CLANG_ENABLE_ARCMT CLANG_ENABLE_STATIC_ANALYZER CLANG_PLUGIN_SUPPORT CLANG_SPAWN_CC1 @@ -22,6 +21,7 @@ llvm_canonicalize_cmake_booleans( LLVM_WITH_Z3 PPC_LINUX_DEFAULT_IEEELONGDOUBLE LLVM_TOOL_LLVM_DRIVER_BUILD + LLVM_INCLUDE_SPIRV_TOOLS_TESTS ) configure_lit_site_cfg( @@ -92,13 +92,6 @@ if(CLANG_ENABLE_STATIC_ANALYZER) ) endif() -if (CLANG_ENABLE_ARCMT) - list(APPEND CLANG_TEST_DEPS - arcmt-test - c-arcmt-test - ) -endif () - if(CLANG_BUILD_EXAMPLES AND CLANG_PLUGIN_SUPPORT) list(APPEND CLANG_TEST_DEPS Attribute @@ -110,6 +103,15 @@ if(CLANG_BUILD_EXAMPLES AND CLANG_PLUGIN_SUPPORT) ) endif () +if(LLVM_INCLUDE_SPIRV_TOOLS_TESTS) + list(APPEND CLANG_TEST_DEPS + spirv-dis + spirv-val + spirv-as + spirv-link + ) +endif() + set(CLANG_TEST_PARAMS USE_Z3_SOLVER=0 ) diff --git a/clang/test/CXX/class/class.init/p1.cpp b/clang/test/CXX/class/class.init/p1.cpp new file mode 100644 index 0000000000000..717dfba89763a --- /dev/null +++ b/clang/test/CXX/class/class.init/p1.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace test_deleted_ctor_note { +struct A { + int a; + A() = delete; // expected-note {{'A' has been explicitly marked deleted here}} + A(int a_) : a(a_) { } +}; + +struct B { + A a1, a2, a3; // expected-note {{default constructed field 'a2' declared here}} + B(int a_) : a1(a_), a3(a_) { } // expected-error{{call to deleted constructor of 'A'}} +}; +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp index e7f501352168c..d548f9c8c2fdf 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/p14-0x.cpp @@ -27,7 +27,7 @@ class Friend { class S { - NoDefault nd1; + NoDefault nd1; // expected-note {{default constructed field 'nd1' declared here}} NoDefault nd2 = 42; Explicit e1; // expected-note {{here}} Explicit e2 = 42; // expected-error {{no viable conversion}} diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp index 15f469440c66f..44a0eb520af22 100644 --- a/clang/test/CXX/drs/cwg0xx.cpp +++ b/clang/test/CXX/drs/cwg0xx.cpp @@ -521,12 +521,12 @@ namespace example1 { namespace A { int i; } - + namespace A1 { using A::i; using A::i; } - + void f() { using A::i; @@ -1371,7 +1371,7 @@ namespace cwg92 { // cwg92: 4 c++17 // considered in this context. In C++17, we *do* perform an implicit // conversion (which performs initialization), and the exception specification // is part of the type of the parameter, so this is invalid. - template struct X {}; + template struct X {}; // since-cxx17-note {{template parameter is declared here}} X<&f> xp; // since-cxx17-error@-1 {{value of type 'void (*)() throw(int, float)' is not implicitly convertible to 'void (*)() throw()'}} diff --git a/clang/test/CXX/drs/cwg12xx.cpp b/clang/test/CXX/drs/cwg12xx.cpp index 344adb6d72023..e02a7e11b80b2 100644 --- a/clang/test/CXX/drs/cwg12xx.cpp +++ b/clang/test/CXX/drs/cwg12xx.cpp @@ -155,6 +155,8 @@ namespace cwg1295 { // cwg1295: 4 // cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}} // cxx98-14-note@#cwg1295-Y {{template parameter is declared here}} // since-cxx17-error@#cwg1295-y {{reference cannot bind to bit-field in converted constant expression}} + // since-cxx17-note@#cwg1295-Y {{template parameter is declared here}} + #if __cplusplus >= 201103L const unsigned other = 0; diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index b5e07a66bb4ed..6c420ecd4c91d 100644 --- a/clang/test/CXX/drs/cwg3xx.cpp +++ b/clang/test/CXX/drs/cwg3xx.cpp @@ -444,7 +444,7 @@ namespace cwg329 { // cwg329: 3.5 // expected-note@#cwg329-b {{in instantiation of template class 'cwg329::A' requested here}} // expected-note@#cwg329-i {{previous definition is here}} }; - A a; + A a; A b; // #cwg329-b void test() { @@ -688,9 +688,9 @@ namespace cwg341 { // cwg341: sup 1708 namespace B { extern "C" int &cwg341_a = cwg341_a; // expected-error@-1 {{redefinition of 'cwg341_a'}} - // expected-note@#cwg341_a {{previous definition is here}} + // expected-note@#cwg341_a {{previous definition is here}} } - extern "C" void cwg341_b(); // #cwg341_b + extern "C" void cwg341_b(); // #cwg341_b } int cwg341_a; // expected-error@-1 {{declaration of 'cwg341_a' in global scope conflicts with declaration with C language linkage}} @@ -708,7 +708,7 @@ namespace cwg341 { // expected-error@-1 {{declaration of 'cwg341_d' with C language linkage conflicts with declaration in global scope}} // expected-note@#cwg341_d {{declared in global scope here}} - namespace A { extern "C" int cwg341_e; } // #cwg341_e + namespace A { extern "C" int cwg341_e; } // #cwg341_e namespace B { extern "C" void cwg341_e(); } // expected-error@-1 {{redefinition of 'cwg341_e' as different kind of symbol}} // expected-note@#cwg341_e {{previous definition is here}} @@ -960,6 +960,7 @@ namespace cwg354 { // cwg354: 3.1 c++11 // cxx11-14-error@#cwg354-p0 {{null non-type template argument must be cast to template parameter type 'int *'}} // cxx11-14-note@#cwg354-ptr {{template parameter is declared here}} // since-cxx17-error@#cwg354-p0 {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}} + // since-cxx17-note@#cwg354-ptr {{template parameter is declared here}} ptr<(int*)0> p1; // cxx98-error@-1 {{non-type template argument does not refer to any declaration}} // cxx98-note@#cwg354-ptr {{template parameter is declared here}} @@ -969,12 +970,14 @@ namespace cwg354 { // cwg354: 3.1 c++11 // cxx11-14-error@#cwg354-p2 {{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}} // cxx11-14-note@#cwg354-ptr {{template parameter is declared here}} // since-cxx17-error@#cwg354-p2 {{value of type 'float *' is not implicitly convertible to 'int *'}} + // since-cxx17-note@#cwg354-ptr {{template parameter is declared here}} ptr<(int S::*)0> p3; // #cwg354-p3 // cxx98-error@#cwg354-p3 {{non-type template argument does not refer to any declaration}} // cxx98-note@#cwg354-ptr {{template parameter is declared here}} // cxx11-14-error@#cwg354-p3 {{null non-type template argument of type 'int S::*' does not match template parameter of type 'int *'}} // cxx11-14-note@#cwg354-ptr {{template parameter is declared here}} // since-cxx17-error@#cwg354-p3 {{value of type 'int S::*' is not implicitly convertible to 'int *'}} + // since-cxx17-note@#cwg354-ptr {{template parameter is declared here}} template int both(); // #cwg354-both-int-ptr template int both(); // #cwg354-both-int @@ -991,6 +994,7 @@ namespace cwg354 { // cwg354: 3.1 c++11 // cxx11-14-error@#cwg354-m0 {{null non-type template argument must be cast to template parameter type 'int S::*'}} // cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}} // since-cxx17-error@#cwg354-m0 {{conversion from 'int' to 'int S::*' is not allowed in a converted constant expression}} + // since-cxx17-note@#cwg354-ptr_mem {{template parameter is declared here}} ptr_mem<(int S::*)0> m1; // cxx98-error@-1 {{non-type template argument is not a pointer to member constant}} ptr_mem<(float S::*)0> m2; // #cwg354-m2 @@ -999,12 +1003,14 @@ namespace cwg354 { // cwg354: 3.1 c++11 // cxx11-14-error@#cwg354-m2 {{null non-type template argument of type 'float S::*' does not match template parameter of type 'int S::*'}} // cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}} // since-cxx17-error@#cwg354-m2 {{value of type 'float S::*' is not implicitly convertible to 'int S::*'}} + // since-cxx17-note@#cwg354-ptr_mem {{template parameter is declared here}} ptr_mem<(int *)0> m3; // #cwg354-m3 // cxx98-error@#cwg354-m3 {{non-type template argument of type 'int *' cannot be converted to a value of type 'int S::*'}} // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} // cxx11-14-error@#cwg354-m3 {{null non-type template argument of type 'int *' does not match template parameter of type 'int S::*'}} // cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}} // since-cxx17-error@#cwg354-m3 {{value of type 'int *' is not implicitly convertible to 'int S::*'}} + // since-cxx17-note@#cwg354-ptr_mem {{template parameter is declared here}} } // namespace cwg354 struct cwg355_S; // cwg355: 2.7 @@ -1116,7 +1122,7 @@ namespace cwg364 { // cwg364: 2.7 } // namespace cwg364 namespace cwg366 { // cwg366: 2.7 -#if "foo" // expected-error {{invalid token at start of a preprocessor expression}} +#if "foo" // expected-error {{invalid token at start of a preprocessor expression}} #endif } // namespace cwg366 diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp index 5bd70c5250b59..3eedef3cf7712 100644 --- a/clang/test/CXX/expr/expr.const/p3-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++1z -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify=expected,cxx11 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify=expected,cxx17 %s // A converted constant expression of type T is a core constant expression, int nonconst = 8; // expected-note 3 {{here}} @@ -66,7 +66,8 @@ enum class EEE : unsigned short { e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}} f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}} }; -template using A = int; +template using A = int; // cxx17-note 2{{template parameter is declared here}} + using Int = A; using Int = A; // expected-error {{not implicitly convertible}} using Int = A<(int)EE::EE32>; @@ -78,6 +79,7 @@ using Int = A<-3>; // expected-error {{template argument evaluates to -3, which // integral conversions as well as boolean conversions. // FIXME: Per core issue 1407, this is not correct. template struct Val { static constexpr T value = v; }; +// cxx17-note@-1 2{{template parameter is declared here}} static_assert(Val::value == 1, ""); // ok static_assert(Val::value == 0, ""); // ok static_assert(Val::value == 1, ""); // ok diff --git a/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p4.cpp b/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p4.cpp new file mode 100644 index 0000000000000..e816da1803694 --- /dev/null +++ b/clang/test/CXX/stmt.stmt/stmt.select/stmt.switch/p4.cpp @@ -0,0 +1,11 @@ +// RUN: %clang -fsyntax-only -std=c++20 -Xclang -verify %s + +void Func(int x) { + switch (x) { + [[likely]] case 0: + case 1: + int i = 3; // expected-note {{jump bypasses variable initialization}} + case 2: // expected-error {{cannot jump from switch statement to this case label}} + break; + } +} diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp index 7fce615516924..629000d88acc3 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp @@ -8,7 +8,7 @@ // be one of: // -- an integral constant expression; or // -- the name of a non-type template-parameter ; or -#ifndef CPP11ONLY +#ifndef CPP11ONLY namespace non_type_tmpl_param { template struct X0 { X0(); }; @@ -31,15 +31,18 @@ namespace non_type_tmpl_param { // omitted if the name refers to a function or array and shall be omitted // if the corresopnding template-parameter is a reference; or namespace addr_of_obj_or_func { - template struct X0 { }; // precxx17-note 5{{here}} + template struct X0 { }; // expected-note 5{{here}} #if __cplusplus >= 201103L // precxx17-note@-2 2{{template parameter is declared here}} #endif - template struct X1 { }; - template struct X2 { }; // precxx17-note 4{{here}} - template struct X2k { }; // precxx17-note {{here}} - template struct X3 { }; // precxx17-note 4{{here}} + template struct X1 { }; // cxx17-note {{here}} +#if __cplusplus <= 199711L + // precxx17-note@-2 {{here}} +#endif + template struct X2 { }; // expected-note 4{{here}} + template struct X2k { }; // expected-note {{here}} + template struct X3 { }; // expected-note 4{{here}} int i = 42; #if __cplusplus >= 201103L diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp index 54fcfccad6f52..3caed045c6688 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp @@ -18,8 +18,9 @@ eval> eD; // expected-error{{implicit instantiation of undefined temp eval> eE; // expected-error{{implicit instantiation of undefined template 'eval>}} template< - template // expected-error{{deduced non-type template argument does not have the same type as the corresponding template parameter ('int' vs 'void *')}} - class TT // expected-note {{previous template template parameter is here}} + template // expected-error {{cannot be narrowed from type 'int' to 'short'}} + // expected-error@-1 {{conversion from 'int' to 'void *' is not allowed in a converted constant expression}} + class TT // expected-note 2{{previous template template parameter is here}} > struct X0 { }; template struct X0a; @@ -31,12 +32,13 @@ template struct X0e; // expected-note{{template parameter is dec X0 inst_x0a; X0 inst_x0b; X0 inst_x0c; -X0 inst_x0d; +X0 inst_x0d; // expected-note {{has different template parameters}} X0 inst_x0e; // expected-note{{template template argument has different template parameters than its corresponding template template parameter}} template // expected-error{{deduced non-type template argument does not have the same type as the corresponding template parameter ('short' vs 'void *')}} - class TT // expected-note {{previous template template parameter is here}} + template // expected-error {{conversion from 'short' to 'void *' is not allowed in a converted constant expression}} + // expected-error@-1 {{cannot be narrowed from type 'int' to 'short'}} + class TT // expected-note 2{{previous template template parameter is here}} > struct X1 { }; template struct X1a; @@ -49,8 +51,8 @@ X1 inst_x1a; X1 inst_x1b; X1 inst_x1c; X1 inst_sx1d; -X1 inst_ix1d; -X1 inst_x1e; // expected-note{{template template argument has different template parameters than its corresponding template template parameter}} +X1 inst_ix1d; // expected-note {{has different template parameters}} +X1 inst_x1e; // expected-note {{has different template parameters}} template class X2; // expected-note{{template is declared here}} \ // expected-note{{template is declared here}} diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp index a990c82564aa4..ab4c663d24c7d 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp @@ -121,8 +121,8 @@ namespace PartialSpecialization { namespace FixedAliasTemplate { template struct S {}; - template using U = S; // expected-note 2{{template parameter is declared here}} - template U &f(U, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} + template using Z = S; // expected-note 2{{template parameter is declared here}} + template Z &f(Z, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}} S &s1 = f({}, 0, 0.0); // expected-error {{no matching function}} } diff --git a/clang/test/ClangScanDeps/modules-context-hash-cwd.c b/clang/test/ClangScanDeps/modules-context-hash-cwd.c new file mode 100644 index 0000000000000..459d2c90debe6 --- /dev/null +++ b/clang/test/ClangScanDeps/modules-context-hash-cwd.c @@ -0,0 +1,188 @@ +// Test current directory pruning when computing the context hash. + +// REQUIRES: shell + +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/cdb0.json.in > %t/cdb0.json +// RUN: sed -e "s|DIR|%/t|g" %t/cdb1.json.in > %t/cdb1.json +// RUN: sed -e "s|DIR|%/t|g" %t/cdb3.json.in > %t/cdb3.json +// RUN: sed -e "s|DIR|%/t|g" %t/cdb4.json.in > %t/cdb4.json +// RUN: sed -e "s|DIR|%/t|g" %t/cdb5.json.in > %t/cdb5.json +// RUN: clang-scan-deps -compilation-database %t/cdb0.json -format experimental-full > %t/result0.json +// RUN: clang-scan-deps -compilation-database %t/cdb1.json -format experimental-full > %t/result1.json +// It is not a typo to use cdb1.json for result2. We intend to use the same +// compilation database, but different clang-scan-deps optimize-args options. +// RUN: clang-scan-deps -compilation-database %t/cdb1.json -format experimental-full -optimize-args=header-search,system-warnings,vfs,canonicalize-macros > %t/result2.json +// RUN: clang-scan-deps -compilation-database %t/cdb3.json -format experimental-full > %t/result3.json +// RUN: clang-scan-deps -compilation-database %t/cdb4.json -format experimental-full > %t/result4.json +// RUN: clang-scan-deps -compilation-database %t/cdb5.json -format experimental-full > %t/result5.json +// RUN: cat %t/result0.json %t/result1.json | FileCheck %s +// RUN: cat %t/result0.json %t/result2.json | FileCheck %s -check-prefix=SKIPOPT +// RUN: cat %t/result3.json %t/result4.json | FileCheck %s -check-prefix=RELPATH +// RUN: cat %t/result0.json %t/result5.json | FileCheck %s + +//--- cdb0.json.in +[{ + "directory": "DIR", + "command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -IDIR/include/ -o DIR/tu.o", + "file": "DIR/tu.c" +}] + +//--- cdb1.json.in +[{ + "directory": "DIR/a", + "command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -IDIR/include/ -o DIR/tu.o", + "file": "DIR/tu.c" +}] + +// cdb2 is skipped because we reuse cdb1. + +//--- cdb3.json.in +[{ + "directory": "DIR", + "command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -fprebuilt-module-path=.././module -IDIR/include/ -o DIR/tu.o ", + "file": "DIR/tu.c" +}] + +//--- cdb4.json.in +[{ + "directory": "DIR/a/", + "command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -fprebuilt-module-path=.././module -IDIR/include/ -o DIR/tu.o ", + "file": "DIR/tu.c" +}] + +//--- cdb5.json.in +[{ + "directory": "DIR", + "command": "clang -c DIR/tu.c -fmodules -fmodules-cache-path=DIR/cache -IDIR/include/ -Xclang -working-directory=DIR/a/ -o DIR/tu.o", + "file": "DIR/tu.c" +}] + +//--- include/module.modulemap +module mod { + header "mod.h" +} + +//--- include/mod.h + +//--- tu.c +#include "mod.h" + +// Check that result0 and result1/result5 compute the same hash with +// optimization on. The only difference between result0 and result1/result5 is +// the compiler's working directory. +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK: "context-hash": "[[HASH:.*]]", +// CHECK: } +// CHECK: "translation-units": [ +// CHECK: { +// CHECK: "commands": [ +// CHECK: { +// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH]]", +// CHECK-NEXT: "module-name": "mod" +// CHECK: } +// CHECK: ], +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK: "context-hash": "[[HASH]]", +// CHECK: } +// CHECK: "translation-units": [ +// CHECK: { +// CHECK: "commands": [ +// CHECK: { +// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "[[HASH]]", +// CHECK-NEXT: "module-name": "mod" +// CHECK: } +// CHECK: ], + +// Check that result0 and result2 compute different hashes because +// the working directory optmization is turned off for result2. +// SKIPOPT: { +// SKIPOPT-NEXT: "modules": [ +// SKIPOPT-NEXT: { +// SKIPOPT-NEXT: "clang-module-deps": [], +// SKIPOPT: "context-hash": "[[HASH0:.*]]", +// SKIPOPT: } +// SKIPOPT: "translation-units": [ +// SKIPOPT: { +// SKIPOPT: "commands": [ +// SKIPOPT: { +// SKIPOPT-NEXT: "clang-context-hash": "{{.*}}", +// SKIPOPT-NEXT: "clang-module-deps": [ +// SKIPOPT-NEXT: { +// SKIPOPT-NEXT: "context-hash": "[[HASH0]]", +// SKIPOPT-NEXT: "module-name": "mod" +// SKIPOPT: } +// SKIPOPT: ], +// SKIPOPT: { +// SKIPOPT-NEXT: "modules": [ +// SKIPOPT-NEXT: { +// SKIPOPT-NEXT: "clang-module-deps": [], +// SKIPOPT-NOT: "context-hash": "[[HASH0]]", +// SKIPOPT: "context-hash": "[[HASH2:.*]]", +// SKIPOPT: } +// SKIPOPT: "translation-units": [ +// SKIPOPT: { +// SKIPOPT: "commands": [ +// SKIPOPT: { +// SKIPOPT-NEXT: "clang-context-hash": "{{.*}}", +// SKIPOPT-NEXT: "clang-module-deps": [ +// SKIPOPT-NEXT: { +// SKIPOPT-NOT: "context-hash": "[[HASH0]]", +// SKIPOPT-NEXT: "context-hash": "[[HASH2]]" +// SKIPOPT-NEXT: "module-name": "mod" +// SKIPOPT: } +// SKIPOPT: ], + +// Check that result3 and result4 contain different hashes because +// both have a same relative path as a command line input, and +// they are produced using different compiler working directories. +// RELPATH: { +// RELPATH-NEXT: "modules": [ +// RELPATH-NEXT: { +// RELPATH-NEXT: "clang-module-deps": [], +// RELPATH: "context-hash": "[[HASH3:.*]]", +// RELPATH: } +// RELPATH: "translation-units": [ +// RELPATH: { +// RELPATH: "commands": [ +// RELPATH: { +// RELPATH-NEXT: "clang-context-hash": "{{.*}}", +// RELPATH-NEXT: "clang-module-deps": [ +// RELPATH-NEXT: { +// RELPATH-NEXT: "context-hash": "[[HASH3]]", +// RELPATH-NEXT: "module-name": "mod" +// RELPATH: } +// RELPATH: ], +// RELPATH: { +// RELPATH-NEXT: "modules": [ +// RELPATH-NEXT: { +// RELPATH-NEXT: "clang-module-deps": [], +// RELPATH-NOT: "context-hash": "[[HASH3]]", +// RELPATH: "context-hash": "[[HASH4:.*]]", +// RELPATH: } +// RELPATH: "translation-units": [ +// RELPATH: { +// RELPATH: "commands": [ +// RELPATH: { +// RELPATH-NEXT: "clang-context-hash": "{{.*}}", +// RELPATH-NEXT: "clang-module-deps": [ +// RELPATH-NEXT: { +// RELPATH-NOT: "context-hash": "[[HASH3]]", +// RELPATH-NEXT: "context-hash": "[[HASH4]]" +// RELPATH-NEXT: "module-name": "mod" +// RELPATH: } +// RELPATH: ], + diff --git a/clang/test/ClangScanDeps/strip-input-args.m b/clang/test/ClangScanDeps/strip-input-args.m index e1954ecc28914..31f634dd80131 100644 --- a/clang/test/ClangScanDeps/strip-input-args.m +++ b/clang/test/ClangScanDeps/strip-input-args.m @@ -11,11 +11,6 @@ // CHECK: "modules": [ // CHECK-NEXT: { -// CHECK: "command-line": [ -// CHECK-NOT: "-arcmt-action=check" -// CHECK-NOT: "-objcmt-migrate-literals" -// CHECK-NOT: "-mt-migrate-directory" -// CHECK: ] // CHECK: "name": "A" // CHECK: } // CHECK-NOT: "name": "A" @@ -25,12 +20,12 @@ [ { "directory": "DIR", - "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -ccc-arcmt-check -fsyntax-only DIR/t1.m", + "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -fsyntax-only DIR/t1.m", "file": "DIR/t1.m" }, { "directory": "DIR", - "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -ccc-objcmt-migrate bob -fsyntax-only DIR/t2.m", + "command": "clang -Imodules/A -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -fsyntax-only DIR/t2.m", "file": "DIR/t2.m" } ] diff --git a/clang/test/ClangScanDeps/tu-buffer.c b/clang/test/ClangScanDeps/tu-buffer.c new file mode 100644 index 0000000000000..b450b13ff434b --- /dev/null +++ b/clang/test/ClangScanDeps/tu-buffer.c @@ -0,0 +1,111 @@ +// UNSUPPORTED: target=powerpc64-ibm-aix{{.*}} + +// RUN: rm -rf %t +// RUN: split-file %s %t + +//--- module.modulemap +module root { header "root.h" } +module direct { header "direct.h" } +module transitive { header "transitive.h" } +module addition { header "addition.h" } +//--- root.h +#include "direct.h" +#include "root/textual.h" +//--- direct.h +#include "transitive.h" +//--- transitive.h +// empty + +//--- addition.h +// empty + +//--- tu.c +#include "root.h" + +//--- root/textual.h +// This is here to verify that the "root" directory doesn't clash with name of +// the "root" module. + +//--- cdb.json.template +[{ + "file": "", + "directory": "DIR", + "command": "clang -fmodules -fmodules-cache-path=DIR/cache -I DIR -x c -c" +}] + +// RUN: sed "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full -tu-buffer-path %t/tu.c > %t/result.json +// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck -DPREFIX=%/t %s --check-prefix=CHECK + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "transitive" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" +// CHECK-NEXT: "[[PREFIX]]/direct.h" +// CHECK-NEXT: ], +// CHECK: "name": "direct" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "direct" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" +// CHECK-NEXT: "[[PREFIX]]/root.h" +// CHECK-NEXT: "[[PREFIX]]/root/textual.h" +// CHECK-NEXT: ], +// CHECK: "name": "root" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" +// CHECK-NEXT: "[[PREFIX]]/transitive.h" +// CHECK-NEXT: ], +// CHECK: "name": "transitive" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "translation-units": [ +// CHECK-NEXT: { +// CHECK-NEXT: "commands": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "root" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK: "file-deps": [ +// CHECK-NEXT: [[PREFIX]]/tu.c +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.c" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } diff --git a/clang/test/ClangScanDeps/working-dir.m b/clang/test/ClangScanDeps/working-dir.m index a04f8c2486b98..c6b7b1988d3cf 100644 --- a/clang/test/ClangScanDeps/working-dir.m +++ b/clang/test/ClangScanDeps/working-dir.m @@ -2,7 +2,7 @@ // RUN: split-file %s %t // RUN: sed -e "s|DIR|%/t|g" %t/build/compile-commands.json.in > %t/build/compile-commands.json // RUN: clang-scan-deps -compilation-database %t/build/compile-commands.json \ -// RUN: -j 1 -format experimental-full --optimize-args=all > %t/deps.db +// RUN: -j 1 -format experimental-full --optimize-args=header-search,system-warnings,vfs,canonicalize-macros > %t/deps.db // RUN: cat %t/deps.db | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t // Check that there are two separate modules hashes. One for each working dir. diff --git a/clang/test/CodeCompletion/member-access.cpp b/clang/test/CodeCompletion/member-access.cpp index bf35f7ad021f7..b181466cdb628 100644 --- a/clang/test/CodeCompletion/member-access.cpp +++ b/clang/test/CodeCompletion/member-access.cpp @@ -417,3 +417,21 @@ void f() { // CHECK-DEPENDENT-NESTEDCLASS: [#int#]field } } + +namespace template_alias { +struct A { + int b; +}; +template +struct S { + A a; +}; +template +using Alias = S; +template +void f(Alias s) { + s.a.b; + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:433:7 %s -o - | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s + // CHECK-TEMPLATE-ALIAS: [#int#]b +} +} diff --git a/clang/test/CodeGen/AArch64/args.cpp b/clang/test/CodeGen/AArch64/args.cpp index fe1298cc683a4..6f1f3d5e2a062 100644 --- a/clang/test/CodeGen/AArch64/args.cpp +++ b/clang/test/CodeGen/AArch64/args.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefix=CHECK-GNU-C -// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-GNU-CXX +// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,DARWIN +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes=CHECK,C +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CXX // Empty structs are ignored for PCS purposes on Darwin and in C mode elsewhere. // In C++ mode on ELF they consume a register slot though. Functions are @@ -15,16 +15,16 @@ struct Empty {}; -// CHECK: define{{.*}} i32 @empty_arg(i32 noundef %a) -// CHECK-GNU-C: define{{.*}} i32 @empty_arg(i32 noundef %a) -// CHECK-GNU-CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a) +// DARWIN: define{{.*}} i32 @empty_arg(i32 noundef %a) +// C: define{{.*}} i32 @empty_arg(i32 noundef %a) +// CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a) EXTERNC int empty_arg(struct Empty e, int a) { return a; } -// CHECK: define{{.*}} void @empty_ret() -// CHECK-GNU-C: define{{.*}} void @empty_ret() -// CHECK-GNU-CXX: define{{.*}} void @empty_ret() +// DARWIN: define{{.*}} void @empty_ret() +// C: define{{.*}} void @empty_ret() +// CXX: define{{.*}} void @empty_ret() EXTERNC struct Empty empty_ret(void) { struct Empty e; return e; @@ -38,30 +38,75 @@ struct SuperEmpty { int arr[0]; }; -// CHECK: define{{.*}} i32 @super_empty_arg(i32 noundef %a) -// CHECK-GNU-C: define{{.*}} i32 @super_empty_arg(i32 noundef %a) -// CHECK-GNU-CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a) +// DARWIN: define{{.*}} i32 @super_empty_arg(i32 noundef %a) +// C: define{{.*}} i32 @super_empty_arg(i32 noundef %a) +// CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a) EXTERNC int super_empty_arg(struct SuperEmpty e, int a) { return a; } -// This is not empty. It has 0 size but consumes a register slot for GCC. +// This is also not empty, and non-standard. We previously considered it to +// consume a register slot, but GCC does not, so we match that. struct SortOfEmpty { struct SuperEmpty e; }; -// CHECK: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) -// CHECK-GNU-C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) -// CHECK-GNU-CXX: define{{.*}} i32 @sort_of_empty_arg(i8 %e.coerce, i32 noundef %a) -EXTERNC int sort_of_empty_arg(struct Empty e, int a) { +// DARWIN: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) +// C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) +// CXX: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) +EXTERNC int sort_of_empty_arg(struct SortOfEmpty e, int a) { return a; } -// CHECK: define{{.*}} void @sort_of_empty_ret() -// CHECK-GNU-C: define{{.*}} void @sort_of_empty_ret() -// CHECK-GNU-CXX: define{{.*}} void @sort_of_empty_ret() +// DARWIN: define{{.*}} void @sort_of_empty_ret() +// C: define{{.*}} void @sort_of_empty_ret() +// CXX: define{{.*}} void @sort_of_empty_ret() EXTERNC struct SortOfEmpty sort_of_empty_ret(void) { struct SortOfEmpty e; return e; } + +#include + +// va_arg matches the above rules, consuming an incoming argument in cases +// where one would be passed, and not doing so when the argument should be +// ignored. + +EXTERNC struct Empty empty_arg_variadic(int a, ...) { +// CHECK-LABEL: @empty_arg_variadic( +// DARWIN-NOT: {{ getelementptr }} +// C-NOT: {{ getelementptr }} +// CXX: %new_reg_offs = add i32 %gr_offs, 8 +// CXX: %new_stack = getelementptr inbounds i8, ptr %stack, i64 8 + va_list vl; + va_start(vl, a); + struct Empty b = va_arg(vl, struct Empty); + va_end(vl); + return b; +} + +EXTERNC struct SuperEmpty super_empty_arg_variadic(int a, ...) { +// CHECK-LABEL: @super_empty_arg_variadic( +// DARWIN-NOT: {{ getelementptr }} +// C-NOT: {{ getelementptr }} +// CXX-NOT: {{ getelementptr }} + va_list vl; + va_start(vl, a); + struct SuperEmpty b = va_arg(vl, struct SuperEmpty); + va_end(vl); + return b; +} + +EXTERNC struct SortOfEmpty sort_of_empty_arg_variadic(int a, ...) { +// CHECK-LABEL: @sort_of_empty_arg_variadic( +// DARWIN: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 0 +// C-NOT: {{ getelementptr }} +// CXX-NOT: {{ getelementptr }} + va_list vl; + va_start(vl, a); + struct SortOfEmpty b = va_arg(vl, struct SortOfEmpty); + va_end(vl); + return b; +} + diff --git a/clang/test/CodeGen/AArch64/builtin-shufflevector-fp8.c b/clang/test/CodeGen/AArch64/builtin-shufflevector-fp8.c new file mode 100644 index 0000000000000..147ca1d1becc1 --- /dev/null +++ b/clang/test/CodeGen/AArch64/builtin-shufflevector-fp8.c @@ -0,0 +1,123 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-linux -target-feature +neon -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s + +// REQUIRES: aarch64-registered-target + +typedef __attribute__((neon_vector_type(8))) signed char int8x8_t; +typedef __attribute__((neon_vector_type(16))) signed char int8x16_t; + +typedef __attribute__((neon_vector_type(8))) __mfp8 mfloat8x8_t; +typedef __attribute__((neon_vector_type(16))) __mfp8 mfloat8x16_t; + +// CHECK-LABEL: define dso_local <8 x i8> @test_8x8( +// CHECK-SAME: <8 x i8> [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <8 x i8> [[X]], <8 x i8> [[X]], <8 x i32> +// CHECK-NEXT: ret <8 x i8> [[SHUFFLE]] +// +mfloat8x8_t test_8x8(mfloat8x8_t x) { + return __builtin_shufflevector(x, x, 3, 2, 1, 0, 3, 2, 1, 0); +} + +// CHECK-LABEL: define dso_local <8 x i8> @test_8x8_v( +// CHECK-SAME: <8 x i8> [[X:%.*]], <8 x i8> noundef [[P:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[MASK:%.*]] = and <8 x i8> [[P]], splat (i8 7) +// CHECK-NEXT: [[SHUF_IDX:%.*]] = extractelement <8 x i8> [[MASK]], i64 0 +// CHECK-NEXT: [[SHUF_ELT:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX]] +// CHECK-NEXT: [[SHUF_INS:%.*]] = insertelement <8 x i8> poison, i8 [[SHUF_ELT]], i64 0 +// CHECK-NEXT: [[SHUF_IDX1:%.*]] = extractelement <8 x i8> [[MASK]], i64 1 +// CHECK-NEXT: [[SHUF_ELT2:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX1]] +// CHECK-NEXT: [[SHUF_INS3:%.*]] = insertelement <8 x i8> [[SHUF_INS]], i8 [[SHUF_ELT2]], i64 1 +// CHECK-NEXT: [[SHUF_IDX4:%.*]] = extractelement <8 x i8> [[MASK]], i64 2 +// CHECK-NEXT: [[SHUF_ELT5:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX4]] +// CHECK-NEXT: [[SHUF_INS6:%.*]] = insertelement <8 x i8> [[SHUF_INS3]], i8 [[SHUF_ELT5]], i64 2 +// CHECK-NEXT: [[SHUF_IDX7:%.*]] = extractelement <8 x i8> [[MASK]], i64 3 +// CHECK-NEXT: [[SHUF_ELT8:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX7]] +// CHECK-NEXT: [[SHUF_INS9:%.*]] = insertelement <8 x i8> [[SHUF_INS6]], i8 [[SHUF_ELT8]], i64 3 +// CHECK-NEXT: [[SHUF_IDX10:%.*]] = extractelement <8 x i8> [[MASK]], i64 4 +// CHECK-NEXT: [[SHUF_ELT11:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX10]] +// CHECK-NEXT: [[SHUF_INS12:%.*]] = insertelement <8 x i8> [[SHUF_INS9]], i8 [[SHUF_ELT11]], i64 4 +// CHECK-NEXT: [[SHUF_IDX13:%.*]] = extractelement <8 x i8> [[MASK]], i64 5 +// CHECK-NEXT: [[SHUF_ELT14:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX13]] +// CHECK-NEXT: [[SHUF_INS15:%.*]] = insertelement <8 x i8> [[SHUF_INS12]], i8 [[SHUF_ELT14]], i64 5 +// CHECK-NEXT: [[SHUF_IDX16:%.*]] = extractelement <8 x i8> [[MASK]], i64 6 +// CHECK-NEXT: [[SHUF_ELT17:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX16]] +// CHECK-NEXT: [[SHUF_INS18:%.*]] = insertelement <8 x i8> [[SHUF_INS15]], i8 [[SHUF_ELT17]], i64 6 +// CHECK-NEXT: [[SHUF_IDX19:%.*]] = extractelement <8 x i8> [[MASK]], i64 7 +// CHECK-NEXT: [[SHUF_ELT20:%.*]] = extractelement <8 x i8> [[X]], i8 [[SHUF_IDX19]] +// CHECK-NEXT: [[SHUF_INS21:%.*]] = insertelement <8 x i8> [[SHUF_INS18]], i8 [[SHUF_ELT20]], i64 7 +// CHECK-NEXT: ret <8 x i8> [[SHUF_INS21]] +// +mfloat8x8_t test_8x8_v(mfloat8x8_t x, int8x8_t p) { + return __builtin_shufflevector(x, p); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_8x16( +// CHECK-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <16 x i8> [[X]], <16 x i8> [[X]], <16 x i32> +// CHECK-NEXT: ret <16 x i8> [[SHUFFLE]] +// +mfloat8x16_t test_8x16(mfloat8x16_t x) { + return __builtin_shufflevector(x, x, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, + 1, 0); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_8x16_v( +// CHECK-SAME: <16 x i8> [[X:%.*]], <16 x i8> noundef [[P:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[MASK:%.*]] = and <16 x i8> [[P]], splat (i8 15) +// CHECK-NEXT: [[SHUF_IDX:%.*]] = extractelement <16 x i8> [[MASK]], i64 0 +// CHECK-NEXT: [[SHUF_ELT:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX]] +// CHECK-NEXT: [[SHUF_INS:%.*]] = insertelement <16 x i8> poison, i8 [[SHUF_ELT]], i64 0 +// CHECK-NEXT: [[SHUF_IDX1:%.*]] = extractelement <16 x i8> [[MASK]], i64 1 +// CHECK-NEXT: [[SHUF_ELT2:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX1]] +// CHECK-NEXT: [[SHUF_INS3:%.*]] = insertelement <16 x i8> [[SHUF_INS]], i8 [[SHUF_ELT2]], i64 1 +// CHECK-NEXT: [[SHUF_IDX4:%.*]] = extractelement <16 x i8> [[MASK]], i64 2 +// CHECK-NEXT: [[SHUF_ELT5:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX4]] +// CHECK-NEXT: [[SHUF_INS6:%.*]] = insertelement <16 x i8> [[SHUF_INS3]], i8 [[SHUF_ELT5]], i64 2 +// CHECK-NEXT: [[SHUF_IDX7:%.*]] = extractelement <16 x i8> [[MASK]], i64 3 +// CHECK-NEXT: [[SHUF_ELT8:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX7]] +// CHECK-NEXT: [[SHUF_INS9:%.*]] = insertelement <16 x i8> [[SHUF_INS6]], i8 [[SHUF_ELT8]], i64 3 +// CHECK-NEXT: [[SHUF_IDX10:%.*]] = extractelement <16 x i8> [[MASK]], i64 4 +// CHECK-NEXT: [[SHUF_ELT11:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX10]] +// CHECK-NEXT: [[SHUF_INS12:%.*]] = insertelement <16 x i8> [[SHUF_INS9]], i8 [[SHUF_ELT11]], i64 4 +// CHECK-NEXT: [[SHUF_IDX13:%.*]] = extractelement <16 x i8> [[MASK]], i64 5 +// CHECK-NEXT: [[SHUF_ELT14:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX13]] +// CHECK-NEXT: [[SHUF_INS15:%.*]] = insertelement <16 x i8> [[SHUF_INS12]], i8 [[SHUF_ELT14]], i64 5 +// CHECK-NEXT: [[SHUF_IDX16:%.*]] = extractelement <16 x i8> [[MASK]], i64 6 +// CHECK-NEXT: [[SHUF_ELT17:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX16]] +// CHECK-NEXT: [[SHUF_INS18:%.*]] = insertelement <16 x i8> [[SHUF_INS15]], i8 [[SHUF_ELT17]], i64 6 +// CHECK-NEXT: [[SHUF_IDX19:%.*]] = extractelement <16 x i8> [[MASK]], i64 7 +// CHECK-NEXT: [[SHUF_ELT20:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX19]] +// CHECK-NEXT: [[SHUF_INS21:%.*]] = insertelement <16 x i8> [[SHUF_INS18]], i8 [[SHUF_ELT20]], i64 7 +// CHECK-NEXT: [[SHUF_IDX22:%.*]] = extractelement <16 x i8> [[MASK]], i64 8 +// CHECK-NEXT: [[SHUF_ELT23:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX22]] +// CHECK-NEXT: [[SHUF_INS24:%.*]] = insertelement <16 x i8> [[SHUF_INS21]], i8 [[SHUF_ELT23]], i64 8 +// CHECK-NEXT: [[SHUF_IDX25:%.*]] = extractelement <16 x i8> [[MASK]], i64 9 +// CHECK-NEXT: [[SHUF_ELT26:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX25]] +// CHECK-NEXT: [[SHUF_INS27:%.*]] = insertelement <16 x i8> [[SHUF_INS24]], i8 [[SHUF_ELT26]], i64 9 +// CHECK-NEXT: [[SHUF_IDX28:%.*]] = extractelement <16 x i8> [[MASK]], i64 10 +// CHECK-NEXT: [[SHUF_ELT29:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX28]] +// CHECK-NEXT: [[SHUF_INS30:%.*]] = insertelement <16 x i8> [[SHUF_INS27]], i8 [[SHUF_ELT29]], i64 10 +// CHECK-NEXT: [[SHUF_IDX31:%.*]] = extractelement <16 x i8> [[MASK]], i64 11 +// CHECK-NEXT: [[SHUF_ELT32:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX31]] +// CHECK-NEXT: [[SHUF_INS33:%.*]] = insertelement <16 x i8> [[SHUF_INS30]], i8 [[SHUF_ELT32]], i64 11 +// CHECK-NEXT: [[SHUF_IDX34:%.*]] = extractelement <16 x i8> [[MASK]], i64 12 +// CHECK-NEXT: [[SHUF_ELT35:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX34]] +// CHECK-NEXT: [[SHUF_INS36:%.*]] = insertelement <16 x i8> [[SHUF_INS33]], i8 [[SHUF_ELT35]], i64 12 +// CHECK-NEXT: [[SHUF_IDX37:%.*]] = extractelement <16 x i8> [[MASK]], i64 13 +// CHECK-NEXT: [[SHUF_ELT38:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX37]] +// CHECK-NEXT: [[SHUF_INS39:%.*]] = insertelement <16 x i8> [[SHUF_INS36]], i8 [[SHUF_ELT38]], i64 13 +// CHECK-NEXT: [[SHUF_IDX40:%.*]] = extractelement <16 x i8> [[MASK]], i64 14 +// CHECK-NEXT: [[SHUF_ELT41:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX40]] +// CHECK-NEXT: [[SHUF_INS42:%.*]] = insertelement <16 x i8> [[SHUF_INS39]], i8 [[SHUF_ELT41]], i64 14 +// CHECK-NEXT: [[SHUF_IDX43:%.*]] = extractelement <16 x i8> [[MASK]], i64 15 +// CHECK-NEXT: [[SHUF_ELT44:%.*]] = extractelement <16 x i8> [[X]], i8 [[SHUF_IDX43]] +// CHECK-NEXT: [[SHUF_INS45:%.*]] = insertelement <16 x i8> [[SHUF_INS42]], i8 [[SHUF_ELT44]], i64 15 +// CHECK-NEXT: ret <16 x i8> [[SHUF_INS45]] +// +mfloat8x16_t test_8x16_v(mfloat8x16_t x, int8x16_t p) { + return __builtin_shufflevector(x, p); +} diff --git a/clang/test/CodeGen/AArch64/fp8-cast.c b/clang/test/CodeGen/AArch64/fp8-cast.c new file mode 100644 index 0000000000000..a9ce31b9e6bea --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-cast.c @@ -0,0 +1,193 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +neon -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s -check-prefix CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -disable-O0-optnone -Werror -Wall -S -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#include + +// Bitcast between FP8 Neon vectors +// CHECK-LABEL: define dso_local <8 x i8> @test_f8_f8( +// CHECK-SAME: <8 x i8> [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[X]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z10test_f8_f813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[X]] +// +mfloat8x8_t test_f8_f8(mfloat8x8_t x) { + return (mfloat8x8_t) x; +} + +// CHECK-LABEL: define dso_local <16 x i8> @testq_f8_f8( +// CHECK-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[X]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z11testq_f8_f814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[X]] +// +mfloat8x16_t testq_f8_f8(mfloat8x16_t x) { + return (mfloat8x16_t) x; +} + +// Bitcast between FP8 and int8 Neon vectors +// CHECK-LABEL: define dso_local <8 x i8> @test_f8_s8( +// CHECK-SAME: <8 x i8> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[X]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z10test_f8_s810__Int8x8_t( +// CHECK-CXX-SAME: <8 x i8> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[X]] +// +mfloat8x8_t test_f8_s8(int8x8_t x) { + return (mfloat8x8_t) x; +} + +// CHECK-LABEL: define dso_local <8 x i8> @test_s8_f8( +// CHECK-SAME: <8 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[X]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x i8> @_Z10test_s8_f813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[X]] +// +int8x8_t test_s8_f8(mfloat8x8_t x) { + return (int8x8_t) x; +} + +// CHECK-LABEL: define dso_local <16 x i8> @testq_f8_s8( +// CHECK-SAME: <16 x i8> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[X]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z11testq_f8_s811__Int8x16_t( +// CHECK-CXX-SAME: <16 x i8> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[X]] +// +mfloat8x16_t testq_f8_s8(int8x16_t x) { + return (mfloat8x16_t) x; +} + +// CHECK-LABEL: define dso_local <16 x i8> @testq_s8_f8( +// CHECK-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[X]] +// +// CHECK-CXX-LABEL: define dso_local noundef <16 x i8> @_Z11testq_s8_f814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[X]] +// +int8x16_t testq_s8_f8(mfloat8x16_t x) { + return (int8x16_t) x; +} + +// Bitcast between FP8 and float32 Neon vectors +// CHECK-LABEL: define dso_local <8 x i8> @test_f8_f32( +// CHECK-SAME: <2 x float> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[X]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z11test_f8_f3213__Float32x2_t( +// CHECK-CXX-SAME: <2 x float> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[X]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_f8_f32(float32x2_t x) { + return (mfloat8x8_t) x; +} + +// CHECK-LABEL: define dso_local <2 x float> @test_f32_f8( +// CHECK-SAME: <8 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[X]] to <2 x float> +// CHECK-NEXT: ret <2 x float> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x float> @_Z11test_f32_f813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[X]] to <2 x float> +// CHECK-CXX-NEXT: ret <2 x float> [[TMP0]] +// +float32x2_t test_f32_f8(mfloat8x8_t x) { + return (float32x2_t) x; +} + +// CHECK-LABEL: define dso_local <16 x i8> @testq_f8_f32( +// CHECK-SAME: <4 x float> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[X]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z12testq_f8_f3213__Float32x4_t( +// CHECK-CXX-SAME: <4 x float> noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[X]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t testq_f8_f32(float32x4_t x) { + return (mfloat8x16_t) x; +} + +// CHECK-LABEL: define dso_local <4 x float> @testq_f32_f8( +// CHECK-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[X]] to <4 x float> +// CHECK-NEXT: ret <4 x float> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z12testq_f32_f814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[X]] to <4 x float> +// CHECK-CXX-NEXT: ret <4 x float> [[TMP0]] +// +float32x4_t testq_f32_f8(mfloat8x16_t x) { + return (float32x4_t) x; +} + +// Bitcast between FP8 and poly128_t (which is integral) +// CHECK-LABEL: define dso_local <16 x i8> @testq_f8_p128( +// CHECK-SAME: i128 noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[X]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z13testq_f8_p128o( +// CHECK-CXX-SAME: i128 noundef [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast i128 [[X]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t testq_f8_p128(poly128_t x) { + return (mfloat8x16_t) x; +} + +// CHECK-LABEL: define dso_local i128 @testq_p128_f8( +// CHECK-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[X]] to i128 +// CHECK-NEXT: ret i128 [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef i128 @_Z13testq_p128_f814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[X]] to i128 +// CHECK-CXX-NEXT: ret i128 [[TMP0]] +// +poly128_t testq_p128_f8(mfloat8x16_t x) { + return (poly128_t) x; +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_cvt.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_cvt.c new file mode 100644 index 0000000000000..4305b840f2a05 --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_cvt.c @@ -0,0 +1,316 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s -check-prefix CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -S -O3 -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#include + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vcvt1_bf16_mf8_fpm( +// CHECK-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT1_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl1.v8bf16.v8i8(<8 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x bfloat> [[VBFCVT1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x bfloat> @_Z23test_vcvt1_bf16_mf8_fpm13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT1_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl1.v8bf16.v8i8(<8 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x bfloat> [[VBFCVT1_I]] +// +bfloat16x8_t test_vcvt1_bf16_mf8_fpm(mfloat8x8_t op, fpm_t fpm) { + return vcvt1_bf16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vcvt1_low_bf16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT1_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl1.v8bf16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-NEXT: ret <8 x bfloat> [[VBFCVT1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x bfloat> @_Z27test_vcvt1_low_bf16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT1_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl1.v8bf16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-CXX-NEXT: ret <8 x bfloat> [[VBFCVT1_I]] +// +bfloat16x8_t test_vcvt1_low_bf16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt1_low_bf16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vcvt2_bf16_mf8_fpm( +// CHECK-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT2_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl2.v8bf16.v8i8(<8 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x bfloat> [[VBFCVT2_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x bfloat> @_Z23test_vcvt2_bf16_mf8_fpm13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT2_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl2.v8bf16.v8i8(<8 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x bfloat> [[VBFCVT2_I]] +// +bfloat16x8_t test_vcvt2_bf16_mf8_fpm(mfloat8x8_t op, fpm_t fpm) { + return vcvt2_bf16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vcvt2_low_bf16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT2_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl2.v8bf16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-NEXT: ret <8 x bfloat> [[VBFCVT2_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x bfloat> @_Z27test_vcvt2_low_bf16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT2_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl2.v8bf16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-CXX-NEXT: ret <8 x bfloat> [[VBFCVT2_I]] +// +bfloat16x8_t test_vcvt2_low_bf16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt2_low_bf16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vcvt1_high_bf16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT1_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl1.v8bf16.v16i8(<16 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x bfloat> [[VBFCVT1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x bfloat> @_Z28test_vcvt1_high_bf16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT1_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl1.v8bf16.v16i8(<16 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x bfloat> [[VBFCVT1_I]] +// +bfloat16x8_t test_vcvt1_high_bf16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt1_high_bf16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x bfloat> @test_vcvt2_high_bf16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT2_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl2.v8bf16.v16i8(<16 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x bfloat> [[VBFCVT2_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x bfloat> @_Z28test_vcvt2_high_bf16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT2_I:%.*]] = call <8 x bfloat> @llvm.aarch64.neon.fp8.cvtl2.v8bf16.v16i8(<16 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x bfloat> [[VBFCVT2_I]] +// +bfloat16x8_t test_vcvt2_high_bf16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt2_high_bf16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vcvt1_f16_mf8_fpm( +// CHECK-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl1.v8f16.v8i8(<8 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x half> [[VBFCVT1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z22test_vcvt1_f16_mf8_fpm13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl1.v8f16.v8i8(<8 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VBFCVT1_I]] +// +float16x8_t test_vcvt1_f16_mf8_fpm(mfloat8x8_t op, fpm_t fpm) { + return vcvt1_f16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vcvt1_low_f16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl1.v8f16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-NEXT: ret <8 x half> [[VBFCVT1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z26test_vcvt1_low_f16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl1.v8f16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VBFCVT1_I]] +// +float16x8_t test_vcvt1_low_f16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt1_low_f16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vcvt2_f16_mf8_fpm( +// CHECK-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl2.v8f16.v8i8(<8 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x half> [[VBFCVT2_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z22test_vcvt2_f16_mf8_fpm13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <8 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl2.v8f16.v8i8(<8 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VBFCVT2_I]] +// +float16x8_t test_vcvt2_f16_mf8_fpm(mfloat8x8_t op, fpm_t fpm) { + return vcvt2_f16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vcvt2_low_f16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl2.v8f16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-NEXT: ret <8 x half> [[VBFCVT2_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z26test_vcvt2_low_f16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <8 x i8> @llvm.vector.extract.v8i8.v16i8(<16 x i8> [[OP]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl2.v8f16.v8i8(<8 x i8> [[TMP0]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VBFCVT2_I]] +// +float16x8_t test_vcvt2_low_f16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt2_low_f16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vcvt1_high_f16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl1.v8f16.v16i8(<16 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x half> [[VBFCVT1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z27test_vcvt1_high_f16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl1.v8f16.v16i8(<16 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VBFCVT1_I]] +// +float16x8_t test_vcvt1_high_f16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt1_high_f16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vcvt2_high_f16_mf8_fpm( +// CHECK-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VBFCVT2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl2.v8f16.v16i8(<16 x i8> [[OP]]) +// CHECK-NEXT: ret <8 x half> [[VBFCVT2_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z27test_vcvt2_high_f16_mf8_fpm14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <16 x i8> [[OP:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VBFCVT2_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.cvtl2.v8f16.v16i8(<16 x i8> [[OP]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VBFCVT2_I]] +// +float16x8_t test_vcvt2_high_f16_mf8_fpm(mfloat8x16_t op, fpm_t fpm) { + return vcvt2_high_f16_mf8_fpm(op, fpm); +} + +// CHECK-LABEL: define dso_local <8 x i8> @test_vcvt_mf8_f32_fpm( +// CHECK-SAME: <4 x float> noundef [[VN:%.*]], <4 x float> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VFCVTN_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.fp8.fcvtn.v8i8.v4f32(<4 x float> [[VN]], <4 x float> [[VM]]) +// CHECK-NEXT: ret <8 x i8> [[VFCVTN_I]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z21test_vcvt_mf8_f32_fpm13__Float32x4_tS_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VN:%.*]], <4 x float> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VFCVTN_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.fp8.fcvtn.v8i8.v4f32(<4 x float> [[VN]], <4 x float> [[VM]]) +// CHECK-CXX-NEXT: ret <8 x i8> [[VFCVTN_I]] +// +mfloat8x8_t test_vcvt_mf8_f32_fpm(float32x4_t vn, float32x4_t vm, fpm_t fpm) { + return vcvt_mf8_f32_fpm(vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vcvt_high_mf8_f32_fpm( +// CHECK-SAME: <8 x i8> [[VD:%.*]], <4 x float> noundef [[VN:%.*]], <4 x float> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VD]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VFCVTN2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.fp8.fcvtn2.v16i8.v4f32(<16 x i8> [[TMP0]], <4 x float> [[VN]], <4 x float> [[VM]]) +// CHECK-NEXT: ret <16 x i8> [[VFCVTN2_I]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vcvt_high_mf8_f32_fpm13__Mfloat8x8_t13__Float32x4_tS0_m( +// CHECK-CXX-SAME: <8 x i8> [[VD:%.*]], <4 x float> noundef [[VN:%.*]], <4 x float> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VD]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VFCVTN2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.fp8.fcvtn2.v16i8.v4f32(<16 x i8> [[TMP0]], <4 x float> [[VN]], <4 x float> [[VM]]) +// CHECK-CXX-NEXT: ret <16 x i8> [[VFCVTN2_I]] +// +mfloat8x16_t test_vcvt_high_mf8_f32_fpm(mfloat8x8_t vd, float32x4_t vn, + float32x4_t vm, fpm_t fpm) { + return vcvt_high_mf8_f32_fpm(vd, vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <8 x i8> @test_vcvt_mf8_f16_fpm( +// CHECK-SAME: <4 x half> noundef [[VN:%.*]], <4 x half> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VN]] to <8 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[VM]] to <8 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VFCVTN2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.fp8.fcvtn.v8i8.v4f16(<4 x half> [[VN]], <4 x half> [[VM]]) +// CHECK-NEXT: ret <8 x i8> [[VFCVTN2_I]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z21test_vcvt_mf8_f16_fpm13__Float16x4_tS_m( +// CHECK-CXX-SAME: <4 x half> noundef [[VN:%.*]], <4 x half> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VN]] to <8 x i8> +// CHECK-CXX-NEXT: [[TMP1:%.*]] = bitcast <4 x half> [[VM]] to <8 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VFCVTN2_I:%.*]] = call <8 x i8> @llvm.aarch64.neon.fp8.fcvtn.v8i8.v4f16(<4 x half> [[VN]], <4 x half> [[VM]]) +// CHECK-CXX-NEXT: ret <8 x i8> [[VFCVTN2_I]] +// +mfloat8x8_t test_vcvt_mf8_f16_fpm(float16x4_t vn, float16x4_t vm, fpm_t fpm) { + return vcvt_mf8_f16_fpm(vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <16 x i8> @test_vcvtq_mf8_f16_fpm( +// CHECK-SAME: <8 x half> noundef [[VN:%.*]], <8 x half> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VN]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[VM]] to <16 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VFCVTN2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.fp8.fcvtn.v16i8.v8f16(<8 x half> [[VN]], <8 x half> [[VM]]) +// CHECK-NEXT: ret <16 x i8> [[VFCVTN2_I]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z22test_vcvtq_mf8_f16_fpm13__Float16x8_tS_m( +// CHECK-CXX-SAME: <8 x half> noundef [[VN:%.*]], <8 x half> noundef [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VN]] to <16 x i8> +// CHECK-CXX-NEXT: [[TMP1:%.*]] = bitcast <8 x half> [[VM]] to <16 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VFCVTN2_I:%.*]] = call <16 x i8> @llvm.aarch64.neon.fp8.fcvtn.v16i8.v8f16(<8 x half> [[VN]], <8 x half> [[VM]]) +// CHECK-CXX-NEXT: ret <16 x i8> [[VFCVTN2_I]] +// +mfloat8x16_t test_vcvtq_mf8_f16_fpm(float16x8_t vn, float16x8_t vm, fpm_t fpm) { + return vcvtq_mf8_f16_fpm(vn, vm, fpm); +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_fdot.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_fdot.c new file mode 100644 index 0000000000000..4d2f5d550c4dc --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_fdot.c @@ -0,0 +1,254 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8dot2 -target-feature +fp8dot4 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8dot2 -target-feature +fp8dot4 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s -check-prefix CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8dot2 -target-feature +fp8dot4 -O3 -Werror -Wall -S -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#include + +// CHECK-LABEL: define dso_local <4 x half> @test_vdot_f16( +// CHECK-SAME: <4 x half> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VD]] to <8 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT21_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fp8.fdot2.v4f16.v8i8(<4 x half> [[VD]], <8 x i8> [[VN]], <8 x i8> [[VM]]) +// CHECK-NEXT: ret <4 x half> [[FDOT21_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x half> @_Z13test_vdot_f1613__Float16x4_t13__Mfloat8x8_tS0_m( +// CHECK-CXX-SAME: <4 x half> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VD]] to <8 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT21_I:%.*]] = call <4 x half> @llvm.aarch64.neon.fp8.fdot2.v4f16.v8i8(<4 x half> [[VD]], <8 x i8> [[VN]], <8 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <4 x half> [[FDOT21_I]] +// +float16x4_t test_vdot_f16(float16x4_t vd, mfloat8x8_t vn, mfloat8x8_t vm, fpm_t fpmr) { + return vdot_f16_mf8_fpm(vd, vn, vm, fpmr); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vdotq_f16( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT21_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fdot2.v8f16.v16i8(<8 x half> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <8 x half> [[FDOT21_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z14test_vdotq_f1613__Float16x8_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT21_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fdot2.v8f16.v16i8(<8 x half> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <8 x half> [[FDOT21_I]] +// +float16x8_t test_vdotq_f16(float16x8_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpmr) { + return vdotq_f16_mf8_fpm(vd, vn, vm, fpmr); +} + +// CHECK-LABEL: define dso_local <4 x half> @test_vdot_lane_f16( +// CHECK-SAME: <4 x half> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VD]] to <8 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT2_LANE:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> +// CHECK-NEXT: [[FDOT2_LANE1:%.*]] = call <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v4f16.v8i8(<4 x half> [[FDOT2_LANE]], <8 x i8> [[VN]], <16 x i8> [[TMP1]], i32 3) +// CHECK-NEXT: ret <4 x half> [[FDOT2_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x half> @_Z18test_vdot_lane_f1613__Float16x4_t13__Mfloat8x8_tS0_m( +// CHECK-CXX-SAME: <4 x half> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VD]] to <8 x i8> +// CHECK-CXX-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT2_LANE:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> +// CHECK-CXX-NEXT: [[FDOT2_LANE1:%.*]] = call <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v4f16.v8i8(<4 x half> [[FDOT2_LANE]], <8 x i8> [[VN]], <16 x i8> [[TMP1]], i32 3) +// CHECK-CXX-NEXT: ret <4 x half> [[FDOT2_LANE1]] +// +float16x4_t test_vdot_lane_f16(float16x4_t vd, mfloat8x8_t vn, mfloat8x8_t vm, fpm_t fpmr) { + return vdot_lane_f16_mf8_fpm(vd, vn, vm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local <4 x half> @test_vdot_laneq_f16( +// CHECK-SAME: <4 x half> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VD]] to <8 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT2_LANE:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> +// CHECK-NEXT: [[FDOT2_LANE1:%.*]] = call <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v4f16.v8i8(<4 x half> [[FDOT2_LANE]], <8 x i8> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <4 x half> [[FDOT2_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x half> @_Z19test_vdot_laneq_f1613__Float16x4_t13__Mfloat8x8_t14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <4 x half> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[VD]] to <8 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT2_LANE:%.*]] = bitcast <8 x i8> [[TMP0]] to <4 x half> +// CHECK-CXX-NEXT: [[FDOT2_LANE1:%.*]] = call <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v4f16.v8i8(<4 x half> [[FDOT2_LANE]], <8 x i8> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-CXX-NEXT: ret <4 x half> [[FDOT2_LANE1]] +// +float16x4_t test_vdot_laneq_f16(float16x4_t vd, mfloat8x8_t vn, mfloat8x16_t vm, fpm_t fpmr) { + return vdot_laneq_f16_mf8_fpm(vd, vn, vm, 7, fpmr); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vdotq_lane_f16( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT2_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-NEXT: [[FDOT2_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v8f16.v16i8(<8 x half> [[FDOT2_LANE]], <16 x i8> [[VN]], <16 x i8> [[TMP1]], i32 3) +// CHECK-NEXT: ret <8 x half> [[FDOT2_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z19test_vdotq_lane_f1613__Float16x8_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT2_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-CXX-NEXT: [[FDOT2_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v8f16.v16i8(<8 x half> [[FDOT2_LANE]], <16 x i8> [[VN]], <16 x i8> [[TMP1]], i32 3) +// CHECK-CXX-NEXT: ret <8 x half> [[FDOT2_LANE1]] +// +float16x8_t test_vdotq_lane_f16(float16x8_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpmr) { + return vdotq_lane_f16_mf8_fpm(vd, vn, vm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vdotq_laneq_f16( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT2_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-NEXT: [[FDOT2_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v8f16.v16i8(<8 x half> [[FDOT2_LANE]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <8 x half> [[FDOT2_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z20test_vdotq_laneq_f1613__Float16x8_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT2_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-CXX-NEXT: [[FDOT2_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane.v8f16.v16i8(<8 x half> [[FDOT2_LANE]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-CXX-NEXT: ret <8 x half> [[FDOT2_LANE1]] +// +float16x8_t test_vdotq_laneq_f16(float16x8_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpmr) { + return vdotq_laneq_f16_mf8_fpm(vd, vn, vm, 7, fpmr); +} + +// CHECK-LABEL: define dso_local <2 x float> @test_vdot_f32( +// CHECK-SAME: <2 x float> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT4_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fp8.fdot4.v2f32.v8i8(<2 x float> [[VD]], <8 x i8> [[VN]], <8 x i8> [[VM]]) +// CHECK-NEXT: ret <2 x float> [[FDOT4_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x float> @_Z13test_vdot_f3213__Float32x2_t13__Mfloat8x8_tS0_m( +// CHECK-CXX-SAME: <2 x float> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT4_I:%.*]] = call <2 x float> @llvm.aarch64.neon.fp8.fdot4.v2f32.v8i8(<2 x float> [[VD]], <8 x i8> [[VN]], <8 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <2 x float> [[FDOT4_I]] +// +float32x2_t test_vdot_f32(float32x2_t vd, mfloat8x8_t vn, mfloat8x8_t vm, fpm_t fpmr) { + return vdot_f32_mf8_fpm(vd, vn, vm, fpmr); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vdotq_f32( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT4_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fdot4.v4f32.v16i8(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <4 x float> [[FDOT4_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z14test_vdotq_f3213__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT4_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fdot4.v4f32.v16i8(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <4 x float> [[FDOT4_I]] +// +float32x4_t test_vdotq_f32(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpmr) { + return vdotq_f32_mf8_fpm(vd, vn, vm, fpmr); +} + +// CHECK-LABEL: define dso_local <2 x float> @test_vdot_lane_f32( +// CHECK-SAME: <2 x float> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT4_LANE:%.*]] = call <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v2f32.v8i8(<2 x float> [[VD]], <8 x i8> [[VN]], <16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: ret <2 x float> [[FDOT4_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x float> @_Z18test_vdot_lane_f3213__Float32x2_t13__Mfloat8x8_tS0_m( +// CHECK-CXX-SAME: <2 x float> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT4_LANE:%.*]] = call <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v2f32.v8i8(<2 x float> [[VD]], <8 x i8> [[VN]], <16 x i8> [[TMP0]], i32 1) +// CHECK-CXX-NEXT: ret <2 x float> [[FDOT4_LANE]] +// +float32x2_t test_vdot_lane_f32(float32x2_t vd, mfloat8x8_t vn, mfloat8x8_t vm, fpm_t fpmr) { + return vdot_lane_f32_mf8_fpm(vd, vn, vm, 1, fpmr); +} + +// CHECK-LABEL: define dso_local <2 x float> @test_vdot_laneq_f32( +// CHECK-SAME: <2 x float> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT4_LANE:%.*]] = call <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v2f32.v8i8(<2 x float> [[VD]], <8 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <2 x float> [[FDOT4_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x float> @_Z19test_vdot_laneq_f3213__Float32x2_t13__Mfloat8x8_t14__Mfloat8x16_tm( +// CHECK-CXX-SAME: <2 x float> noundef [[VD:%.*]], <8 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT4_LANE:%.*]] = call <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v2f32.v8i8(<2 x float> [[VD]], <8 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-CXX-NEXT: ret <2 x float> [[FDOT4_LANE]] +// +float32x2_t test_vdot_laneq_f32(float32x2_t vd, mfloat8x8_t vn, mfloat8x16_t vm, fpm_t fpmr) { + return vdot_laneq_f32_mf8_fpm(vd, vn, vm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vdotq_lane_f32( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT4_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v4f32.v16i8(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 1) +// CHECK-NEXT: ret <4 x float> [[FDOT4_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z19test_vdotq_lane_f3213__Float32x4_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT4_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v4f32.v16i8(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 1) +// CHECK-CXX-NEXT: ret <4 x float> [[FDOT4_LANE]] +// +float32x4_t test_vdotq_lane_f32(float32x4_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpmr) { + return vdotq_lane_f32_mf8_fpm(vd, vn, vm, 1, fpmr); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vdotq_laneq_f32( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: [[FDOT4_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v4f32.v16i8(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <4 x float> [[FDOT4_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z20test_vdotq_laneq_f3213__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-CXX-NEXT: [[FDOT4_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane.v4f32.v16i8(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-CXX-NEXT: ret <4 x float> [[FDOT4_LANE]] +// +float32x4_t test_vdotq_laneq_f32(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpmr) { + return vdotq_laneq_f32_mf8_fpm(vd, vn, vm, 3, fpmr); +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_fmla.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_fmla.c new file mode 100644 index 0000000000000..736538073cb39 --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_fmla.c @@ -0,0 +1,365 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s -check-prefix CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -S -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#include + +// CHECK-LABEL: define dso_local <8 x half> @test_vmlalb( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLAL1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalb.v8f16(<8 x half> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <8 x half> [[VMLAL1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z11test_vmlalb13__Float16x8_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLAL1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalb.v8f16(<8 x half> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VMLAL1_I]] +// +float16x8_t test_vmlalb(float16x8_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlalbq_f16_mf8_fpm(vd, vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vmlalt( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLAL1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalt.v8f16(<8 x half> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <8 x half> [[VMLAL1_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z11test_vmlalt13__Float16x8_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLAL1_I:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalt.v8f16(<8 x half> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <8 x half> [[VMLAL1_I]] +// +float16x8_t test_vmlalt(float16x8_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlaltq_f16_mf8_fpm(vd, vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlallbb( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbb.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <4 x float> [[VMLALL_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z13test_vmlallbb13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbb.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_I]] +// +float32x4_t test_vmlallbb(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlallbbq_f32_mf8_fpm(vd, vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlallbt( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbt.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <4 x float> [[VMLALL_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z13test_vmlallbt13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbt.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_I]] +// +float32x4_t test_vmlallbt(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlallbtq_f32_mf8_fpm(vd, vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlalltb( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltb.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <4 x float> [[VMLALL_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z13test_vmlalltb13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltb.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_I]] +// +float32x4_t test_vmlalltb(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlalltbq_f32_mf8_fpm(vd, vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlalltt( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltt.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-NEXT: ret <4 x float> [[VMLALL_I]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z13test_vmlalltt13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_I:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltt.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]]) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_I]] +// +float32x4_t test_vmlalltt(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlallttq_f32_mf8_fpm(vd, vn, vm, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vmlalb_lane( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalb.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[TMP1]], i32 0) +// CHECK-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z16test_vmlalb_lane13__Float16x8_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-CXX-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalb.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[TMP1]], i32 0) +// CHECK-CXX-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +float16x8_t test_vmlalb_lane(float16x8_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpm) { + return vmlalbq_lane_f16_mf8_fpm(vd, vn, vm, 0, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vmlalb_laneq( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalb.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z17test_vmlalb_laneq13__Float16x8_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-CXX-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalb.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-CXX-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +float16x8_t test_vmlalb_laneq(float16x8_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlalbq_laneq_f16_mf8_fpm(vd, vn, vm, 0, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vmlalt_lane( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalt.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[TMP1]], i32 7) +// CHECK-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z16test_vmlalt_lane13__Float16x8_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: [[TMP1:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-CXX-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalt.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[TMP1]], i32 7) +// CHECK-CXX-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +float16x8_t test_vmlalt_lane(float16x8_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpm) { + return vmlaltq_lane_f16_mf8_fpm(vd, vn, vm, 7, fpm); +} + +// CHECK-LABEL: define dso_local <8 x half> @test_vmlalt_laneq( +// CHECK-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalt.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 15) +// CHECK-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z17test_vmlalt_laneq13__Float16x8_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <8 x half> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[VD]] to <16 x i8> +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLAL_LANE:%.*]] = bitcast <16 x i8> [[TMP0]] to <8 x half> +// CHECK-CXX-NEXT: [[VMLAL_LANE1:%.*]] = call <8 x half> @llvm.aarch64.neon.fp8.fmlalt.lane.v8f16(<8 x half> [[VMLAL_LANE]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 15) +// CHECK-CXX-NEXT: ret <8 x half> [[VMLAL_LANE1]] +// +float16x8_t test_vmlalt_laneq(float16x8_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlaltq_laneq_f16_mf8_fpm(vd, vn, vm, 15, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlallbb_lane( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 0) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z18test_vmlallbb_lane13__Float32x4_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 0) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlallbb_lane(float32x4_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpm) { + return vmlallbbq_lane_f32_mf8_fpm(vd, vn, vm, 0, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlallbb_laneq( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z19test_vmlallbb_laneq13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 0) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlallbb_laneq(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlallbbq_laneq_f32_mf8_fpm(vd, vn, vm, 0, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlallbt_lane( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 3) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z18test_vmlallbt_lane13__Float32x4_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 3) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlallbt_lane(float32x4_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpm) { + return vmlallbtq_lane_f32_mf8_fpm(vd, vn, vm, 3, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlallbt_laneq( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z19test_vmlallbt_laneq13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlallbt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 3) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlallbt_laneq(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlallbtq_laneq_f32_mf8_fpm(vd, vn, vm, 3, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlalltb_lane( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 7) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z18test_vmlalltb_lane13__Float32x4_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 7) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlalltb_lane(float32x4_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpm) { + return vmlalltbq_lane_f32_mf8_fpm(vd, vn, vm, 7, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlalltb_laneq( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z19test_vmlalltb_laneq13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltb.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 7) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlalltb_laneq(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlalltbq_laneq_f32_mf8_fpm(vd, vn, vm, 7, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlalltt_lane( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 7) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z18test_vmlalltt_lane13__Float32x4_t14__Mfloat8x16_t13__Mfloat8x8_tm( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <8 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = call <16 x i8> @llvm.vector.insert.v16i8.v8i8(<16 x i8> poison, <8 x i8> [[VM]], i64 0) +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[TMP0]], i32 7) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlalltt_lane(float32x4_t vd, mfloat8x16_t vn, mfloat8x8_t vm, fpm_t fpm) { + return vmlallttq_lane_f32_mf8_fpm(vd, vn, vm, 7, fpm); +} + +// CHECK-LABEL: define dso_local <4 x float> @test_vmlalltt_laneq( +// CHECK-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 15) +// CHECK-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z19test_vmlalltt_laneq13__Float32x4_t14__Mfloat8x16_tS0_m( +// CHECK-CXX-SAME: <4 x float> noundef [[VD:%.*]], <16 x i8> [[VN:%.*]], <16 x i8> [[VM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[VMLALL_LANE:%.*]] = call <4 x float> @llvm.aarch64.neon.fp8.fmlalltt.lane.v4f32(<4 x float> [[VD]], <16 x i8> [[VN]], <16 x i8> [[VM]], i32 15) +// CHECK-CXX-NEXT: ret <4 x float> [[VMLALL_LANE]] +// +float32x4_t test_vmlalltt_laneq(float32x4_t vd, mfloat8x16_t vn, mfloat8x16_t vm, fpm_t fpm) { + return vmlallttq_laneq_f32_mf8_fpm(vd, vn, vm, 15, fpm); +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_reinterpret.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_reinterpret.c new file mode 100644 index 0000000000000..201d4dbbe34ad --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_neon_fp8_reinterpret.c @@ -0,0 +1,855 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +#include +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg | FileCheck %s -check-prefix CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -S -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_p8_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x i8> @_Z24test_vreinterpret_p8_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[V]] +// +poly8x8_t test_vreinterpret_p8_mf8(mfloat8x8_t v) { + return vreinterpret_p8_mf8(v); +} +// CHECK-LABEL: define dso_local <1 x i64> @test_vreinterpret_p64_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x i64> +// CHECK-NEXT: ret <1 x i64> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <1 x i64> @_Z25test_vreinterpret_p64_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x i64> +// CHECK-CXX-NEXT: ret <1 x i64> [[TMP0]] +// +poly64x1_t test_vreinterpret_p64_mf8(mfloat8x8_t v) { + return vreinterpret_p64_mf8(v); +} +// CHECK-LABEL: define dso_local <4 x i16> @test_vreinterpret_p16_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x i16> +// CHECK-NEXT: ret <4 x i16> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x i16> @_Z25test_vreinterpret_p16_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x i16> +// CHECK-CXX-NEXT: ret <4 x i16> [[TMP0]] +// +poly16x4_t test_vreinterpret_p16_mf8(mfloat8x8_t v) { + return vreinterpret_p16_mf8(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_p8_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local noundef <16 x i8> @_Z25test_vreinterpretq_p8_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[V]] +// +poly8x16_t test_vreinterpretq_p8_mf8(mfloat8x16_t v) { + return vreinterpretq_p8_mf8(v); +} +// CHECK-LABEL: define dso_local i128 @test_vreinterpretq_p128_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to i128 +// CHECK-NEXT: ret i128 [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef i128 @_Z27test_vreinterpretq_p128_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to i128 +// CHECK-CXX-NEXT: ret i128 [[TMP0]] +// +poly128_t test_vreinterpretq_p128_mf8(mfloat8x16_t v) { + return vreinterpretq_p128_mf8(v); +} +// CHECK-LABEL: define dso_local <2 x i64> @test_vreinterpretq_p64_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x i64> +// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x i64> @_Z26test_vreinterpretq_p64_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x i64> +// CHECK-CXX-NEXT: ret <2 x i64> [[TMP0]] +// +poly64x2_t test_vreinterpretq_p64_mf8(mfloat8x16_t v) { + return vreinterpretq_p64_mf8(v); +} +// CHECK-LABEL: define dso_local <8 x i16> @test_vreinterpretq_p16_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x i16> +// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x i16> @_Z26test_vreinterpretq_p16_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x i16> +// CHECK-CXX-NEXT: ret <8 x i16> [[TMP0]] +// +poly16x8_t test_vreinterpretq_p16_mf8(mfloat8x16_t v) { + return vreinterpretq_p16_mf8(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_u8_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local noundef <16 x i8> @_Z25test_vreinterpretq_u8_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[V]] +// +uint8x16_t test_vreinterpretq_u8_mf8(mfloat8x16_t v) { + return vreinterpretq_u8_mf8(v); +} +// CHECK-LABEL: define dso_local <4 x i32> @test_vreinterpretq_u32_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <4 x i32> +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x i32> @_Z26test_vreinterpretq_u32_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <4 x i32> +// CHECK-CXX-NEXT: ret <4 x i32> [[TMP0]] +// +uint32x4_t test_vreinterpretq_u32_mf8(mfloat8x16_t v) { + return vreinterpretq_u32_mf8(v); +} +// CHECK-LABEL: define dso_local <2 x i64> @test_vreinterpretq_u64_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x i64> +// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x i64> @_Z26test_vreinterpretq_u64_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x i64> +// CHECK-CXX-NEXT: ret <2 x i64> [[TMP0]] +// +uint64x2_t test_vreinterpretq_u64_mf8(mfloat8x16_t v) { + return vreinterpretq_u64_mf8(v); +} +// CHECK-LABEL: define dso_local <8 x i16> @test_vreinterpretq_u16_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x i16> +// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x i16> @_Z26test_vreinterpretq_u16_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x i16> +// CHECK-CXX-NEXT: ret <8 x i16> [[TMP0]] +// +uint16x8_t test_vreinterpretq_u16_mf8(mfloat8x16_t v) { + return vreinterpretq_u16_mf8(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_s8_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local noundef <16 x i8> @_Z25test_vreinterpretq_s8_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[V]] +// +int8x16_t test_vreinterpretq_s8_mf8(mfloat8x16_t v) { + return vreinterpretq_s8_mf8(v); +} +// CHECK-LABEL: define dso_local <2 x double> @test_vreinterpretq_f64_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x double> +// CHECK-NEXT: ret <2 x double> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x double> @_Z26test_vreinterpretq_f64_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x double> +// CHECK-CXX-NEXT: ret <2 x double> [[TMP0]] +// +float64x2_t test_vreinterpretq_f64_mf8(mfloat8x16_t v) { + return vreinterpretq_f64_mf8(v); +} +// CHECK-LABEL: define dso_local <4 x float> @test_vreinterpretq_f32_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <4 x float> +// CHECK-NEXT: ret <4 x float> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x float> @_Z26test_vreinterpretq_f32_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <4 x float> +// CHECK-CXX-NEXT: ret <4 x float> [[TMP0]] +// +float32x4_t test_vreinterpretq_f32_mf8(mfloat8x16_t v) { + return vreinterpretq_f32_mf8(v); +} +// CHECK-LABEL: define dso_local <8 x half> @test_vreinterpretq_f16_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x half> +// CHECK-NEXT: ret <8 x half> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x half> @_Z26test_vreinterpretq_f16_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x half> +// CHECK-CXX-NEXT: ret <8 x half> [[TMP0]] +// +float16x8_t test_vreinterpretq_f16_mf8(mfloat8x16_t v) { + return vreinterpretq_f16_mf8(v); +} +// CHECK-LABEL: define dso_local <4 x i32> @test_vreinterpretq_s32_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <4 x i32> +// CHECK-NEXT: ret <4 x i32> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x i32> @_Z26test_vreinterpretq_s32_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <4 x i32> +// CHECK-CXX-NEXT: ret <4 x i32> [[TMP0]] +// +int32x4_t test_vreinterpretq_s32_mf8(mfloat8x16_t v) { + return vreinterpretq_s32_mf8(v); +} +// CHECK-LABEL: define dso_local <2 x i64> @test_vreinterpretq_s64_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x i64> +// CHECK-NEXT: ret <2 x i64> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x i64> @_Z26test_vreinterpretq_s64_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <2 x i64> +// CHECK-CXX-NEXT: ret <2 x i64> [[TMP0]] +// +int64x2_t test_vreinterpretq_s64_mf8(mfloat8x16_t v) { + return vreinterpretq_s64_mf8(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_p8( +// CHECK-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z25test_vreinterpretq_mf8_p812__Poly8x16_t( +// CHECK-CXX-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[V]] +// +mfloat8x16_t test_vreinterpretq_mf8_p8(poly8x16_t v) { + return vreinterpretq_mf8_p8(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_p128( +// CHECK-SAME: i128 noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast i128 [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z27test_vreinterpretq_mf8_p128o( +// CHECK-CXX-SAME: i128 noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast i128 [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_p128(poly128_t v) { + return vreinterpretq_mf8_p128(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_p64( +// CHECK-SAME: <2 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_p6412__Poly64x2_t( +// CHECK-CXX-SAME: <2 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_p64(poly64x2_t v) { + return vreinterpretq_mf8_p64(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_p16( +// CHECK-SAME: <8 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_p1612__Poly16x8_t( +// CHECK-CXX-SAME: <8 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_p16(poly16x8_t v) { + return vreinterpretq_mf8_p16(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_u8( +// CHECK-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z25test_vreinterpretq_mf8_u812__Uint8x16_t( +// CHECK-CXX-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[V]] +// +mfloat8x16_t test_vreinterpretq_mf8_u8(uint8x16_t v) { + return vreinterpretq_mf8_u8(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_u32( +// CHECK-SAME: <4 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_u3212__Uint32x4_t( +// CHECK-CXX-SAME: <4 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_u32(uint32x4_t v) { + return vreinterpretq_mf8_u32(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_u64( +// CHECK-SAME: <2 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_u6412__Uint64x2_t( +// CHECK-CXX-SAME: <2 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_u64(uint64x2_t v) { + return vreinterpretq_mf8_u64(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_u16( +// CHECK-SAME: <8 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_u1612__Uint16x8_t( +// CHECK-CXX-SAME: <8 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_u16(uint16x8_t v) { + return vreinterpretq_mf8_u16(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_s8( +// CHECK-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <16 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z25test_vreinterpretq_mf8_s811__Int8x16_t( +// CHECK-CXX-SAME: <16 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <16 x i8> [[V]] +// +mfloat8x16_t test_vreinterpretq_mf8_s8(int8x16_t v) { + return vreinterpretq_mf8_s8(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_f64( +// CHECK-SAME: <2 x double> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_f6413__Float64x2_t( +// CHECK-CXX-SAME: <2 x double> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x double> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_f64(float64x2_t v) { + return vreinterpretq_mf8_f64(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_f32( +// CHECK-SAME: <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_f3213__Float32x4_t( +// CHECK-CXX-SAME: <4 x float> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x float> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_f32(float32x4_t v) { + return vreinterpretq_mf8_f32(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_f16( +// CHECK-SAME: <8 x half> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_f1613__Float16x8_t( +// CHECK-CXX-SAME: <8 x half> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x half> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_f16(float16x8_t v) { + return vreinterpretq_mf8_f16(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_s32( +// CHECK-SAME: <4 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_s3211__Int32x4_t( +// CHECK-CXX-SAME: <4 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x i32> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_s32(int32x4_t v) { + return vreinterpretq_mf8_s32(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_s64( +// CHECK-SAME: <2 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_s6411__Int64x2_t( +// CHECK-CXX-SAME: <2 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x i64> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_s64(int64x2_t v) { + return vreinterpretq_mf8_s64(v); +} +// CHECK-LABEL: define dso_local <16 x i8> @test_vreinterpretq_mf8_s16( +// CHECK-SAME: <8 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[V]] to <16 x i8> +// CHECK-NEXT: ret <16 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z26test_vreinterpretq_mf8_s1611__Int16x8_t( +// CHECK-CXX-SAME: <8 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i16> [[V]] to <16 x i8> +// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// +mfloat8x16_t test_vreinterpretq_mf8_s16(int16x8_t v) { + return vreinterpretq_mf8_s16(v); +} +// CHECK-LABEL: define dso_local <8 x i16> @test_vreinterpretq_s16_mf8( +// CHECK-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x i16> +// CHECK-NEXT: ret <8 x i16> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x i16> @_Z26test_vreinterpretq_s16_mf814__Mfloat8x16_t( +// CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <16 x i8> [[V]] to <8 x i16> +// CHECK-CXX-NEXT: ret <8 x i16> [[TMP0]] +// +int16x8_t test_vreinterpretq_s16_mf8(mfloat8x16_t v) { + return vreinterpretq_s16_mf8(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_u8_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x i8> @_Z24test_vreinterpret_u8_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[V]] +// +uint8x8_t test_vreinterpret_u8_mf8(mfloat8x8_t v) { + return vreinterpret_u8_mf8(v); +} +// CHECK-LABEL: define dso_local <2 x i32> @test_vreinterpret_u32_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <2 x i32> +// CHECK-NEXT: ret <2 x i32> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x i32> @_Z25test_vreinterpret_u32_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <2 x i32> +// CHECK-CXX-NEXT: ret <2 x i32> [[TMP0]] +// +uint32x2_t test_vreinterpret_u32_mf8(mfloat8x8_t v) { + return vreinterpret_u32_mf8(v); +} +// CHECK-LABEL: define dso_local <1 x i64> @test_vreinterpret_u64_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x i64> +// CHECK-NEXT: ret <1 x i64> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <1 x i64> @_Z25test_vreinterpret_u64_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x i64> +// CHECK-CXX-NEXT: ret <1 x i64> [[TMP0]] +// +uint64x1_t test_vreinterpret_u64_mf8(mfloat8x8_t v) { + return vreinterpret_u64_mf8(v); +} +// CHECK-LABEL: define dso_local <4 x i16> @test_vreinterpret_u16_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x i16> +// CHECK-NEXT: ret <4 x i16> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x i16> @_Z25test_vreinterpret_u16_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x i16> +// CHECK-CXX-NEXT: ret <4 x i16> [[TMP0]] +// +uint16x4_t test_vreinterpret_u16_mf8(mfloat8x8_t v) { + return vreinterpret_u16_mf8(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_s8_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local noundef <8 x i8> @_Z24test_vreinterpret_s8_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[V]] +// +int8x8_t test_vreinterpret_s8_mf8(mfloat8x8_t v) { + return vreinterpret_s8_mf8(v); +} +// CHECK-LABEL: define dso_local <1 x double> @test_vreinterpret_f64_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x double> +// CHECK-NEXT: ret <1 x double> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <1 x double> @_Z25test_vreinterpret_f64_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x double> +// CHECK-CXX-NEXT: ret <1 x double> [[TMP0]] +// +float64x1_t test_vreinterpret_f64_mf8(mfloat8x8_t v) { + return vreinterpret_f64_mf8(v); +} +// CHECK-LABEL: define dso_local <2 x float> @test_vreinterpret_f32_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <2 x float> +// CHECK-NEXT: ret <2 x float> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x float> @_Z25test_vreinterpret_f32_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <2 x float> +// CHECK-CXX-NEXT: ret <2 x float> [[TMP0]] +// +float32x2_t test_vreinterpret_f32_mf8(mfloat8x8_t v) { + return vreinterpret_f32_mf8(v); +} +// CHECK-LABEL: define dso_local <4 x half> @test_vreinterpret_f16_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x half> +// CHECK-NEXT: ret <4 x half> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x half> @_Z25test_vreinterpret_f16_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x half> +// CHECK-CXX-NEXT: ret <4 x half> [[TMP0]] +// +float16x4_t test_vreinterpret_f16_mf8(mfloat8x8_t v) { + return vreinterpret_f16_mf8(v); +} +// CHECK-LABEL: define dso_local <2 x i32> @test_vreinterpret_s32_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <2 x i32> +// CHECK-NEXT: ret <2 x i32> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <2 x i32> @_Z25test_vreinterpret_s32_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <2 x i32> +// CHECK-CXX-NEXT: ret <2 x i32> [[TMP0]] +// +int32x2_t test_vreinterpret_s32_mf8(mfloat8x8_t v) { + return vreinterpret_s32_mf8(v); +} +// CHECK-LABEL: define dso_local <1 x i64> @test_vreinterpret_s64_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x i64> +// CHECK-NEXT: ret <1 x i64> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <1 x i64> @_Z25test_vreinterpret_s64_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <1 x i64> +// CHECK-CXX-NEXT: ret <1 x i64> [[TMP0]] +// +int64x1_t test_vreinterpret_s64_mf8(mfloat8x8_t v) { + return vreinterpret_s64_mf8(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_p8( +// CHECK-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z24test_vreinterpret_mf8_p811__Poly8x8_t( +// CHECK-CXX-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[V]] +// +mfloat8x8_t test_vreinterpret_mf8_p8(poly8x8_t v) { + return vreinterpret_mf8_p8(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_p64( +// CHECK-SAME: <1 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_p6412__Poly64x1_t( +// CHECK-CXX-SAME: <1 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_p64(poly64x1_t v) { + return vreinterpret_mf8_p64(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_p16( +// CHECK-SAME: <4 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_p1612__Poly16x4_t( +// CHECK-CXX-SAME: <4 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_p16(poly16x4_t v) { + return vreinterpret_mf8_p16(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_u8( +// CHECK-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z24test_vreinterpret_mf8_u811__Uint8x8_t( +// CHECK-CXX-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[V]] +// +mfloat8x8_t test_vreinterpret_mf8_u8(uint8x8_t v) { + return vreinterpret_mf8_u8(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_u32( +// CHECK-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_u3212__Uint32x2_t( +// CHECK-CXX-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_u32(uint32x2_t v) { + return vreinterpret_mf8_u32(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_u64( +// CHECK-SAME: <1 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_u6412__Uint64x1_t( +// CHECK-CXX-SAME: <1 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_u64(uint64x1_t v) { + return vreinterpret_mf8_u64(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_u16( +// CHECK-SAME: <4 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_u1612__Uint16x4_t( +// CHECK-CXX-SAME: <4 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_u16(uint16x4_t v) { + return vreinterpret_mf8_u16(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_s8( +// CHECK-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: ret <8 x i8> [[V]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z24test_vreinterpret_mf8_s810__Int8x8_t( +// CHECK-CXX-SAME: <8 x i8> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: ret <8 x i8> [[V]] +// +mfloat8x8_t test_vreinterpret_mf8_s8(int8x8_t v) { + return vreinterpret_mf8_s8(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_f64( +// CHECK-SAME: <1 x double> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x double> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_f6413__Float64x1_t( +// CHECK-CXX-SAME: <1 x double> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <1 x double> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_f64(float64x1_t v) { + return vreinterpret_mf8_f64(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_f32( +// CHECK-SAME: <2 x float> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_f3213__Float32x2_t( +// CHECK-CXX-SAME: <2 x float> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x float> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_f32(float32x2_t v) { + return vreinterpret_mf8_f32(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_f16( +// CHECK-SAME: <4 x half> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_f1613__Float16x4_t( +// CHECK-CXX-SAME: <4 x half> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x half> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_f16(float16x4_t v) { + return vreinterpret_mf8_f16(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_s32( +// CHECK-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_s3211__Int32x2_t( +// CHECK-CXX-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <2 x i32> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_s32(int32x2_t v) { + return vreinterpret_mf8_s32(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_s64( +// CHECK-SAME: <1 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_s6411__Int64x1_t( +// CHECK-CXX-SAME: <1 x i64> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <1 x i64> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_s64(int64x1_t v) { + return vreinterpret_mf8_s64(v); +} +// CHECK-LABEL: define dso_local <8 x i8> @test_vreinterpret_mf8_s16( +// CHECK-SAME: <4 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V]] to <8 x i8> +// CHECK-NEXT: ret <8 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z25test_vreinterpret_mf8_s1611__Int16x4_t( +// CHECK-CXX-SAME: <4 x i16> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <4 x i16> [[V]] to <8 x i8> +// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// +mfloat8x8_t test_vreinterpret_mf8_s16(int16x4_t v) { + return vreinterpret_mf8_s16(v); +} +// CHECK-LABEL: define dso_local <4 x i16> @test_vreinterpret_s16_mf8( +// CHECK-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x i16> +// CHECK-NEXT: ret <4 x i16> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local noundef <4 x i16> @_Z25test_vreinterpret_s16_mf813__Mfloat8x8_t( +// CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <8 x i8> [[V]] to <4 x i16> +// CHECK-CXX-NEXT: ret <4 x i16> [[TMP0]] +// +int16x4_t test_vreinterpret_s16_mf8(mfloat8x8_t v) { + return vreinterpret_s16_mf8(v); +} diff --git a/clang/test/CodeGen/AArch64/pure-scalable-args.c b/clang/test/CodeGen/AArch64/pure-scalable-args.c index b03011e70b6a6..fecd370d09be3 100644 --- a/clang/test/CodeGen/AArch64/pure-scalable-args.c +++ b/clang/test/CodeGen/AArch64/pure-scalable-args.c @@ -67,7 +67,7 @@ void test_argpass_simple(PST *p) { void argpass_simple_callee(PST); argpass_simple_callee(*p); } -// CHECK-AAPCS: define dso_local void @test_argpass_simple(ptr nocapture noundef readonly %p) +// CHECK-AAPCS: define dso_local void @test_argpass_simple(ptr noundef readonly captures(none) %p) // CHECK-AAPCS-NEXT: entry: // CHECK-AAPCS-NEXT: %0 = load <2 x i8>, ptr %p, align 16 // CHECK-AAPCS-NEXT: %cast.scalable = tail call @llvm.vector.insert.nxv2i8.v2i8( poison, <2 x i8> %0, i64 0) @@ -292,7 +292,7 @@ PST test_return(PST *p) { return *p; } // CHECK-AAPCS: define dso_local <{ , , , , , }> @test_return(ptr -// CHECK-DARWIN: define void @test_return(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.PST) align 16 initializes((0, 96)) %agg.result, ptr nocapture noundef readonly %p) +// CHECK-DARWIN: define void @test_return(ptr dead_on_unwind noalias writable writeonly sret(%struct.PST) align 16 captures(none) initializes((0, 96)) %agg.result, ptr noundef readonly captures(none) %p) // Corner case of 1-element aggregate // p->x -> q0 @@ -300,7 +300,7 @@ SmallPST test_return_small_pst(SmallPST *p) { return *p; } // CHECK-AAPCS: define dso_local @test_return_small_pst(ptr -// CHECK-DARWIN: define i128 @test_return_small_pst(ptr nocapture noundef readonly %p) +// CHECK-DARWIN: define i128 @test_return_small_pst(ptr noundef readonly captures(none) %p) // Big PST, returned indirectly @@ -308,8 +308,8 @@ SmallPST test_return_small_pst(SmallPST *p) { BigPST test_return_big_pst(BigPST *p) { return *p; } -// CHECK-AAPCS: define dso_local void @test_return_big_pst(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.BigPST) align 16 initializes((0, 176)) %agg.result, ptr nocapture noundef readonly %p) -// CHECK-DARWIN: define void @test_return_big_pst(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.BigPST) align 16 initializes((0, 176)) %agg.result, ptr nocapture noundef readonly %p) +// CHECK-AAPCS: define dso_local void @test_return_big_pst(ptr dead_on_unwind noalias writable writeonly sret(%struct.BigPST) align 16 captures(none) initializes((0, 176)) %agg.result, ptr noundef readonly captures(none) %p) +// CHECK-DARWIN: define void @test_return_big_pst(ptr dead_on_unwind noalias writable writeonly sret(%struct.BigPST) align 16 captures(none) initializes((0, 176)) %agg.result, ptr noundef readonly captures(none) %p) // Variadic arguments are unnamed, PST passed indirectly. // (Passing SVE types to a variadic function currently unsupported by diff --git a/clang/test/CodeGen/AArch64/sme-attributes-member-function-pointer.cpp b/clang/test/CodeGen/AArch64/sme-attributes-member-function-pointer.cpp new file mode 100644 index 0000000000000..ee784c816a060 --- /dev/null +++ b/clang/test/CodeGen/AArch64/sme-attributes-member-function-pointer.cpp @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -x c++ -std=c++20 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK + +struct TestStruct; + +__arm_new("za", "zt0") void test(TestStruct& TS, + void (TestStruct::*streaming_member_ptr)() __arm_streaming, + void (TestStruct::*streaming_compat_member)() __arm_streaming_compatible, + void (TestStruct::*arm_in_member)() __arm_in("za", "zt0"), + void (TestStruct::*arm_inout_member)() __arm_inout("za", "zt0"), + void (TestStruct::*arm_preserves_member)() __arm_preserves("za", "zt0"), + void (TestStruct::*arm_agnostic_member)() __arm_agnostic("sme_za_state")) { + + // CHECK: call void %{{.*}} [[STREAMING_MEMBER_CALL_ATTRS:#.+]] + (TS.*streaming_member_ptr)(); + + // CHECK: call void %{{.*}} [[STREAMING_COMPAT_MEMBER_CALL_ATTRS:#.+]] + (TS.*streaming_compat_member)(); + + // CHECK: call void %{{.*}} [[ARM_IN_MEMBER_CALL_ATTRS:#.+]] + (TS.*arm_in_member)(); + + // CHECK: call void %{{.*}} [[ARM_INOUT_MEMBER_CALL_ATTRS:#.+]] + (TS.*arm_inout_member)(); + + // CHECK: call void %{{.*}} [[ARM_PRESERVES_MEMBER_CALL_ATTRS:#.+]] + (TS.*arm_preserves_member)(); + + // CHECK: call void %{{.*}} [[ARM_AGNOSTIC_MEMBER_CALL_ATTRS:#.+]] + (TS.*arm_agnostic_member)(); +} + +// CHECK: attributes [[STREAMING_MEMBER_CALL_ATTRS]] = { "aarch64_pstate_sm_enabled" } +// CHECK: attributes [[STREAMING_COMPAT_MEMBER_CALL_ATTRS]] = { "aarch64_pstate_sm_compatible" } +// CHECK: attributes [[ARM_IN_MEMBER_CALL_ATTRS]] = { "aarch64_in_za" "aarch64_in_zt0" } +// CHECK: attributes [[ARM_INOUT_MEMBER_CALL_ATTRS]] = { "aarch64_inout_za" "aarch64_inout_zt0" } +// CHECK: attributes [[ARM_PRESERVES_MEMBER_CALL_ATTRS]] = { "aarch64_preserves_za" "aarch64_preserves_zt0" } +// CHECK: attributes [[ARM_AGNOSTIC_MEMBER_CALL_ATTRS]] = { "aarch64_za_state_agnostic" } diff --git a/clang/test/CodeGen/AArch64/sme-intrinsics/aarch64-sme-attrs.cpp b/clang/test/CodeGen/AArch64/sme-intrinsics/aarch64-sme-attrs.cpp index 54762c8b41412..c734c6953e5d1 100644 --- a/clang/test/CodeGen/AArch64/sme-intrinsics/aarch64-sme-attrs.cpp +++ b/clang/test/CodeGen/AArch64/sme-intrinsics/aarch64-sme-attrs.cpp @@ -300,12 +300,12 @@ int test_variadic_template() __arm_inout("za") { preserves_za_decl); } -// CHECK: attributes #[[SM_ENABLED]] = { mustprogress noinline nounwind "aarch64_pstate_sm_enabled" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } +// CHECK: attributes #[[SM_ENABLED]] = { mustprogress noinline nounwind vscale_range(1,16) "aarch64_pstate_sm_enabled" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } // CHECK: attributes #[[NORMAL_DECL]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } // CHECK: attributes #[[SM_ENABLED_DECL]] = { "aarch64_pstate_sm_enabled" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } // CHECK: attributes #[[SM_COMPATIBLE]] = { mustprogress noinline nounwind "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } // CHECK: attributes #[[SM_COMPATIBLE_DECL]] = { "aarch64_pstate_sm_compatible" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } -// CHECK: attributes #[[SM_BODY]] = { mustprogress noinline nounwind "aarch64_pstate_sm_body" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } +// CHECK: attributes #[[SM_BODY]] = { mustprogress noinline nounwind vscale_range(1,16) "aarch64_pstate_sm_body" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } // CHECK: attributes #[[ZA_SHARED]] = { mustprogress noinline nounwind "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } // CHECK: attributes #[[ZA_SHARED_DECL]] = { "aarch64_inout_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } // CHECK: attributes #[[ZA_PRESERVED]] = { mustprogress noinline nounwind "aarch64_preserves_za" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+bf16,+sme" } diff --git a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_read.c b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_read.c index 508fad09ea715..0605f9eef036f 100644 --- a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_read.c +++ b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_read.c @@ -318,6 +318,41 @@ svuint64_t test_svread_hor_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice return SME_ACLE_FUNC(svread_hor_za64, _u64, _m)(zd, pg, 7, slice); } +// CHECK-C-LABEL: define dso_local @test_svread_hor_za8_mf8( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z23test_svread_hor_za8_mf8u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_hor_za8_mf8(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + return SME_ACLE_FUNC(svread_hor_za8, _mf8, _m)(zd, pg, 0, slice_base); +} + +// CHECK-C-LABEL: define dso_local @test_svread_hor_za8_mf8_1( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z25test_svread_hor_za8_mf8_1u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_hor_za8_mf8_1(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + uint32_t slice = slice_base + 15; + return SME_ACLE_FUNC(svread_hor_za8, _mf8, _m)(zd, pg, 0, slice); +} + // CHECK-C-LABEL: define dso_local @test_svread_hor_za16_f16( // CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: @@ -754,6 +789,38 @@ svuint64_t test_svread_hor_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slic return SME_ACLE_FUNC(svread_hor_za128, _u64, _m)(zd, pg, 15, slice_base); } +// CHECK-C-LABEL: define dso_local @test_svread_hor_za128_mf8( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z25test_svread_hor_za128_mf8u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_hor_za128_mf8(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + return SME_ACLE_FUNC(svread_hor_za128, _mf8, _m)(zd, pg, 0, slice_base); +} + +// CHECK-C-LABEL: define dso_local @test_svread_hor_za128_mf8_1( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z27test_svread_hor_za128_mf8_1u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.horiz.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_hor_za128_mf8_1(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + return SME_ACLE_FUNC(svread_hor_za128, _mf8, _m)(zd, pg, 15, slice_base); +} + // CHECK-C-LABEL: define dso_local @test_svread_hor_za128_f16( // CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: @@ -1202,6 +1269,41 @@ svuint64_t test_svread_ver_za64_u64_1(svuint64_t zd, svbool_t pg, uint32_t slice return SME_ACLE_FUNC(svread_ver_za64, _u64, _m)(zd, pg, 7, slice); } +// CHECK-C-LABEL: define dso_local @test_svread_ver_za8_mf8( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z23test_svread_ver_za8_mf8u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_ver_za8_mf8(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + return SME_ACLE_FUNC(svread_ver_za8, _mf8, _m)(zd, pg, 0, slice_base); +} + +// CHECK-C-LABEL: define dso_local @test_svread_ver_za8_mf8_1( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z25test_svread_ver_za8_mf8_1u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.read.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[ADD]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_ver_za8_mf8_1(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + uint32_t slice = slice_base + 15; + return SME_ACLE_FUNC(svread_ver_za8, _mf8, _m)(zd, pg, 0, slice); +} + // CHECK-C-LABEL: define dso_local @test_svread_ver_za16_f16( // CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: @@ -1638,6 +1740,38 @@ svuint64_t test_svread_ver_za128_u64_1(svuint64_t zd, svbool_t pg, uint32_t slic return SME_ACLE_FUNC(svread_ver_za128, _u64, _m)(zd, pg, 15, slice_base); } +// CHECK-C-LABEL: define dso_local @test_svread_ver_za128_mf8( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z25test_svread_ver_za128_mf8u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 0, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_ver_za128_mf8(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + return SME_ACLE_FUNC(svread_ver_za128, _mf8, _m)(zd, pg, 0, slice_base); +} + +// CHECK-C-LABEL: define dso_local @test_svread_ver_za128_mf8_1( +// CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z27test_svread_ver_za128_mf8_1u13__SVMfloat8_tu10__SVBool_tj( +// CHECK-CXX-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readq.vert.nxv16i8( [[ZD]], [[PG]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svread_ver_za128_mf8_1(svmfloat8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming __arm_in("za") { + return SME_ACLE_FUNC(svread_ver_za128, _mf8, _m)(zd, pg, 15, slice_base); +} + // CHECK-C-LABEL: define dso_local @test_svread_ver_za128_f16( // CHECK-C-SAME: [[ZD:%.*]], [[PG:%.*]], i32 noundef [[SLICE_BASE:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: diff --git a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_write.c b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_write.c index 86a691f14623f..99b96ee87553c 100644 --- a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_write.c +++ b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_write.c @@ -318,6 +318,41 @@ void test_svwrite_hor_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn SME_ACLE_FUNC(svwrite_hor_za64, _u64, _m)(7, slice, pg, zn); } +// CHECK-C-LABEL: define dso_local void @test_svwrite_hor_za8_mf8( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z24test_svwrite_hor_za8_mf8ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_hor_za8_mf8(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svwrite_hor_za8, _mf8, _m)(0, slice_base, pg, zn); +} + +// CHECK-C-LABEL: define dso_local void @test_svwrite_hor_za8_mf8_1( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z26test_svwrite_hor_za8_mf8_1ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.horiz.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_hor_za8_mf8_1(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + uint32_t slice = slice_base + 15; + SME_ACLE_FUNC(svwrite_hor_za8, _mf8, _m)(0, slice, pg, zn); +} + // CHECK-C-LABEL: define dso_local void @test_svwrite_hor_za16_f16( // CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: @@ -754,6 +789,39 @@ void test_svwrite_hor_za128_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t z SME_ACLE_FUNC(svwrite_hor_za128, _u64, _m)(15, slice_base, pg, zn); } + +// CHECK-C-LABEL: define dso_local void @test_svwrite_hor_za128_mf8( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z26test_svwrite_hor_za128_mf8ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_hor_za128_mf8(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svwrite_hor_za128, _mf8, _m)(0, slice_base, pg, zn); +} + +// CHECK-C-LABEL: define dso_local void @test_svwrite_hor_za128_mf8_1( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z28test_svwrite_hor_za128_mf8_1ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.horiz.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_hor_za128_mf8_1(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svwrite_hor_za128, _mf8, _m)(15, slice_base, pg, zn); +} + // CHECK-C-LABEL: define dso_local void @test_svwrite_hor_za128_f16( // CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: @@ -1202,6 +1270,41 @@ void test_svwrite_ver_za64_u64_1(uint32_t slice_base, svbool_t pg, svuint64_t zn SME_ACLE_FUNC(svwrite_ver_za64, _u64, _m)(7, slice, pg, zn); } +// CHECK-C-LABEL: define dso_local void @test_svwrite_ver_za8_mf8( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z24test_svwrite_ver_za8_mf8ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_ver_za8_mf8(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svwrite_ver_za8, _mf8, _m)(0, slice_base, pg, zn); +} + +// CHECK-C-LABEL: define dso_local void @test_svwrite_ver_za8_mf8_1( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z26test_svwrite_ver_za8_mf8_1ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.write.vert.nxv16i8(i32 0, i32 [[ADD]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_ver_za8_mf8_1(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + uint32_t slice = slice_base + 15; + SME_ACLE_FUNC(svwrite_ver_za8, _mf8, _m)(0, slice, pg, zn); +} + // CHECK-C-LABEL: define dso_local void @test_svwrite_ver_za16_f16( // CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: @@ -1656,6 +1759,38 @@ void test_svwrite_ver_za128_f16(uint32_t slice_base, svbool_t pg, svfloat16_t zn SME_ACLE_FUNC(svwrite_ver_za128, _f16, _m)(0, slice_base, pg, zn); } +// CHECK-C-LABEL: define dso_local void @test_svwrite_ver_za128_mf8( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z26test_svwrite_ver_za128_mf8ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 0, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_ver_za128_mf8(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svwrite_ver_za128, _mf8, _m)(0, slice_base, pg, zn); +} + +// CHECK-C-LABEL: define dso_local void @test_svwrite_ver_za128_mf8_1( +// CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-C-NEXT: entry: +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-C-NEXT: ret void +// +// CHECK-CXX-LABEL: define dso_local void @_Z28test_svwrite_ver_za128_mf8_1ju10__SVBool_tu13__SVMfloat8_t( +// CHECK-CXX-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-CXX-NEXT: entry: +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.writeq.vert.nxv16i8(i32 15, i32 [[SLICE_BASE]], [[PG]], [[ZN]]) +// CHECK-CXX-NEXT: ret void +// +void test_svwrite_ver_za128_mf8_1(uint32_t slice_base, svbool_t pg, svmfloat8_t zn) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svwrite_ver_za128, _mf8, _m)(15, slice_base, pg, zn); +} + // CHECK-C-LABEL: define dso_local void @test_svwrite_ver_za128_f16_1( // CHECK-C-SAME: i32 noundef [[SLICE_BASE:%.*]], [[PG:%.*]], [[ZN:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-C-NEXT: entry: diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt.c index 8de82abe05324..1ab02afbe0904 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt.c @@ -52,6 +52,19 @@ svuint16_t test_svluti2_lane_zt_u16(svuint8_t zn) __arm_streaming __arm_in("zt0" return svluti2_lane_zt_u16(0, zn, 15); } +// CHECK-LABEL: @test_svluti2_lane_zt_mf8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.luti2.lane.zt.nxv16i8(i32 0, [[ZN:%.*]], i32 15) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti2_lane_zt_mf8u11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.luti2.lane.zt.nxv16i8(i32 0, [[ZN:%.*]], i32 15) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svluti2_lane_zt_mf8(svuint8_t zn) __arm_streaming __arm_in("zt0") { + return svluti2_lane_zt_mf8(0, zn, 15); +} // CHECK-LABEL: @test_svluti2_lane_zt_s16( // CHECK-NEXT: entry: diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x2.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x2.c index 3b17c6d9edb19..e97075703b185 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x2.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x2.c @@ -37,6 +37,20 @@ svint8x2_t test_svluti2_lane_zt_s8(svuint8_t zn) __arm_streaming __arm_in("zt0") return svluti2_lane_zt_s8_x2(0, zn, 7); } +// CHECK-LABEL: @test_svluti2_lane_zt_mf8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.luti2.lane.zt.x2.nxv16i8(i32 0, [[ZN:%.*]], i32 7) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti2_lane_zt_mf8u11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.luti2.lane.zt.x2.nxv16i8(i32 0, [[ZN:%.*]], i32 7) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svluti2_lane_zt_mf8(svuint8_t zn) __arm_streaming __arm_in("zt0") { + return svluti2_lane_zt_mf8_x2(0, zn, 7); +} + // CHECK-LABEL: @test_svluti2_lane_zt_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.luti2.lane.zt.x2.nxv8i16(i32 0, [[ZN:%.*]], i32 7) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x4.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x4.c index 38059019737f8..0730812b1f06f 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x4.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti2_lane_zt_x4.c @@ -37,6 +37,20 @@ svint8x4_t test_svluti2_lane_zt_s8(svuint8_t zn) __arm_streaming __arm_in("zt0") return svluti2_lane_zt_s8_x4(0, zn, 3); } +// CHECK-LABEL: @test_svluti2_lane_zt_mf8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.luti2.lane.zt.x4.nxv16i8(i32 0, [[ZN:%.*]], i32 3) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti2_lane_zt_mf8u11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.luti2.lane.zt.x4.nxv16i8(i32 0, [[ZN:%.*]], i32 3) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svluti2_lane_zt_mf8(svuint8_t zn) __arm_streaming __arm_in("zt0") { + return svluti2_lane_zt_mf8_x4(0, zn, 3); +} + // CHECK-LABEL: @test_svluti2_lane_zt_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.luti2.lane.zt.x4.nxv8i16(i32 0, [[ZN:%.*]], i32 3) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt.c index 16e66d1c21222..b687b580b15a6 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt.c @@ -38,6 +38,20 @@ svint8_t test_svluti4_lane_zt_s8(svuint8_t zn) __arm_streaming __arm_in("zt0") { return svluti4_lane_zt_s8(0, zn, 7); } +// CHECK-LABEL: @test_svluti4_lane_zt_mf8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.luti4.lane.zt.nxv16i8(i32 0, [[ZN:%.*]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti4_lane_zt_mf8u11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.luti4.lane.zt.nxv16i8(i32 0, [[ZN:%.*]], i32 7) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svluti4_lane_zt_mf8(svuint8_t zn) __arm_streaming __arm_in("zt0") { + return svluti4_lane_zt_mf8(0, zn, 7); +} + // CHECK-LABEL: @test_svluti4_lane_zt_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.luti4.lane.zt.nxv8i16(i32 0, [[ZN:%.*]], i32 7) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt_x2.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt_x2.c index db615b3cd1c24..1a9e9d84c6359 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt_x2.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_luti4_lane_zt_x2.c @@ -37,6 +37,20 @@ svint8x2_t test_svluti4_lane_zt_s8(svuint8_t zn) __arm_streaming __arm_in("zt0") return svluti4_lane_zt_s8_x2(0, zn, 3); } +// CHECK-LABEL: @test_svluti4_lane_zt_mf8( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.luti4.lane.zt.x2.nxv16i8(i32 0, [[ZN:%.*]], i32 3) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z24test_svluti4_lane_zt_mf8u11__SVUint8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.luti4.lane.zt.x2.nxv16i8(i32 0, [[ZN:%.*]], i32 3) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svluti4_lane_zt_mf8(svuint8_t zn) __arm_streaming __arm_in("zt0") { + return svluti4_lane_zt_mf8_x2(0, zn, 3); +} + // CHECK-LABEL: @test_svluti4_lane_zt_u16( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.luti4.lane.zt.x2.nxv8i16(i32 0, [[ZN:%.*]], i32 3) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_read.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_read.c index b8cd1e1653ea9..c9d532d5fce45 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_read.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_read.c @@ -35,6 +35,20 @@ svint8x2_t test_svread_ver_za8_s8_vg2(uint32_t base) __arm_streaming __arm_in("z return svread_ver_za8_s8_vg2(0, base); } +// CHECK-LABEL: @test_svread_ver_za8_mf8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z27test_svread_ver_za8_mf8_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svread_ver_za8_mf8_vg2(uint32_t base) __arm_streaming __arm_in("za") { + return svread_ver_za8_mf8_vg2(0, base); +} + // CHECK-LABEL: @test_svread_hor_za8_u8_vg2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) @@ -63,6 +77,20 @@ svint8x2_t test_svread_hor_za8_s8_vg2(uint32_t base) __arm_streaming __arm_in("z return svread_hor_za8_s8_vg2(0, base); } +// CHECK-LABEL: @test_svread_hor_za8_mf8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z27test_svread_hor_za8_mf8_vg2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svread_hor_za8_mf8_vg2(uint32_t base) __arm_streaming __arm_in("za") { + return svread_hor_za8_mf8_vg2(0, base); +} + // CHECK-LABEL: @test_svread_hor_za8_u8_vg4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) @@ -91,6 +119,20 @@ svint8x4_t test_svread_hor_za8_s8_vg4(uint32_t base) __arm_streaming __arm_in("z return svread_hor_za8_s8_vg4(0, base); } +// CHECK-LABEL: @test_svread_hor_za8_mf8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z27test_svread_hor_za8_mf8_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svread_hor_za8_mf8_vg4(uint32_t base) __arm_streaming __arm_in("za") { + return svread_hor_za8_mf8_vg4(0, base); +} + // CHECK-LABEL: @test_svread_ver_za8_u8_vg4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) @@ -119,6 +161,20 @@ svint8x4_t test_svread_ver_za8_s8_vg4(uint32_t base) __arm_streaming __arm_in("z return svread_ver_za8_s8_vg4(0, base); } +// CHECK-LABEL: @test_svread_ver_za8_mf8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z27test_svread_ver_za8_mf8_vg4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svread_ver_za8_mf8_vg4(uint32_t base) __arm_streaming __arm_in("za") { + return svread_ver_za8_mf8_vg4(0, base); +} + // CHECK-LABEL: @test_svread_hor_za16_u16_vg2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]]) @@ -581,7 +637,6 @@ svfloat64x2_t test_svread_ver_za64_f64_vg2(uint32_t base) __arm_streaming __arm_ return svread_ver_za64_f64_vg2(7, base); } -// // CHECK-LABEL: @test_svread_ver_za64_s64_vg2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.ver.vg2.nxv2i64(i32 7, i32 [[BASE:%.*]]) @@ -708,6 +763,19 @@ svuint8x2_t test_svread_za8_u8_vg1x2(uint32_t base) __arm_streaming __arm_in("za return svread_za8_u8_vg1x2(base); } +// CHECK-LABEL: @test_svread_za8_mf8_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv16i8(i32 [[BASE:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z25test_svread_za8_mf8_vg1x2j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv16i8(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svread_za8_mf8_vg1x2(uint32_t base) __arm_streaming __arm_in("za") { + return svread_za8_mf8_vg1x2(base); +} // CHECK-LABEL: @test_svread_za16_s16_vg1x2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.read.vg1x2.nxv8i16(i32 [[BASE:%.*]]) @@ -876,6 +944,20 @@ svuint8x4_t test_svread_za8_u8_vg1x4(uint32_t base) __arm_streaming __arm_in("za return svread_za8_u8_vg1x4(base); } +// CHECK-LABEL: @test_svread_za8_mf8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv16i8(i32 [[BASE:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z25test_svread_za8_mf8_vg1x4j( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv16i8(i32 [[BASE:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svread_za8_mf8_vg1x4(uint32_t base) __arm_streaming __arm_in("za") { + return svread_za8_mf8_vg1x4(base); +} + // CHECK-LABEL: @test_svread_za16_s16_vg1x4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.read.vg1x4.nxv8i16(i32 [[BASE:%.*]]) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx2.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx2.c index 4047b2fbd1965..893cc7519a1d0 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx2.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx2.c @@ -45,6 +45,19 @@ svuint8x2_t test_svsel_u8_x2(svcount_t pn, svuint8x2_t zn, svuint8x2_t zm) __arm return SVE_ACLE_FUNC(svsel,_u8_x2)(pn, zn, zm); } +// CHECK-LABEL: @test_svsel_mf8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.sel.x2.nxv16i8(target("aarch64.svcount") [[PN:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svsel_mf8_x2u11__SVCount_t13svmfloat8x2_tS0_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.sel.x2.nxv16i8(target("aarch64.svcount") [[PN:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svsel_mf8_x2(svcount_t pn, svmfloat8x2_t zn, svmfloat8x2_t zm) __arm_streaming { + return SVE_ACLE_FUNC(svsel,_mf8_x2)(pn, zn, zm); +} // 16-bit SELs // CHECK-LABEL: @test_svsel_s16_x2( diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx4.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx4.c index 871d70943c9df..d4e77d998e3c2 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx4.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_selx4.c @@ -33,29 +33,43 @@ svint8x4_t test_svsel_s8_x4(svcount_t pn, svint8x4_t zn1, svint8x4_t zn2) __arm_ // CHECK-LABEL: @test_svsel_u8_x4( // CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv16i8(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] +// +// CPP-CHECK-LABEL: @_Z16test_svsel_u8_x4u11__SVCount_t11svuint8x4_tS0_S0_S0_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv16i8(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] +// +svuint8x4_t test_svsel_u8_x4(svcount_t pn, svuint8x4_t zn1, svuint8x4_t zn2, svuint8x4_t zn3, svuint8x4_t zn4) __arm_streaming { + return SVE_ACLE_FUNC(svsel,_u8_x4)(pn, zn1, zn2); +} + +// CHECK-LABEL: @test_svsel_mf8_x4( +// CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv16i8(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) // CHECK-NEXT: ret { , , , } [[TMP0]] // -// CPP-CHECK-LABEL: @_Z16test_svsel_u8_x4u11__SVCount_t11svuint8x4_tS0_S0_S0_( +// CPP-CHECK-LABEL: @_Z17test_svsel_mf8_x4u11__SVCount_t13svmfloat8x4_tS0_( // CPP-CHECK-NEXT: entry: // CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv16i8(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) // CPP-CHECK-NEXT: ret { , , , } [[TMP0]] // -svuint8x4_t test_svsel_u8_x4(svcount_t pn, svuint8x4_t zn1, svuint8x4_t zn2, svuint8x4_t zn3, svuint8x4_t zn4) __arm_streaming { - return SVE_ACLE_FUNC(svsel,_u8_x4)(pn, zn1, zn2); +svmfloat8x4_t test_svsel_mf8_x4(svcount_t pn, svmfloat8x4_t zn1, svmfloat8x4_t zn2) __arm_streaming { + return SVE_ACLE_FUNC(svsel,_mf8_x4)(pn, zn1, zn2); } // 16-bit SELs // CHECK-LABEL: @test_svsel_s16_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_s16_x4u11__SVCount_t11svint16x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svint16x4_t test_svsel_s16_x4(svcount_t pn, svint16x4_t zn1, svint16x4_t zn2, svint16x4_t zn3, svint16x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_s16_x4)(pn, zn1, zn2); @@ -63,13 +77,13 @@ svint16x4_t test_svsel_s16_x4(svcount_t pn, svint16x4_t zn1, svint16x4_t zn2, sv // CHECK-LABEL: @test_svsel_u16_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_u16_x4u11__SVCount_t12svuint16x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8i16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svuint16x4_t test_svsel_u16_x4(svcount_t pn, svuint16x4_t zn1, svuint16x4_t zn2, svuint16x4_t zn3, svuint16x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_u16_x4)(pn, zn1, zn2); @@ -77,13 +91,13 @@ svuint16x4_t test_svsel_u16_x4(svcount_t pn, svuint16x4_t zn1, svuint16x4_t zn2, // CHECK-LABEL: @test_svsel_f16_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8f16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8f16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_f16_x4u11__SVCount_t13svfloat16x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8f16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8f16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svfloat16x4_t test_svsel_f16_x4(svcount_t pn, svfloat16x4_t zn1, svfloat16x4_t zn2, svfloat16x4_t zn3, svfloat16x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_f16_x4)(pn, zn1, zn2); @@ -91,13 +105,13 @@ svfloat16x4_t test_svsel_f16_x4(svcount_t pn, svfloat16x4_t zn1, svfloat16x4_t z // CHECK-LABEL: @test_svsel_bf16_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8bf16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8bf16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z18test_svsel_bf16_x4u11__SVCount_t14svbfloat16x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8bf16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv8bf16(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svbfloat16x4_t test_svsel_bf16_x4(svcount_t pn, svbfloat16x4_t zn1, svbfloat16x4_t zn2, svbfloat16x4_t zn3, svbfloat16x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_bf16_x4)(pn, zn1, zn2); @@ -107,13 +121,13 @@ svbfloat16x4_t test_svsel_bf16_x4(svcount_t pn, svbfloat16x4_t zn1, svbfloat16x4 // CHECK-LABEL: @test_svsel_s32_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_s32_x4u11__SVCount_t11svint32x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svint32x4_t test_svsel_s32_x4(svcount_t pn, svint32x4_t zn1, svint32x4_t zn2, svint32x4_t zn3, svint32x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_s32_x4)(pn, zn1, zn2); @@ -121,13 +135,13 @@ svint32x4_t test_svsel_s32_x4(svcount_t pn, svint32x4_t zn1, svint32x4_t zn2, sv // CHECK-LABEL: @test_svsel_u32_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_u32_x4u11__SVCount_t12svuint32x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4i32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svuint32x4_t test_svsel_u32_x4(svcount_t pn, svuint32x4_t zn1, svuint32x4_t zn2, svuint32x4_t zn3, svuint32x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_u32_x4)(pn, zn1, zn2); @@ -135,13 +149,13 @@ svuint32x4_t test_svsel_u32_x4(svcount_t pn, svuint32x4_t zn1, svuint32x4_t zn2, // CHECK-LABEL: @test_svsel_f32_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4f32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4f32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_f32_x4u11__SVCount_t13svfloat32x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4f32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv4f32(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svfloat32x4_t test_svsel_f32_x4(svcount_t pn, svfloat32x4_t zn1, svfloat32x4_t zn2, svfloat32x4_t zn3, svfloat32x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_f32_x4)(pn, zn1, zn2); @@ -151,13 +165,13 @@ svfloat32x4_t test_svsel_f32_x4(svcount_t pn, svfloat32x4_t zn1, svfloat32x4_t z // CHECK-LABEL: @test_svsel_s64_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_s64_x4u11__SVCount_t11svint64x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svint64x4_t test_svsel_s64_x4(svcount_t pn, svint64x4_t zn1, svint64x4_t zn2, svint64x4_t zn3, svint64x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_s64_x4)(pn, zn1, zn2); @@ -165,13 +179,13 @@ svint64x4_t test_svsel_s64_x4(svcount_t pn, svint64x4_t zn1, svint64x4_t zn2, sv // CHECK-LABEL: @test_svsel_u64_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_u64_x4u11__SVCount_t12svuint64x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2i64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svuint64x4_t test_svsel_u64_x4(svcount_t pn, svuint64x4_t zn1, svuint64x4_t zn2, svuint64x4_t zn3, svuint64x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_u64_x4)(pn, zn1, zn2); @@ -179,13 +193,13 @@ svuint64x4_t test_svsel_u64_x4(svcount_t pn, svuint64x4_t zn1, svuint64x4_t zn2, // CHECK-LABEL: @test_svsel_f64_x4( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2f64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CHECK-NEXT: ret { , , , } [[TMP0]] +// CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2f64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP2]] // // CPP-CHECK-LABEL: @_Z17test_svsel_f64_x4u11__SVCount_t13svfloat64x4_tS0_S0_S0_( // CPP-CHECK-NEXT: entry: -// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2f64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) -// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call { , , , } @llvm.aarch64.sve.sel.x4.nxv2f64(target("aarch64.svcount") [[PN:%.*]], [[ZN1_COERCE0:%.*]], [[ZN1_COERCE1:%.*]], [[ZN1_COERCE2:%.*]], [[ZN1_COERCE3:%.*]], [[ZN2_COERCE0:%.*]], [[ZN2_COERCE1:%.*]], [[ZN2_COERCE2:%.*]], [[ZN2_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP2]] // svfloat64x4_t test_svsel_f64_x4(svcount_t pn, svfloat64x4_t zn1, svfloat64x4_t zn2, svfloat64x4_t zn3, svfloat64x4_t zn4) __arm_streaming { return SVE_ACLE_FUNC(svsel,_f64_x4)(pn, zn1, zn2); diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx2.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx2.c index 9a66ee5262082..ec3a2952b2ac6 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx2.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx2.c @@ -46,6 +46,20 @@ svuint8x2_t test_svuzp_u8_x2(svuint8x2_t zn) __arm_streaming { return SVE_ACLE_FUNC(svuzp,_u8_x2)(zn); } +// CHECK-LABEL: @test_svuzp_mf8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_mf8_x213svmfloat8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.uzp.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svuzp_mf8_x2(svmfloat8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_mf8_x2)(zn); +} + // 16-bit UZPs // CHECK-LABEL: @test_svuzp_s16_x2( @@ -222,6 +236,20 @@ svuint8x2_t test_svuzpq_u8_x2(svuint8x2_t zn) __arm_streaming { return SVE_ACLE_FUNC(svuzpq,_u8_x2)(zn); } +// CHECK-LABEL: @test_svuzpq_mf8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_mf8_x213svmfloat8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svuzpq_mf8_x2(svmfloat8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_mf8_x2)(zn); +} + // CHECK-LABEL: @test_svuzpq_s16_x2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.uzpq.x2.nxv8i16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx4.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx4.c index 131928615edcd..aeac2ae78f6e6 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx4.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_uzpx4.c @@ -46,6 +46,20 @@ svuint8x4_t test_svuzp_u8_x4(svuint8x4_t zn) __arm_streaming { return SVE_ACLE_FUNC(svuzp,_u8_x4)(zn); } +// CHECK-LABEL: @test_svuzp_mf8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svuzp_mf8_x413svmfloat8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzp.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svuzp_mf8_x4(svmfloat8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzp,_mf8_x4)(zn); +} + // 16-bit UZPs // CHECK-LABEL: @test_svuzp_s16_x4( @@ -222,6 +236,20 @@ svuint8x4_t test_svuzpq_u8_x4(svuint8x4_t zn) __arm_streaming { return SVE_ACLE_FUNC(svuzpq,_u8_x4)(zn); } +// CHECK-LABEL: @test_svuzpq_mf8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z18test_svuzpq_mf8_x413svmfloat8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svuzpq_mf8_x4(svmfloat8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svuzpq,_mf8_x4)(zn); +} + // CHECK-LABEL: @test_svuzpq_s16_x4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.uzpq.x4.nxv8i16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx2.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx2.c index 787b7d0b3ea1a..735b3697f150b 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx2.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx2.c @@ -45,6 +45,20 @@ svuint8x2_t test_svzip_u8_x2(svuint8x2_t zn) __arm_streaming { return SVE_ACLE_FUNC(svzip,_u8_x2)(zn); } +// CHECK-LABEL: @test_svzip_mf8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_mf8_x213svmfloat8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.zip.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svzip_mf8_x2(svmfloat8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_mf8_x2)(zn); +} + // 16-bit ZIPs // CHECK-LABEL: @test_svzip_s16_x2( @@ -221,6 +235,20 @@ svuint8x2_t test_svzipq_u8_x2(svuint8x2_t zn) __arm_streaming { return SVE_ACLE_FUNC(svzipq,_u8_x2)(zn); } +// CHECK-LABEL: @test_svzipq_mf8_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_mf8_x213svmfloat8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svzipq_mf8_x2(svmfloat8x2_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_mf8_x2)(zn); +} + // CHECK-LABEL: @test_svzipq_s16_x2( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.zipq.x2.nxv8i16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx4.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx4.c index 9bea471bc9837..341ae290e9b0e 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx4.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_vector_zipx4.c @@ -45,6 +45,20 @@ svuint8x4_t test_svzip_u8_x4(svuint8x4_t zn) __arm_streaming { return SVE_ACLE_FUNC(svzip,_u8_x4)(zn); } +// CHECK-LABEL: @test_svzip_mf8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svzip_mf8_x413svmfloat8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.zip.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svzip_mf8_x4(svmfloat8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzip,_mf8_x4)(zn); +} + // 16-bit ZIPs // CHECK-LABEL: @test_svzip_s16_x4( @@ -221,6 +235,20 @@ svuint8x4_t test_svzipq_u8_x4(svuint8x4_t zn) __arm_streaming { return SVE_ACLE_FUNC(svzipq,_u8_x4)(zn); } +// CHECK-LABEL: @test_svzipq_mf8_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z18test_svzipq_mf8_x413svmfloat8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv16i8( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svzipq_mf8_x4(svmfloat8x4_t zn) __arm_streaming { + return SVE_ACLE_FUNC(svzipq,_mf8_x4)(zn); +} + // CHECK-LABEL: @test_svzipq_s16_x4( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sve.zipq.x4.nxv8i16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_write.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_write.c index 1bdca4a12bcbd..7d0fbc9479a87 100644 --- a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_write.c +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_write.c @@ -44,6 +44,20 @@ void test_svwrite_ver_za8_s8_vg2(uint32_t base, svint8x2_t val) __arm_streaming SVE_ACLE_FUNC(svwrite_ver_za8,_s8,_vg2,)(0, base, val); } +// CHECK-LABEL: @test_svwrite_ver_za8_mf8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z28test_svwrite_ver_za8_mf8_vg2j13svmfloat8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za8_mf8_vg2(uint32_t base, svmfloat8x2_t val) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svwrite_ver_za8,_mf8,_vg2,)(0, base, val); +} + // CHECK-LABEL: @test_svwrite_hor_za8_u8_vg2( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) @@ -72,6 +86,20 @@ void test_svwrite_hor_za8_s8_vg2(uint32_t base, svint8x2_t val) __arm_streaming SVE_ACLE_FUNC(svwrite_hor_za8,_s8,_vg2,)(0, base, val); } +// CHECK-LABEL: @test_svwrite_hor_za8_mf8_vg2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z28test_svwrite_hor_za8_mf8_vg2j13svmfloat8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za8_mf8_vg2(uint32_t base, svmfloat8x2_t val) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svwrite_hor_za8,_mf8,_vg2,)(0, base, val); +} + // CHECK-LABEL: @test_svwrite_hor_za8_u8_vg4( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) @@ -100,6 +128,20 @@ void test_svwrite_hor_za8_s8_vg4(uint32_t base, svint8x4_t val) __arm_streaming SVE_ACLE_FUNC(svwrite_hor_za8,_s8,_vg4,)(0, base, val); } +// CHECK-LABEL: @test_svwrite_hor_za8_mf8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z28test_svwrite_hor_za8_mf8_vg4j13svmfloat8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_hor_za8_mf8_vg4(uint32_t base, svmfloat8x4_t val) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svwrite_hor_za8,_mf8,_vg4,)(0, base, val); +} + // CHECK-LABEL: @test_svwrite_ver_za8_u8_vg4( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) @@ -128,6 +170,20 @@ void test_svwrite_ver_za8_s8_vg4(uint32_t base, svint8x4_t val) __arm_streaming SVE_ACLE_FUNC(svwrite_ver_za8,_s8,_vg4,)(0, base, val); } +// CHECK-LABEL: @test_svwrite_ver_za8_mf8_vg4( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z28test_svwrite_ver_za8_mf8_vg4j13svmfloat8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.ver.vg4.nxv16i8(i32 0, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_ver_za8_mf8_vg4(uint32_t base, svmfloat8x4_t val) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svwrite_ver_za8,_mf8,_vg4,)(0, base, val); +} + // CHECK-LABEL: @test_svwrite_hor_za16_u16_vg2( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.aarch64.sme.write.hor.vg2.nxv8i16(i32 1, i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) @@ -716,6 +772,20 @@ void test_svwrite_za8_u8_vg1x2(uint32_t base, svuint8x2_t val) __arm_streaming _ SVE_ACLE_FUNC(svwrite_za8,_u8,_vg1x2,)(base, val); } +// CHECK-LABEL: @test_svwrite_za8_mf8_vg1x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv16i8(i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z26test_svwrite_za8_mf8_vg1x2j13svmfloat8x2_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv16i8(i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za8_mf8_vg1x2(uint32_t base, svmfloat8x2_t val) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svwrite_za8,_mf8,_vg1x2,)(base, val); +} + // CHECK-LABEL: @test_svwrite_za16_s16_vg1x2( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x2.nxv8i16(i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]]) @@ -856,6 +926,20 @@ void test_svwrite_za64_s64_vg1x2(uint32_t base, svint64x2_t val) __arm_streaming SVE_ACLE_FUNC(svwrite_za64,_s64,_vg1x2,)(base, val); } +// CHECK-LABEL: @test_svwrite_za8_mf8_vg1x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv16i8(i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: @_Z26test_svwrite_za8_mf8_vg1x4j13svmfloat8x4_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv16i8(i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret void +// +void test_svwrite_za8_mf8_vg1x4(uint32_t base, svmfloat8x4_t val) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svwrite_za8,_mf8,_vg1x4,)(base, val); +} + // CHECK-LABEL: @test_svwrite_za8_s8_vg1x4( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.aarch64.sme.write.vg1x4.nxv16i8(i32 [[BASE:%.*]], [[VAL_COERCE0:%.*]], [[VAL_COERCE1:%.*]], [[VAL_COERCE2:%.*]], [[VAL_COERCE3:%.*]]) diff --git a/clang/test/CodeGen/AArch64/sme2p1-intrinsics/acle_sme2p1_movaz.c b/clang/test/CodeGen/AArch64/sme2p1-intrinsics/acle_sme2p1_movaz.c index 7fa2249827c4e..98324e78b16bc 100644 --- a/clang/test/CodeGen/AArch64/sme2p1-intrinsics/acle_sme2p1_movaz.c +++ b/clang/test/CodeGen/AArch64/sme2p1-intrinsics/acle_sme2p1_movaz.c @@ -42,6 +42,23 @@ svuint8x2_t test_svreadz_hor_za8_u8_x2(uint32_t slice) __arm_streaming __arm_ino return svreadz_hor_za8_u8_vg2(0, slice); } +// CHECK-LABEL: define dso_local { , } @test_svreadz_hor_za8_mf8_x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.readz.horiz.x2.nxv16i8(i32 0, i32 [[SLICE]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local { , } @_Z27test_svreadz_hor_za8_mf8_x2j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.readz.horiz.x2.nxv16i8(i32 0, i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svreadz_hor_za8_mf8_x2(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_hor_za8_mf8_vg2(0, slice); +} + // CHECK-LABEL: define dso_local { , } @test_svreadz_hor_za16_s16_x2( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -252,6 +269,23 @@ svuint8x2_t test_svreadz_ver_za8_u8_x2(uint32_t slice) __arm_streaming __arm_ino return svreadz_ver_za8_u8_vg2(0, slice); } +// CHECK-LABEL: define dso_local { , } @test_svreadz_ver_za8_mf8_x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.readz.vert.x2.nxv16i8(i32 0, i32 [[SLICE]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local { , } @_Z27test_svreadz_ver_za8_mf8_x2j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.readz.vert.x2.nxv16i8(i32 0, i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svreadz_ver_za8_mf8_x2(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_ver_za8_mf8_vg2(0, slice); +} + // CHECK-LABEL: define dso_local { , } @test_svreadz_ver_za16_s16_x2( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -460,6 +494,23 @@ svuint8x4_t test_svreadz_hor_za8_u8_x4(uint32_t slice) __arm_streaming __arm_ino return svreadz_hor_za8_u8_vg4(0, slice); } +// CHECK-LABEL: define dso_local { , , , } @test_svreadz_hor_za8_mf8_x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.readz.horiz.x4.nxv16i8(i32 0, i32 [[SLICE]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local { , , , } @_Z27test_svreadz_hor_za8_mf8_x4j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.readz.horiz.x4.nxv16i8(i32 0, i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svreadz_hor_za8_mf8_x4(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_hor_za8_mf8_vg4(0, slice); +} + // CHECK-LABEL: define dso_local { , , , } @test_svreadz_hor_za16_s16_x4( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -667,6 +718,23 @@ svuint8x4_t test_svreadz_ver_za8_u8_x4(uint32_t slice) __arm_streaming __arm_ino return svreadz_ver_za8_u8_vg4(0, slice); } +// CHECK-LABEL: define dso_local { , , , } @test_svreadz_ver_za8_mf8_x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.readz.vert.x4.nxv16i8(i32 0, i32 [[SLICE]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local { , , , } @_Z27test_svreadz_ver_za8_mf8_x4j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.readz.vert.x4.nxv16i8(i32 0, i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svreadz_ver_za8_mf8_x4(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_ver_za8_mf8_vg4(0, slice); +} + // CHECK-LABEL: define dso_local { , , , } @test_svreadz_ver_za16_s16_x4( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -872,6 +940,23 @@ svuint8_t test_svreadz_hor_za8_u8(uint32_t slice) __arm_streaming __arm_inout("z return svreadz_hor_za8_u8(0, slice); } +// CHECK-LABEL: define dso_local @test_svreadz_hor_za8_mf8( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readz.horiz.nxv16i8(i32 0, i32 [[SLICE]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local @_Z24test_svreadz_hor_za8_mf8j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readz.horiz.nxv16i8(i32 0, i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svreadz_hor_za8_mf8(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_hor_za8_mf8(0, slice); +} + // CHECK-LABEL: define dso_local @test_svreadz_hor_za16_s16( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -1078,6 +1163,23 @@ svuint8_t test_svreadz_hor_za128_u8(uint32_t slice) __arm_streaming __arm_inout( return svreadz_hor_za128_u8(1, slice); } +// CHECK-LABEL: define dso_local @test_svreadz_hor_za128_mf8( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readz.q.horiz.nxv16i8(i32 0, i32 [[SLICE]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local @_Z26test_svreadz_hor_za128_mf8j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sme.readz.q.horiz.nxv16i8(i32 0, i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svreadz_hor_za128_mf8(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_hor_za128_mf8(0, slice); +} + // CHECK-LABEL: define dso_local @test_svreadz_hor_za128_s16( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -1287,6 +1389,23 @@ svuint8x2_t test_svreadz_za8_u8_x2(uint32_t slice) __arm_streaming __arm_inout(" return svreadz_za8_u8_vg1x2(slice); } +// CHECK-LABEL: define dso_local { , } @test_svreadz_za8_mf8_x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.readz.x2.nxv16i8(i32 [[SLICE]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local { , } @_Z23test_svreadz_za8_mf8_x2j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sme.readz.x2.nxv16i8(i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svmfloat8x2_t test_svreadz_za8_mf8_x2(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_za8_mf8_vg1x2(slice); +} + // CHECK-LABEL: define dso_local { , } @test_svreadz_za16_s16_x2( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: @@ -1495,6 +1614,23 @@ svuint8x4_t test_svreadz_za8_u8_x4(uint32_t slice) __arm_streaming __arm_inout(" return svreadz_za8_u8_vg1x4(slice); } +// CHECK-LABEL: define dso_local { , , , } @test_svreadz_za8_mf8_x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.readz.x4.nxv16i8(i32 [[SLICE]]) +// CHECK-NEXT: ret { , , , } [[TMP0]] +// +// CPP-CHECK-LABEL: define dso_local { , , , } @_Z23test_svreadz_za8_mf8_x4j( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , , , } @llvm.aarch64.sme.readz.x4.nxv16i8(i32 [[SLICE]]) +// CPP-CHECK-NEXT: ret { , , , } [[TMP0]] +// +svmfloat8x4_t test_svreadz_za8_mf8_x4(uint32_t slice) __arm_streaming __arm_inout("za") +{ + return svreadz_za8_mf8_vg1x4(slice); +} + // CHECK-LABEL: define dso_local { , , , } @test_svreadz_za16_s16_x4( // CHECK-SAME: i32 noundef [[SLICE:%.*]]) #[[ATTR0]] { // CHECK-NEXT: entry: diff --git a/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c b/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c index 28d69d52c9ae7..bbed683ac1fd7 100644 --- a/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c +++ b/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c @@ -59,7 +59,7 @@ typedef int8_t vec_int8 __attribute__((vector_size(N / 8))); // CHECK128-NEXT: ret <16 x i8> [[CASTFIXEDSVE]] // CHECK-LABEL: define{{.*}} void @f2( -// CHECK-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret(<[[#div(VBITS,8)]] x i8>) align 16 initializes((0, [[#div(VBITS,8)]])) %agg.result, ptr nocapture noundef readonly %0) +// CHECK-SAME: ptr dead_on_unwind noalias writable writeonly sret(<[[#div(VBITS,8)]] x i8>) align 16 captures(none) initializes((0, [[#div(VBITS,8)]])) %agg.result, ptr noundef readonly captures(none) %0) // CHECK-NEXT: entry: // CHECK-NEXT: [[X:%.*]] = load <[[#div(VBITS,8)]] x i8>, ptr [[TMP0:%.*]], align 16, [[TBAA6:!tbaa !.*]] // CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) diff --git a/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_revd.c b/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_revd.c index b1121eb46e2a2..d947cf78660ff 100644 --- a/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_revd.c +++ b/clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_revd.c @@ -397,6 +397,20 @@ svuint64_t test_svrevd_u64_x(svbool_t pg, svuint64_t op) MODE_ATTR { } +// CHECK-LABEL: @test_svrevd_mf8_z( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.revd.nxv16i8( zeroinitializer, [[PG:%.*]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_mf8_zu10__SVBool_tu13__SVMfloat8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.revd.nxv16i8( zeroinitializer, [[PG:%.*]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svrevd_mf8_z(svbool_t pg, svmfloat8_t op) MODE_ATTR { + return SVE_ACLE_FUNC(svrevd, _mf8, _z, )(pg, op); +} + // CHECK-LABEL: @test_svrevd_bf16_z( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) @@ -461,6 +475,20 @@ svfloat64_t test_svrevd_f64_z(svbool_t pg, svfloat64_t op) MODE_ATTR { return SVE_ACLE_FUNC(svrevd, _f64, _z, )(pg, op); } +// CHECK-LABEL: @test_svrevd_mf8_m( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.revd.nxv16i8( [[INACTIVE:%.*]], [[PG:%.*]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_mf8_mu13__SVMfloat8_tu10__SVBool_tS_( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.revd.nxv16i8( [[INACTIVE:%.*]], [[PG:%.*]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svrevd_mf8_m(svmfloat8_t inactive, svbool_t pg, svmfloat8_t op) MODE_ATTR { + return SVE_ACLE_FUNC(svrevd, _mf8, _m, )(inactive, pg, op); +} + // CHECK-LABEL: @test_svrevd_bf16_m( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) @@ -525,6 +553,20 @@ svfloat64_t test_svrevd_f64_m(svfloat64_t inactive, svbool_t pg, svfloat64_t op) return SVE_ACLE_FUNC(svrevd, _f64, _m, )(inactive, pg, op); } +// CHECK-LABEL: @test_svrevd_mf8_x( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.revd.nxv16i8( undef, [[PG:%.*]], [[OP:%.*]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_svrevd_mf8_xu10__SVBool_tu13__SVMfloat8_t( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.revd.nxv16i8( undef, [[PG:%.*]], [[OP:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svrevd_mf8_x(svbool_t pg, svmfloat8_t op) MODE_ATTR { + return SVE_ACLE_FUNC(svrevd, _mf8, _x, )(pg, op); +} + // CHECK-LABEL: @test_svrevd_bf16_x( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.convert.from.svbool.nxv8i1( [[PG:%.*]]) diff --git a/clang/test/CodeGen/PowerPC/aix-vaargs.c b/clang/test/CodeGen/PowerPC/aix-vaargs.c index 724ba6560cdb9..8716a9e4698c4 100644 --- a/clang/test/CodeGen/PowerPC/aix-vaargs.c +++ b/clang/test/CodeGen/PowerPC/aix-vaargs.c @@ -68,8 +68,8 @@ void testva (int n, ...) { // CHECK: declare void @llvm.va_start.p0(ptr) -// AIX32: declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg) -// AIX64: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) +// AIX32: declare void @llvm.memcpy.p0.p0.i32(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i32, i1 immarg) +// AIX64: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) // CHECK: declare void @llvm.va_copy.p0(ptr, ptr) // CHECK: declare void @llvm.va_end.p0(ptr) diff --git a/clang/test/CodeGen/SystemZ/systemz-inline-asm.c b/clang/test/CodeGen/SystemZ/systemz-inline-asm.c index 2a9d6a5f87454..9e62b8e107900 100644 --- a/clang/test/CodeGen/SystemZ/systemz-inline-asm.c +++ b/clang/test/CodeGen/SystemZ/systemz-inline-asm.c @@ -123,7 +123,7 @@ double test_f64(double f, double g) { long double test_f128(long double f, long double g) { asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g)); return f; -// CHECK: define{{.*}} void @test_f128(ptr dead_on_unwind noalias nocapture writable writeonly sret(fp128) align 8 initializes((0, 16)) [[DEST:%.*]], ptr nocapture noundef readonly %0, ptr nocapture noundef readonly %1) +// CHECK: define{{.*}} void @test_f128(ptr dead_on_unwind noalias writable writeonly sret(fp128) align 8 captures(none) initializes((0, 16)) [[DEST:%.*]], ptr noundef readonly captures(none) %0, ptr noundef readonly captures(none) %1) // CHECK: %f = load fp128, ptr %0 // CHECK: %g = load fp128, ptr %1 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g) diff --git a/clang/test/CodeGen/X86/avx-cxx-record.cpp b/clang/test/CodeGen/X86/avx-cxx-record.cpp new file mode 100644 index 0000000000000..bcd9c361fda90 --- /dev/null +++ b/clang/test/CodeGen/X86/avx-cxx-record.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -O2 -target-cpu x86-64-v3 -o - | FileCheck %s + +using UInt64x2 = unsigned long long __attribute__((__vector_size__(16), may_alias)); + +template +struct XMM1 { + UInt64x2 x; +}; + +struct XMM2 : XMM1<0>, XMM1<1> { +}; + +// CHECK: define{{.*}} @_Z3foov({{.*}} [[ARG:%.*]]){{.*}} +// CHECK: entry: +// CHECK-NEXT: store {{.*}}, ptr [[ARG]]{{.*}} +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr {{.*}}, ptr [[ARG]]{{.*}} +// CHECK-NEXT: store {{.*}}, ptr [[TMP1]]{{.*}} +XMM2 foo() { + XMM2 result; + ((XMM1<0>*)&result)->x = UInt64x2{1, 2}; + ((XMM1<1>*)&result)->x = UInt64x2{3, 4}; + return result; +} diff --git a/clang/test/CodeGen/X86/avx10_2_512convert-builtins.c b/clang/test/CodeGen/X86/avx10_2_512convert-builtins.c index 22503c640a727..dcf7bbc005a7c 100644 --- a/clang/test/CodeGen/X86/avx10_2_512convert-builtins.c +++ b/clang/test/CodeGen/X86/avx10_2_512convert-builtins.c @@ -201,22 +201,22 @@ __m512i test_mm512_maskz_cvts2ph_hf8(__mmask64 __U, __m512h __A, __m512h __B) { return _mm512_maskz_cvts2ph_hf8(__U, __A, __B); } -__m512h test_mm512_cvthf8(__m256i __A) { - // CHECK-LABEL: @test_mm512_cvthf8( +__m512h test_mm512_cvthf8_ph(__m256i __A) { + // CHECK-LABEL: @test_mm512_cvthf8_ph( // CHECK: call <32 x half> @llvm.x86.avx10.mask.vcvthf82ph512( - return _mm512_cvthf8(__A); + return _mm512_cvthf8_ph(__A); } -__m512h test_mm512_mask_cvthf8(__m512h __A, __mmask32 __B, __m256i __C) { - // CHECK-LABEL: @test_mm512_mask_cvthf8( +__m512h test_mm512_mask_cvthf8_ph(__m512h __A, __mmask32 __B, __m256i __C) { + // CHECK-LABEL: @test_mm512_mask_cvthf8_ph( // CHECK: call <32 x half> @llvm.x86.avx10.mask.vcvthf82ph512( - return _mm512_mask_cvthf8(__A, __B, __C); + return _mm512_mask_cvthf8_ph(__A, __B, __C); } -__m512h test_mm512_maskz_cvthf8(__mmask32 __A, __m256i __B) { - // CHECK-LABEL: @test_mm512_maskz_cvthf8( +__m512h test_mm512_maskz_cvthf8_ph(__mmask32 __A, __m256i __B) { + // CHECK-LABEL: @test_mm512_maskz_cvthf8_ph( // CHECK: call <32 x half> @llvm.x86.avx10.mask.vcvthf82ph512( - return _mm512_maskz_cvthf8(__A, __B); + return _mm512_maskz_cvthf8_ph(__A, __B); } __m256i test_mm512_cvtph_bf8(__m512h __A) { diff --git a/clang/test/CodeGen/X86/avx10_2convert-builtins.c b/clang/test/CodeGen/X86/avx10_2convert-builtins.c index efd9a31c40875..87fc6ffd7bc17 100644 --- a/clang/test/CodeGen/X86/avx10_2convert-builtins.c +++ b/clang/test/CodeGen/X86/avx10_2convert-builtins.c @@ -231,7 +231,7 @@ __m256i test_mm256_cvt2ph_bf8(__m256h __A, __m256h __B) { return _mm256_cvt2ph_bf8(__A, __B); } -__m256i test_mm256_mask_cvt2ph_bf8(__m256i __W, __mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_mask_cvt2ph_bf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_mask_cvt2ph_bf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2bf8256( // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} @@ -239,7 +239,7 @@ __m256i test_mm256_mask_cvt2ph_bf8(__m256i __W, __mmask16 __U, __m256h __A, __m2 return _mm256_mask_cvt2ph_bf8(__W, __U, __A, __B); } -__m256i test_mm256_maskz_cvt2ph_bf8(__mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_maskz_cvt2ph_bf8(__mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_maskz_cvt2ph_bf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2bf8256( // CHECK: zeroinitializer @@ -275,7 +275,7 @@ __m256i test_mm256_cvts2ph_bf8(__m256h __A, __m256h __B) { return _mm256_cvts2ph_bf8(__A, __B); } -__m256i test_mm256_mask_cvts2ph_bf8(__m256i __W, __mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_mask_cvts2ph_bf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_mask_cvts2ph_bf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2bf8s256( // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} @@ -283,7 +283,7 @@ __m256i test_mm256_mask_cvts2ph_bf8(__m256i __W, __mmask16 __U, __m256h __A, __m return _mm256_mask_cvts2ph_bf8(__W, __U, __A, __B); } -__m256i test_mm256_maskz_cvts2ph_bf8(__mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_maskz_cvts2ph_bf8(__mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_maskz_cvts2ph_bf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2bf8s256( // CHECK: zeroinitializer @@ -319,7 +319,7 @@ __m256i test_mm256_cvt2ph_hf8(__m256h __A, __m256h __B) { return _mm256_cvt2ph_hf8(__A, __B); } -__m256i test_mm256_mask_cvt2ph_hf8(__m256i __W, __mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_mask_cvt2ph_hf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_mask_cvt2ph_hf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2hf8256( // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} @@ -327,7 +327,7 @@ __m256i test_mm256_mask_cvt2ph_hf8(__m256i __W, __mmask16 __U, __m256h __A, __m2 return _mm256_mask_cvt2ph_hf8(__W, __U, __A, __B); } -__m256i test_mm256_maskz_cvt2ph_hf8(__mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_maskz_cvt2ph_hf8(__mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_maskz_cvt2ph_hf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2hf8256( // CHECK: zeroinitializer @@ -363,7 +363,7 @@ __m256i test_mm256_cvts2ph_hf8(__m256h __A, __m256h __B) { return _mm256_cvts2ph_hf8(__A, __B); } -__m256i test_mm256_mask_cvts2ph_hf8(__m256i __W, __mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_mask_cvts2ph_hf8(__m256i __W, __mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_mask_cvts2ph_hf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2hf8s256( // CHECK: select <32 x i1> %{{.*}}, <32 x i8> %{{.*}}, <32 x i8> %{{.*}} @@ -371,7 +371,7 @@ __m256i test_mm256_mask_cvts2ph_hf8(__m256i __W, __mmask16 __U, __m256h __A, __m return _mm256_mask_cvts2ph_hf8(__W, __U, __A, __B); } -__m256i test_mm256_maskz_cvts2ph_hf8(__mmask16 __U, __m256h __A, __m256h __B) { +__m256i test_mm256_maskz_cvts2ph_hf8(__mmask32 __U, __m256h __A, __m256h __B) { // CHECK-LABEL: @test_mm256_maskz_cvts2ph_hf8( // CHECK: call <32 x i8> @llvm.x86.avx10.vcvt2ph2hf8s256( // CHECK: zeroinitializer @@ -379,40 +379,40 @@ __m256i test_mm256_maskz_cvts2ph_hf8(__mmask16 __U, __m256h __A, __m256h __B) { return _mm256_maskz_cvts2ph_hf8(__U, __A, __B); } -__m128h test_mm_cvthf8(__m128i __A) { - // CHECK-LABEL: @test_mm_cvthf8( +__m128h test_mm_cvthf8_ph(__m128i __A) { + // CHECK-LABEL: @test_mm_cvthf8_ph( // CHECK: call <8 x half> @llvm.x86.avx10.mask.vcvthf82ph128( - return _mm_cvthf8(__A); + return _mm_cvthf8_ph(__A); } -__m128h test_mm_mask_cvthf8(__m128h __A, __mmask8 __B, __m128i __C) { - // CHECK-LABEL: @test_mm_mask_cvthf8( +__m128h test_mm_mask_cvthf8_ph(__m128h __A, __mmask8 __B, __m128i __C) { + // CHECK-LABEL: @test_mm_mask_cvthf8_ph( // CHECK: call <8 x half> @llvm.x86.avx10.mask.vcvthf82ph128( - return _mm_mask_cvthf8(__A, __B, __C); + return _mm_mask_cvthf8_ph(__A, __B, __C); } -__m128h test_mm_maskz_cvthf8(__mmask8 __A, __m128i __B) { - // CHECK-LABEL: @test_mm_maskz_cvthf8( +__m128h test_mm_maskz_cvthf8_ph(__mmask8 __A, __m128i __B) { + // CHECK-LABEL: @test_mm_maskz_cvthf8_ph( // CHECK: call <8 x half> @llvm.x86.avx10.mask.vcvthf82ph128( - return _mm_maskz_cvthf8(__A, __B); + return _mm_maskz_cvthf8_ph(__A, __B); } -__m256h test_mm256_cvthf8(__m128i __A) { - // CHECK-LABEL: @test_mm256_cvthf8( +__m256h test_mm256_cvthf8_ph(__m128i __A) { + // CHECK-LABEL: @test_mm256_cvthf8_ph( // CHECK: call <16 x half> @llvm.x86.avx10.mask.vcvthf82ph256( - return _mm256_cvthf8(__A); + return _mm256_cvthf8_ph(__A); } -__m256h test_mm256_mask_cvthf8(__m256h __A, __mmask16 __B, __m128i __C) { - // CHECK-LABEL: @test_mm256_mask_cvthf8( +__m256h test_mm256_mask_cvthf8_ph(__m256h __A, __mmask16 __B, __m128i __C) { + // CHECK-LABEL: @test_mm256_mask_cvthf8_ph( // CHECK: call <16 x half> @llvm.x86.avx10.mask.vcvthf82ph256( - return _mm256_mask_cvthf8(__A, __B, __C); + return _mm256_mask_cvthf8_ph(__A, __B, __C); } -__m256h test_mm256_maskz_cvthf8(__mmask16 __A, __m128i __B) { - // CHECK-LABEL: @test_mm256_maskz_cvthf8( +__m256h test_mm256_maskz_cvthf8_ph(__mmask16 __A, __m128i __B) { + // CHECK-LABEL: @test_mm256_maskz_cvthf8_ph( // CHECK: call <16 x half> @llvm.x86.avx10.mask.vcvthf82ph256( - return _mm256_maskz_cvthf8(__A, __B); + return _mm256_maskz_cvthf8_ph(__A, __B); } __m128i test_mm_cvtph_bf8(__m128h __A) { diff --git a/clang/test/CodeGen/allow-ubsan-check-inline.c b/clang/test/CodeGen/allow-ubsan-check-inline.c index 1de24ab90dac0..eed48cf15ecca 100644 --- a/clang/test/CodeGen/allow-ubsan-check-inline.c +++ b/clang/test/CodeGen/allow-ubsan-check-inline.c @@ -1,3 +1,8 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow -fsanitize-skip-hot-cutoff=signed-integer-overflow=0.000001 -O3 -mllvm -lower-allow-check-random-rate=1 -Rpass=lower-allow-check -Rpass-missed=lower-allow-check -fno-inline 2>&1 | FileCheck %s --check-prefixes=NOINL --implicit-check-not="remark:" +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow -fsanitize-skip-hot-cutoff=signed-integer-overflow=0.000001 -O3 -mllvm -lower-allow-check-random-rate=1 -Rpass=lower-allow-check -Rpass-missed=lower-allow-check 2>&1 | FileCheck %s --check-prefixes=INLINE --implicit-check-not="remark:" +// +// -ubsan-guard-checks is deprecated and will be removed in the future; +// use -fsanitize-skip-hot-cutoff, as shown above. // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow -mllvm -ubsan-guard-checks -O3 -mllvm -lower-allow-check-random-rate=1 -Rpass=lower-allow-check -Rpass-missed=lower-allow-check -fno-inline 2>&1 | FileCheck %s --check-prefixes=NOINL --implicit-check-not="remark:" // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow -mllvm -ubsan-guard-checks -O3 -mllvm -lower-allow-check-random-rate=1 -Rpass=lower-allow-check -Rpass-missed=lower-allow-check 2>&1 | FileCheck %s --check-prefixes=INLINE --implicit-check-not="remark:" diff --git a/clang/test/CodeGen/allow-ubsan-check.c b/clang/test/CodeGen/allow-ubsan-check.c index 38b4848c1edc1..0cd81a77f5cc5 100644 --- a/clang/test/CodeGen/allow-ubsan-check.c +++ b/clang/test/CodeGen/allow-ubsan-check.c @@ -1,4 +1,7 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// +// We can't use -fsanitize-skip-hot-cutoff because that includes both -ubsan-guard-checks and +//-lower-allow-check-percentile-cutoff. // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -O1 -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null,local-bounds -mllvm -ubsan-guard-checks | FileCheck %s // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -O1 -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null,local-bounds -mllvm -ubsan-guard-checks -fsanitize-trap=signed-integer-overflow,integer-divide-by-zero,null,local-bounds | FileCheck %s --check-prefixes=TR // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -O1 -o - %s -fsanitize=signed-integer-overflow,integer-divide-by-zero,null,local-bounds -mllvm -ubsan-guard-checks -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,null,local-bounds | FileCheck %s --check-prefixes=REC @@ -7,18 +10,26 @@ // CHECK-LABEL: define dso_local noundef i32 @div( // CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[Y]], 0, !nosanitize [[META2:![0-9]+]] -// CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], -2147483648, !nosanitize [[META2]] -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[Y]], -1, !nosanitize [[META2]] -// CHECK-NEXT: [[OR_NOT5:%.*]] = and i1 [[TMP1]], [[TMP2]] -// CHECK-NEXT: [[DOTNOT3:%.*]] = or i1 [[TMP0]], [[OR_NOT5]] -// CHECK-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META2]] -// CHECK-NEXT: [[DOTNOT1:%.*]] = and i1 [[DOTNOT3]], [[TMP3]] -// CHECK-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// CHECK-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META2:![0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META2]] +// CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META2]] +// CHECK-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META2]] +// +// 27 == SO_IntegerDivideByZero +// CHECK-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), !nosanitize [[META2]] +// CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META2]] +// CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META2]] +// +// 41 == SO_SignedIntegerOverflow +// CHECK-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] +// CHECK-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]] +// CHECK-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META2]] +// CHECK-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META2]] +// CHECK-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] // CHECK: [[HANDLER_DIVREM_OVERFLOW]]: -// CHECK-NEXT: [[TMP4:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]] -// CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]] -// CHECK-NEXT: tail call void @__ubsan_handle_divrem_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR6:[0-9]+]], !nosanitize [[META2]] +// CHECK-NEXT: [[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]] +// CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]] +// CHECK-NEXT: tail call void @__ubsan_handle_divrem_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]], !nosanitize [[META2]] // CHECK-NEXT: unreachable, !nosanitize [[META2]] // CHECK: [[CONT]]: // CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X]], [[Y]] @@ -27,14 +38,18 @@ // TR-LABEL: define dso_local noundef i32 @div( // TR-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // TR-NEXT: [[ENTRY:.*:]] -// TR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[Y]], 0, !nosanitize [[META2:![0-9]+]] -// TR-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], -2147483648, !nosanitize [[META2]] -// TR-NEXT: [[TMP2:%.*]] = icmp eq i32 [[Y]], -1, !nosanitize [[META2]] -// TR-NEXT: [[OR_NOT5:%.*]] = and i1 [[TMP1]], [[TMP2]] -// TR-NEXT: [[DOTNOT3:%.*]] = or i1 [[TMP0]], [[OR_NOT5]] -// TR-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META2]] -// TR-NEXT: [[DOTNOT1:%.*]] = and i1 [[DOTNOT3]], [[TMP3]] -// TR-NEXT: br i1 [[DOTNOT1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] +// TR-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META2:![0-9]+]] +// TR-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META2]] +// TR-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META2]] +// TR-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META2]] +// TR-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), !nosanitize [[META2]] +// TR-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META2]] +// TR-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META2]] +// TR-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] +// TR-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]] +// TR-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META2]] +// TR-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META2]] +// TR-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[TRAP:.*]], !nosanitize [[META2]] // TR: [[TRAP]]: // TR-NEXT: tail call void @llvm.ubsantrap(i8 3) #[[ATTR5:[0-9]+]], !nosanitize [[META2]] // TR-NEXT: unreachable, !nosanitize [[META2]] @@ -45,18 +60,22 @@ // REC-LABEL: define dso_local noundef i32 @div( // REC-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // REC-NEXT: [[ENTRY:.*:]] -// REC-NEXT: [[TMP0:%.*]] = icmp eq i32 [[Y]], 0, !nosanitize [[META2:![0-9]+]] -// REC-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], -2147483648, !nosanitize [[META2]] -// REC-NEXT: [[TMP2:%.*]] = icmp eq i32 [[Y]], -1, !nosanitize [[META2]] -// REC-NEXT: [[OR_NOT5:%.*]] = and i1 [[TMP1]], [[TMP2]] -// REC-NEXT: [[DOTNOT3:%.*]] = or i1 [[TMP0]], [[OR_NOT5]] -// REC-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META2]] -// REC-NEXT: [[DOTNOT1:%.*]] = and i1 [[DOTNOT3]], [[TMP3]] -// REC-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// REC-NEXT: [[TMP0:%.*]] = icmp ne i32 [[Y]], 0, !nosanitize [[META2:![0-9]+]] +// REC-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X]], -2147483648, !nosanitize [[META2]] +// REC-NEXT: [[TMP2:%.*]] = icmp ne i32 [[Y]], -1, !nosanitize [[META2]] +// REC-NEXT: [[OR:%.*]] = or i1 [[TMP1]], [[TMP2]], !nosanitize [[META2]] +// REC-NEXT: [[TMP3:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 27), !nosanitize [[META2]] +// REC-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true, !nosanitize [[META2]] +// REC-NEXT: [[TMP5:%.*]] = or i1 [[TMP0]], [[TMP4]], !nosanitize [[META2]] +// REC-NEXT: [[TMP6:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] +// REC-NEXT: [[TMP7:%.*]] = xor i1 [[TMP6]], true, !nosanitize [[META2]] +// REC-NEXT: [[TMP8:%.*]] = or i1 [[OR]], [[TMP7]], !nosanitize [[META2]] +// REC-NEXT: [[TMP9:%.*]] = and i1 [[TMP5]], [[TMP8]], !nosanitize [[META2]] +// REC-NEXT: br i1 [[TMP9]], label %[[CONT:.*]], label %[[HANDLER_DIVREM_OVERFLOW:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] // REC: [[HANDLER_DIVREM_OVERFLOW]]: -// REC-NEXT: [[TMP4:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]] -// REC-NEXT: [[TMP5:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]] -// REC-NEXT: tail call void @__ubsan_handle_divrem_overflow(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP4]], i64 [[TMP5]]) #[[ATTR6:[0-9]+]], !nosanitize [[META2]] +// REC-NEXT: [[TMP10:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]] +// REC-NEXT: [[TMP11:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]] +// REC-NEXT: tail call void @__ubsan_handle_divrem_overflow(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR6:[0-9]+]], !nosanitize [[META2]] // REC-NEXT: br label %[[CONT]], !nosanitize [[META2]] // REC: [[CONT]]: // REC-NEXT: [[DIV:%.*]] = sdiv i32 [[X]], [[Y]] @@ -70,21 +89,23 @@ int div(int x, int y) { // CHECK-SAME: ptr noundef readonly [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META2]] -// CHECK-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 22), !nosanitize [[META2]] +// +// 29 == SO_Null +// CHECK-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META2]] // CHECK-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] -// CHECK-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// CHECK-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]] // CHECK: [[HANDLER_TYPE_MISMATCH]]: // CHECK-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META2]] // CHECK-NEXT: unreachable, !nosanitize [[META2]] // CHECK: [[CONT]]: -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA4:![0-9]+]] +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA5:![0-9]+]] // CHECK-NEXT: ret i32 [[TMP2]] // // TR-LABEL: define dso_local i32 @null( // TR-SAME: ptr noundef readonly [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // TR-NEXT: [[ENTRY:.*:]] // TR-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META2]] -// TR-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 22), !nosanitize [[META2]] +// TR-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META2]] // TR-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] // TR-NEXT: br i1 [[DOTNOT1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] // TR: [[TRAP]]: @@ -98,14 +119,14 @@ int div(int x, int y) { // REC-SAME: ptr noundef readonly [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // REC-NEXT: [[ENTRY:.*:]] // REC-NEXT: [[TMP0:%.*]] = icmp eq ptr [[X]], null, !nosanitize [[META2]] -// REC-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 22), !nosanitize [[META2]] +// REC-NEXT: [[TMP1:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 29), !nosanitize [[META2]] // REC-NEXT: [[DOTNOT1:%.*]] = and i1 [[TMP0]], [[TMP1]] -// REC-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// REC-NEXT: br i1 [[DOTNOT1]], label %[[HANDLER_TYPE_MISMATCH:.*]], label %[[CONT:.*]], !prof [[PROF4:![0-9]+]], !nosanitize [[META2]] // REC: [[HANDLER_TYPE_MISMATCH]]: // REC-NEXT: tail call void @__ubsan_handle_type_mismatch_v1(ptr nonnull @[[GLOB2:[0-9]+]], i64 0) #[[ATTR6]], !nosanitize [[META2]] // REC-NEXT: br label %[[CONT]], !nosanitize [[META2]] // REC: [[CONT]]: -// REC-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA4:![0-9]+]] +// REC-NEXT: [[TMP2:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA5:![0-9]+]] // REC-NEXT: ret i32 [[TMP2]] // int null(int* x) { @@ -117,9 +138,11 @@ int null(int* x) { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]]), !nosanitize [[META2]] // CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 0), !nosanitize [[META2]] +// +// 41 == SO_SignedIntegerOverflow +// CHECK-NEXT: [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] // CHECK-NEXT: [[DOTDEMORGAN:%.*]] = and i1 [[TMP1]], [[TMP2]] -// CHECK-NEXT: br i1 [[DOTDEMORGAN]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// CHECK-NEXT: br i1 [[DOTDEMORGAN]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF4]], !nosanitize [[META2]] // CHECK: [[HANDLER_ADD_OVERFLOW]]: // CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]] // CHECK-NEXT: [[TMP4:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]] @@ -134,7 +157,7 @@ int null(int* x) { // TR-NEXT: [[ENTRY:.*:]] // TR-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]]), !nosanitize [[META2]] // TR-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// TR-NEXT: [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 0), !nosanitize [[META2]] +// TR-NEXT: [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] // TR-NEXT: [[DOTDEMORGAN:%.*]] = and i1 [[TMP1]], [[TMP2]] // TR-NEXT: br i1 [[DOTDEMORGAN]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] // TR: [[TRAP]]: @@ -149,9 +172,9 @@ int null(int* x) { // REC-NEXT: [[ENTRY:.*:]] // REC-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 [[Y]]), !nosanitize [[META2]] // REC-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// REC-NEXT: [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 0), !nosanitize [[META2]] +// REC-NEXT: [[TMP2:%.*]] = tail call i1 @llvm.allow.ubsan.check(i8 41), !nosanitize [[META2]] // REC-NEXT: [[DOTDEMORGAN:%.*]] = and i1 [[TMP1]], [[TMP2]] -// REC-NEXT: br i1 [[DOTDEMORGAN]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// REC-NEXT: br i1 [[DOTDEMORGAN]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF4]], !nosanitize [[META2]] // REC: [[HANDLER_ADD_OVERFLOW]]: // REC-NEXT: [[TMP3:%.*]] = zext i32 [[X]] to i64, !nosanitize [[META2]] // REC-NEXT: [[TMP4:%.*]] = zext i32 [[Y]] to i64, !nosanitize [[META2]] @@ -175,12 +198,14 @@ void use(double*); // CHECK-NEXT: call void @use(ptr noundef nonnull [[VLA]]) #[[ATTR7:[0-9]+]] // CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 // CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[TMP0]], [[IDXPROM]] +// +// 71 == SO_LocalBounds // CHECK-NEXT: [[TMP2:%.*]] = call i1 @llvm.allow.ubsan.check(i8 71), !nosanitize [[META2]] // CHECK-NEXT: [[TMP3:%.*]] = and i1 [[TMP1]], [[TMP2]], !nosanitize [[META2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[TRAP:.*]], label %[[BB4:.*]] // CHECK: [[BB4]]: // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[VLA]], i64 [[IDXPROM]] -// CHECK-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] +// CHECK-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA9:![0-9]+]] // CHECK-NEXT: ret double [[TMP5]] // CHECK: [[TRAP]]: // CHECK-NEXT: call void @__ubsan_handle_local_out_of_bounds_abort() #[[ATTR6]], !nosanitize [[META2]] @@ -202,7 +227,7 @@ void use(double*); // TR-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA7:![0-9]+]] // TR-NEXT: ret double [[TMP5]] // TR: [[TRAP]]: -// TR-NEXT: call void @llvm.ubsantrap(i8 3) #[[ATTR5]], !nosanitize [[META2]] +// TR-NEXT: call void @llvm.ubsantrap(i8 71) #[[ATTR5]], !nosanitize [[META2]] // TR-NEXT: unreachable, !nosanitize [[META2]] // // REC-LABEL: define dso_local double @lbounds( @@ -218,7 +243,7 @@ void use(double*); // REC-NEXT: br i1 [[TMP3]], label %[[TRAP:.*]], label %[[BB4:.*]] // REC: [[BB4]]: // REC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[VLA]], i64 [[IDXPROM]] -// REC-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] +// REC-NEXT: [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA9:![0-9]+]] // REC-NEXT: ret double [[TMP5]] // REC: [[TRAP]]: // REC-NEXT: call void @__ubsan_handle_local_out_of_bounds() #[[ATTR6]], !nosanitize [[META2]] @@ -232,13 +257,14 @@ double lbounds(int b, int i) { //. // CHECK: [[META2]] = !{} -// CHECK: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} -// CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0} -// CHECK: [[META5]] = !{!"int", [[META6:![0-9]+]], i64 0} -// CHECK: [[META6]] = !{!"omnipotent char", [[META7:![0-9]+]], i64 0} -// CHECK: [[META7]] = !{!"Simple C/C++ TBAA"} -// CHECK: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} -// CHECK: [[META9]] = !{!"double", [[META6]], i64 0} +// CHECK: [[PROF3]] = !{!"branch_weights", i32 1048575, i32 1} +// CHECK: [[PROF4]] = !{!"branch_weights", i32 1, i32 1048575} +// CHECK: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0} +// CHECK: [[META6]] = !{!"int", [[META7:![0-9]+]], i64 0} +// CHECK: [[META7]] = !{!"omnipotent char", [[META8:![0-9]+]], i64 0} +// CHECK: [[META8]] = !{!"Simple C/C++ TBAA"} +// CHECK: [[TBAA9]] = !{[[META10:![0-9]+]], [[META10]], i64 0} +// CHECK: [[META10]] = !{!"double", [[META7]], i64 0} //. // TR: [[META2]] = !{} // TR: [[TBAA3]] = !{[[META4:![0-9]+]], [[META4]], i64 0} @@ -249,11 +275,12 @@ double lbounds(int b, int i) { // TR: [[META8]] = !{!"double", [[META5]], i64 0} //. // REC: [[META2]] = !{} -// REC: [[PROF3]] = !{!"branch_weights", i32 1, i32 1048575} -// REC: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0} -// REC: [[META5]] = !{!"int", [[META6:![0-9]+]], i64 0} -// REC: [[META6]] = !{!"omnipotent char", [[META7:![0-9]+]], i64 0} -// REC: [[META7]] = !{!"Simple C/C++ TBAA"} -// REC: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} -// REC: [[META9]] = !{!"double", [[META6]], i64 0} +// REC: [[PROF3]] = !{!"branch_weights", i32 1048575, i32 1} +// REC: [[PROF4]] = !{!"branch_weights", i32 1, i32 1048575} +// REC: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0} +// REC: [[META6]] = !{!"int", [[META7:![0-9]+]], i64 0} +// REC: [[META7]] = !{!"omnipotent char", [[META8:![0-9]+]], i64 0} +// REC: [[META8]] = !{!"Simple C/C++ TBAA"} +// REC: [[TBAA9]] = !{[[META10:![0-9]+]], [[META10]], i64 0} +// REC: [[META10]] = !{!"double", [[META7]], i64 0} //. diff --git a/clang/test/CodeGen/arm-cmse-attr.c b/clang/test/CodeGen/arm-cmse-attr.c index 6322a82dfa462..b01124a03df7b 100644 --- a/clang/test/CodeGen/arm-cmse-attr.c +++ b/clang/test/CodeGen/arm-cmse-attr.c @@ -29,9 +29,9 @@ void f4(void) __attribute__((cmse_nonsecure_entry)) { } -// CHECK: define{{.*}} void @f1(ptr nocapture noundef readonly %fptr) {{[^#]*}}#0 { +// CHECK: define{{.*}} void @f1(ptr noundef readonly captures(none) %fptr) {{[^#]*}}#0 { // CHECK: call void %fptr() #2 -// CHECK: define{{.*}} void @f2(ptr nocapture noundef readonly %fptr) {{[^#]*}}#0 { +// CHECK: define{{.*}} void @f2(ptr noundef readonly captures(none) %fptr) {{[^#]*}}#0 { // CHECK: call void %fptr() #2 // CHECK: define{{.*}} void @f3() {{[^#]*}}#1 { // CHECK: define{{.*}} void @f4() {{[^#]*}}#1 { diff --git a/clang/test/CodeGen/arm-empty-args.cpp b/clang/test/CodeGen/arm-empty-args.cpp new file mode 100644 index 0000000000000..4e61c78b73ab9 --- /dev/null +++ b/clang/test/CodeGen/arm-empty-args.cpp @@ -0,0 +1,131 @@ +// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - -x c %s | FileCheck %s --check-prefixes=CHECK,C +// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,CXX +// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fclang-abi-compat=19 | FileCheck %s --check-prefixes=CHECK,CXXCLANG19 +// RUN: %clang_cc1 -triple thumbv7k-apple-watchos2.0 -target-abi aapcs16 -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,WATCHOS + +// Empty structs are ignored for PCS purposes on WatchOS and in C mode +// elsewhere. In C++ mode they consume a register slot though. Functions are +// slightly bigger than minimal to make confirmation against actual GCC +// behaviour easier. + +#if __cplusplus +#define EXTERNC extern "C" +#else +#define EXTERNC +#endif + +struct Empty {}; + +// C: define{{.*}} i32 @empty_arg(i32 noundef %a) +// CXX: define{{.*}} i32 @empty_arg(i8 %e.coerce, i32 noundef %a) +// CXXCLANG19: define{{.*}} i32 @empty_arg(i32 noundef %a) +// WATCHOS: define{{.*}} i32 @empty_arg(i32 noundef %a) +EXTERNC int empty_arg(struct Empty e, int a) { + return a; +} + +// C: define{{.*}} void @empty_ret() +// CXX: define{{.*}} void @empty_ret() +// CXXCLANG19: define{{.*}} void @empty_ret() +// WATCHOS: define{{.*}} void @empty_ret() +EXTERNC struct Empty empty_ret(void) { + struct Empty e; + return e; +} + +// However, what counts as "empty" is a baroque mess. This is super-empty, it's +// ignored even in C++ mode. It also has sizeof == 0, violating C++, but that's +// legacy for you: + +struct SuperEmpty { + int arr[0]; +}; + +// C: define{{.*}} i32 @super_empty_arg(i32 noundef %a) +// CXX: define{{.*}} i32 @super_empty_arg(i32 noundef %a) +// CXXCLANG19: define{{.*}} i32 @super_empty_arg(i32 noundef %a) +// WATCHOS: define{{.*}} i32 @super_empty_arg(i32 noundef %a) +EXTERNC int super_empty_arg(struct SuperEmpty e, int a) { + return a; +} + +struct SortOfEmpty { + struct SuperEmpty e; +}; + +// C: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) +// CXX: define{{.*}} i32 @sort_of_empty_arg(i8 %e.coerce, i32 noundef %a) +// CXXCLANG19: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) +// WATCHOS: define{{.*}} i32 @sort_of_empty_arg(i32 noundef %a) +EXTERNC int sort_of_empty_arg(struct Empty e, int a) { + return a; +} + +// C: define{{.*}} void @sort_of_empty_ret() +// CXX: define{{.*}} void @sort_of_empty_ret() +// CXXCLANG19: define{{.*}} void @sort_of_empty_ret() +// WATCHOS: define{{.*}} void @sort_of_empty_ret() +EXTERNC struct SortOfEmpty sort_of_empty_ret(void) { + struct SortOfEmpty e; + return e; +} + +#include + +// va_arg matches the above rules, consuming an incoming argument in cases +// where one would be passed, and not doing so when the argument should be +// ignored. + +EXTERNC int empty_arg_variadic(int a, ...) { +// CHECK-LABEL: @empty_arg_variadic( +// C: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// C-NOT: {{ getelementptr }} +// CXX: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// CXX: %argp.next2 = getelementptr inbounds i8, ptr %argp.cur1, i32 4 +// CXXCLANG19: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// CXXCLANG19-NOT: {{ getelementptr }} +// WATCHOS: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// WATCHOS-NOT: {{ getelementptr }} + va_list vl; + va_start(vl, a); + struct Empty b = va_arg(vl, struct Empty); + int c = va_arg(vl, int); + va_end(vl); + return c; +} + +EXTERNC int super_empty_arg_variadic(int a, ...) { +// CHECK-LABEL: @super_empty_arg_variadic( +// C: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// C-NOT: {{ getelementptr }} +// CXX: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// CXX-NOT: {{ getelementptr }} +// CXXCLANG19: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// CXXCLANG19-NOT: {{ getelementptr }} +// WATCHOS: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// WATCHOS-NOT: {{ getelementptr }} + va_list vl; + va_start(vl, a); + struct SuperEmpty b = va_arg(vl, struct SuperEmpty); + int c = va_arg(vl, int); + va_end(vl); + return c; +} + +EXTERNC int sort_of_empty_arg_variadic(int a, ...) { +// CHECK-LABEL: @sort_of_empty_arg_variadic( +// C: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// C-NOT: {{ getelementptr }} +// CXX: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// CXX-NOT: {{ getelementptr }} +// CXXCLANG19: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// CXXCLANG19-NOT: {{ getelementptr }} +// WATCHOS: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i32 4 +// WATCHOS-NOT: {{ getelementptr }} + va_list vl; + va_start(vl, a); + struct SortOfEmpty b = va_arg(vl, struct SortOfEmpty); + int c = va_arg(vl, int); + va_end(vl); + return c; +} diff --git a/clang/test/CodeGen/arm-mfp8.c b/clang/test/CodeGen/arm-mfp8.c index bf91066335a25..9385b537f18b3 100644 --- a/clang/test/CodeGen/arm-mfp8.c +++ b/clang/test/CodeGen/arm-mfp8.c @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 -// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-C -// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -o - -x c++ %s | FileCheck %s --check-prefixes=CHECK,CHECK-CXX +// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -disable-O0-optnone -o - %s | opt -S --passes=mem2reg | FileCheck %s --check-prefixes=CHECK-C +// RUN: %clang_cc1 -emit-llvm -triple aarch64-arm-none-eabi -target-feature -fp8 -target-feature +neon -disable-O0-optnone -o - -x c++ %s | opt -S --passes=mem2reg | FileCheck %s --check-prefixes=CHECK-CXX // REQUIRES: aarch64-registered-target @@ -10,18 +10,12 @@ // CHECK-C-LABEL: define dso_local <16 x i8> @test_ret_mfloat8x16_t( // CHECK-C-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-C-NEXT: [[ENTRY:.*:]] -// CHECK-C-NEXT: [[V_ADDR:%.*]] = alloca <16 x i8>, align 16 -// CHECK-C-NEXT: store <16 x i8> [[V]], ptr [[V_ADDR]], align 16 -// CHECK-C-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[V_ADDR]], align 16 -// CHECK-C-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-C-NEXT: ret <16 x i8> [[V]] // -// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z21test_ret_mfloat8x16_tu14__MFloat8x16_t( +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z21test_ret_mfloat8x16_t14__Mfloat8x16_t( // CHECK-CXX-SAME: <16 x i8> [[V:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-CXX-NEXT: [[ENTRY:.*:]] -// CHECK-CXX-NEXT: [[V_ADDR:%.*]] = alloca <16 x i8>, align 16 -// CHECK-CXX-NEXT: store <16 x i8> [[V]], ptr [[V_ADDR]], align 16 -// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[V_ADDR]], align 16 -// CHECK-CXX-NEXT: ret <16 x i8> [[TMP0]] +// CHECK-CXX-NEXT: ret <16 x i8> [[V]] // mfloat8x16_t test_ret_mfloat8x16_t(mfloat8x16_t v) { return v; @@ -30,18 +24,12 @@ mfloat8x16_t test_ret_mfloat8x16_t(mfloat8x16_t v) { // CHECK-C-LABEL: define dso_local <8 x i8> @test_ret_mfloat8x8_t( // CHECK-C-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { // CHECK-C-NEXT: [[ENTRY:.*:]] -// CHECK-C-NEXT: [[V_ADDR:%.*]] = alloca <8 x i8>, align 8 -// CHECK-C-NEXT: store <8 x i8> [[V]], ptr [[V_ADDR]], align 8 -// CHECK-C-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[V_ADDR]], align 8 -// CHECK-C-NEXT: ret <8 x i8> [[TMP0]] +// CHECK-C-NEXT: ret <8 x i8> [[V]] // -// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z20test_ret_mfloat8x8_tu13__MFloat8x8_t( +// CHECK-CXX-LABEL: define dso_local <8 x i8> @_Z20test_ret_mfloat8x8_t13__Mfloat8x8_t( // CHECK-CXX-SAME: <8 x i8> [[V:%.*]]) #[[ATTR0]] { // CHECK-CXX-NEXT: [[ENTRY:.*:]] -// CHECK-CXX-NEXT: [[V_ADDR:%.*]] = alloca <8 x i8>, align 8 -// CHECK-CXX-NEXT: store <8 x i8> [[V]], ptr [[V_ADDR]], align 8 -// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[V_ADDR]], align 8 -// CHECK-CXX-NEXT: ret <8 x i8> [[TMP0]] +// CHECK-CXX-NEXT: ret <8 x i8> [[V]] // mfloat8x8_t test_ret_mfloat8x8_t(mfloat8x8_t v) { return v; @@ -50,28 +38,22 @@ mfloat8x8_t test_ret_mfloat8x8_t(mfloat8x8_t v) { // CHECK-C-LABEL: define dso_local <1 x i8> @func1n( // CHECK-C-SAME: <1 x i8> [[MFP8:%.*]]) #[[ATTR0]] { // CHECK-C-NEXT: [[ENTRY:.*:]] -// CHECK-C-NEXT: [[MFP8_ADDR:%.*]] = alloca <1 x i8>, align 1 // CHECK-C-NEXT: [[F1N:%.*]] = alloca [10 x <1 x i8>], align 1 -// CHECK-C-NEXT: store <1 x i8> [[MFP8]], ptr [[MFP8_ADDR]], align 1 -// CHECK-C-NEXT: [[TMP0:%.*]] = load <1 x i8>, ptr [[MFP8_ADDR]], align 1 // CHECK-C-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x <1 x i8>], ptr [[F1N]], i64 0, i64 2 -// CHECK-C-NEXT: store <1 x i8> [[TMP0]], ptr [[ARRAYIDX]], align 1 +// CHECK-C-NEXT: store <1 x i8> [[MFP8]], ptr [[ARRAYIDX]], align 1 // CHECK-C-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x <1 x i8>], ptr [[F1N]], i64 0, i64 2 -// CHECK-C-NEXT: [[TMP1:%.*]] = load <1 x i8>, ptr [[ARRAYIDX1]], align 1 -// CHECK-C-NEXT: ret <1 x i8> [[TMP1]] +// CHECK-C-NEXT: [[TMP0:%.*]] = load <1 x i8>, ptr [[ARRAYIDX1]], align 1 +// CHECK-C-NEXT: ret <1 x i8> [[TMP0]] // // CHECK-CXX-LABEL: define dso_local <1 x i8> @_Z6func1nu6__mfp8( // CHECK-CXX-SAME: <1 x i8> [[MFP8:%.*]]) #[[ATTR0]] { // CHECK-CXX-NEXT: [[ENTRY:.*:]] -// CHECK-CXX-NEXT: [[MFP8_ADDR:%.*]] = alloca <1 x i8>, align 1 // CHECK-CXX-NEXT: [[F1N:%.*]] = alloca [10 x <1 x i8>], align 1 -// CHECK-CXX-NEXT: store <1 x i8> [[MFP8]], ptr [[MFP8_ADDR]], align 1 -// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <1 x i8>, ptr [[MFP8_ADDR]], align 1 // CHECK-CXX-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x <1 x i8>], ptr [[F1N]], i64 0, i64 2 -// CHECK-CXX-NEXT: store <1 x i8> [[TMP0]], ptr [[ARRAYIDX]], align 1 +// CHECK-CXX-NEXT: store <1 x i8> [[MFP8]], ptr [[ARRAYIDX]], align 1 // CHECK-CXX-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [10 x <1 x i8>], ptr [[F1N]], i64 0, i64 2 -// CHECK-CXX-NEXT: [[TMP1:%.*]] = load <1 x i8>, ptr [[ARRAYIDX1]], align 1 -// CHECK-CXX-NEXT: ret <1 x i8> [[TMP1]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <1 x i8>, ptr [[ARRAYIDX1]], align 1 +// CHECK-CXX-NEXT: ret <1 x i8> [[TMP0]] // __mfp8 func1n(__mfp8 mfp8) { __mfp8 f1n[10]; @@ -79,7 +61,43 @@ __mfp8 func1n(__mfp8 mfp8) { return f1n[2]; } +// CHECK-C-LABEL: define dso_local <1 x i8> @test_extract_element( +// CHECK-C-SAME: <16 x i8> [[X:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0]] { +// CHECK-C-NEXT: [[ENTRY:.*:]] +// CHECK-C-NEXT: [[RETVAL:%.*]] = alloca <1 x i8>, align 1 +// CHECK-C-NEXT: [[VECEXT:%.*]] = extractelement <16 x i8> [[X]], i32 [[I]] +// CHECK-C-NEXT: store i8 [[VECEXT]], ptr [[RETVAL]], align 1 +// CHECK-C-NEXT: [[TMP0:%.*]] = load <1 x i8>, ptr [[RETVAL]], align 1 +// CHECK-C-NEXT: ret <1 x i8> [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local <1 x i8> @_Z20test_extract_element14__Mfloat8x16_ti( +// CHECK-CXX-SAME: <16 x i8> [[X:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[RETVAL:%.*]] = alloca <1 x i8>, align 1 +// CHECK-CXX-NEXT: [[VECEXT:%.*]] = extractelement <16 x i8> [[X]], i32 [[I]] +// CHECK-CXX-NEXT: store i8 [[VECEXT]], ptr [[RETVAL]], align 1 +// CHECK-CXX-NEXT: [[TMP0:%.*]] = load <1 x i8>, ptr [[RETVAL]], align 1 +// CHECK-CXX-NEXT: ret <1 x i8> [[TMP0]] +// +mfloat8_t test_extract_element(mfloat8x16_t x, int i) { + return x[i]; +} - -//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: -// CHECK: {{.*}} +// CHECK-C-LABEL: define dso_local <16 x i8> @test_insert_element( +// CHECK-C-SAME: <16 x i8> [[X:%.*]], i32 noundef [[I:%.*]], <1 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-C-NEXT: [[ENTRY:.*:]] +// CHECK-C-NEXT: [[TMP0:%.*]] = bitcast <1 x i8> [[V]] to i8 +// CHECK-C-NEXT: [[VECINS:%.*]] = insertelement <16 x i8> [[X]], i8 [[TMP0]], i32 [[I]] +// CHECK-C-NEXT: ret <16 x i8> [[VECINS]] +// +// CHECK-CXX-LABEL: define dso_local <16 x i8> @_Z19test_insert_element14__Mfloat8x16_tiu6__mfp8( +// CHECK-CXX-SAME: <16 x i8> [[X:%.*]], i32 noundef [[I:%.*]], <1 x i8> [[V:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: [[TMP0:%.*]] = bitcast <1 x i8> [[V]] to i8 +// CHECK-CXX-NEXT: [[VECINS:%.*]] = insertelement <16 x i8> [[X]], i8 [[TMP0]], i32 [[I]] +// CHECK-CXX-NEXT: ret <16 x i8> [[VECINS]] +// +mfloat8x16_t test_insert_element(mfloat8x16_t x, int i, mfloat8_t v) { + x[i] = v; + return x; +} diff --git a/clang/test/CodeGen/arm-vfp16-arguments.c b/clang/test/CodeGen/arm-vfp16-arguments.c index 3c6691df4747a..c0bbb3df72bf3 100644 --- a/clang/test/CodeGen/arm-vfp16-arguments.c +++ b/clang/test/CodeGen/arm-vfp16-arguments.c @@ -71,6 +71,6 @@ void test_hfa(hfa_t a) {} hfa_t ghfa; hfa_t test_ret_hfa(void) { return ghfa; } -// CHECK-SOFT: define{{.*}} void @test_ret_hfa(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.hfa_t) align 8 initializes((0, 16)) %agg.result) +// CHECK-SOFT: define{{.*}} void @test_ret_hfa(ptr dead_on_unwind noalias writable writeonly sret(%struct.hfa_t) align 8 captures(none) initializes((0, 16)) %agg.result) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @test_ret_hfa() // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.hfa_t @test_ret_hfa() diff --git a/clang/test/CodeGen/arm-vfp16-arguments2.cpp b/clang/test/CodeGen/arm-vfp16-arguments2.cpp index b810cfd0a6648..6e9a24e70c141 100644 --- a/clang/test/CodeGen/arm-vfp16-arguments2.cpp +++ b/clang/test/CodeGen/arm-vfp16-arguments2.cpp @@ -37,27 +37,27 @@ struct S5 : B1 { B1 M[1]; }; -// CHECK-SOFT: define{{.*}} void @_Z2f12S1(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S1) align 8 initializes((0, 16)) %agg.result, [2 x i64] %s1.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f12S1(ptr dead_on_unwind noalias writable writeonly sret(%struct.S1) align 8 captures(none) initializes((0, 16)) %agg.result, [2 x i64] %s1.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f12S1([2 x <2 x i32>] returned %s1.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S1 @_Z2f12S1(%struct.S1 returned %s1.coerce) struct S1 f1(struct S1 s1) { return s1; } -// CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S2) align 8 initializes((0, 16)) %agg.result, [4 x i32] %s2.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr dead_on_unwind noalias writable writeonly sret(%struct.S2) align 8 captures(none) initializes((0, 16)) %agg.result, [4 x i32] %s2.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f22S2([2 x <2 x i32>] returned %s2.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S2 @_Z2f22S2(%struct.S2 %s2.coerce) struct S2 f2(struct S2 s2) { return s2; } -// CHECK-SOFT: define{{.*}} void @_Z2f32S3(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S3) align 8 initializes((0, 16)) %agg.result, [2 x i64] %s3.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f32S3(ptr dead_on_unwind noalias writable writeonly sret(%struct.S3) align 8 captures(none) initializes((0, 16)) %agg.result, [2 x i64] %s3.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f32S3([2 x <2 x i32>] returned %s3.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S3 @_Z2f32S3(%struct.S3 %s3.coerce) struct S3 f3(struct S3 s3) { return s3; } -// CHECK-SOFT: define{{.*}} void @_Z2f42S4(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S4) align 8 initializes((0, 16)) %agg.result, [2 x i64] %s4.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f42S4(ptr dead_on_unwind noalias writable writeonly sret(%struct.S4) align 8 captures(none) initializes((0, 16)) %agg.result, [2 x i64] %s4.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f42S4([2 x <2 x i32>] returned %s4.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S4 @_Z2f42S4(%struct.S4 %s4.coerce) struct S4 f4(struct S4 s4) { return s4; } -// CHECK-SOFT: define{{.*}} void @_Z2f52S5(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.S5) align 8 initializes((0, 16)) %agg.result, [2 x i64] %s5.coerce) +// CHECK-SOFT: define{{.*}} void @_Z2f52S5(ptr dead_on_unwind noalias writable writeonly sret(%struct.S5) align 8 captures(none) initializes((0, 16)) %agg.result, [2 x i64] %s5.coerce) // CHECK-HARD: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 %s5.coerce) // CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S5 @_Z2f52S5(%struct.S5 %s5.coerce) struct S5 f5(struct S5 s5) { return s5; } diff --git a/clang/test/CodeGen/attr-counted-by-pr110385.c b/clang/test/CodeGen/attr-counted-by-pr110385.c index f211610c3173b..412c12cb687c4 100644 --- a/clang/test/CodeGen/attr-counted-by-pr110385.c +++ b/clang/test/CodeGen/attr-counted-by-pr110385.c @@ -26,7 +26,7 @@ struct bucket2 { void init(void * __attribute__((pass_dynamic_object_size(0)))); // CHECK-LABEL: define dso_local void @test1( -// CHECK-SAME: ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[FOO:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[GROWABLE:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GROWABLE]], align 8, !tbaa [[TBAA2:![0-9]+]] diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index 1066e2e74160a..e85f3db1121af 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -9,11 +9,13 @@ #endif #ifdef COUNTED_BY -#define __counted_by(member) __attribute__((__counted_by__(member))) +#define __counted_by(member) __attribute__((__counted_by__(member))) #else #define __counted_by(member) #endif +#define __bdos(P) __builtin_dynamic_object_size(P, 0) + #define DECLARE_FLEX_ARRAY(TYPE, NAME) \ struct { \ struct { } __empty_ ## NAME; \ @@ -75,7 +77,7 @@ struct anon_struct { // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test1( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef writeonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 @@ -93,7 +95,7 @@ struct anon_struct { // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test1( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef writeonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 @@ -112,11 +114,11 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT6:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: // SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR: cont6: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) @@ -125,13 +127,13 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef captures(none) [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] // NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void @@ -153,30 +155,30 @@ void test1(struct annotated *p, int index, int val) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test2(struct annotated *p, size_t index) { - p->array[index] = __builtin_dynamic_object_size(p->array, 1); + p->array[index] = __bdos(p->array); } // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] +// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 [[TMP1]], i64 0 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test2_bdos( // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { @@ -189,7 +191,7 @@ void test2(struct annotated *p, size_t index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test2_bdos(struct annotated *p) { - return __builtin_dynamic_object_size(p->array, 1); + return __bdos(p->array); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3( @@ -236,11 +238,11 @@ size_t test2_bdos(struct annotated *p) { void test3(struct annotated *p, size_t index) { // This test differs from 'test2' by checking bdos on the whole array and not // just the FAM. - p->array[index] = __builtin_dynamic_object_size(p, 0); + p->array[index] = __bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test3_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // @@ -260,107 +262,122 @@ void test3(struct annotated *p, size_t index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test3_bdos(struct annotated *p) { - return __builtin_dynamic_object_size(p, 0); + return __bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 3) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont4: -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl i32 [[COUNTED_BY_LOAD]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 244 -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP5]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM12:%.*]] = sext i32 [[ADD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp ult i64 [[IDXPROM12]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label [[CONT19:%.*]], label [[HANDLER_OUT_OF_BOUNDS15:%.*]], !prof [[PROF3]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds15: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM12]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl i32 [[DOTCOUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT12:%.*]], label [[HANDLER_OUT_OF_BOUNDS8:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds8: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont12: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 244 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = and i32 [[RESULT]], 252 +// SANITIZE-WITH-ATTR-NEXT: [[CONV2:%.*]] = select i1 [[TMP3]], i32 [[TMP4]], i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV2]], ptr [[ARRAYIDX10]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT81:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 3 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT81]], label [[HANDLER_OUT_OF_BOUNDS18:%.*]], label [[CONT19:%.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds18: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 4) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont19: -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], 3 -// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = add i32 [[TMP3]], 240 -// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = select i1 [[TMP7]], i32 [[TMP9]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM12]] -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV8]], ptr [[ARRAYIDX17]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD21:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[ADD27:%.*]] = add nsw i32 [[INDEX]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM28:%.*]] = sext i32 [[ADD27]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = zext i32 [[COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP10]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT35:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds31: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM28]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM31:%.*]] = sext i32 [[ADD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp ult i64 [[IDXPROM31]], [[TMP0]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP5]], label [[CONT38:%.*]], label [[HANDLER_OUT_OF_BOUNDS34:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds34: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM31]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont35: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM28]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = sext i32 [[COUNTED_BY_LOAD21]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = sext i32 [[FAM_IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = sub nsw i64 [[TMP13]], [[TMP14]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = icmp sgt i64 [[TMP15]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = and i1 [[TMP12]], [[TMP16]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP15]] to i32 -// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = shl i32 [[DOTTR]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = and i32 [[TMP18]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV23:%.*]] = select i1 [[TMP17]], i32 [[TMP19]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV23]], ptr [[ARRAYIDX33]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR: cont38: +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[DOTCOUNTED_BY_LOAD]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[RESULT25:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 240 +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = and i32 [[RESULT25]], 252 +// SANITIZE-WITH-ATTR-NEXT: [[CONV27:%.*]] = select i1 [[TMP6]], i32 [[TMP7]], i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX36:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM31]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV27]], ptr [[ARRAYIDX36]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM42:%.*]] = sext i32 [[FAM_IDX]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD44:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD44]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp ugt i64 [[IDXPROM42]], [[TMP8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS45:%.*]], label [[CONT46:%.*]], !prof [[PROF8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds45: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM42]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont46: +// SANITIZE-WITH-ATTR-NEXT: [[ADD59:%.*]] = add nsw i32 [[INDEX]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM60:%.*]] = sext i32 [[ADD59]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = icmp ult i64 [[IDXPROM60]], [[TMP8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP9]], label [[CONT67:%.*]], label [[HANDLER_OUT_OF_BOUNDS63:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds63: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB10:[0-9]+]], i64 [[IDXPROM60]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont67: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX65:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM60]] +// SANITIZE-WITH-ATTR-NEXT: [[COUNT50:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD44]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = sub nsw i64 [[COUNT50]], [[IDXPROM42]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP10]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc nuw i64 [[TMP11]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[CONV54:%.*]] = shl i32 [[DOTTR]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[CONV55:%.*]] = and i32 [[CONV54]], 252 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV55]], ptr [[ARRAYIDX65]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[COUNTED_BY_LOAD]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 244 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i32 [[TMP1]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl i32 [[COUNTED_BY_LOAD]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 244 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = and i32 [[RESULT]], 252 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP0]], i32 [[TMP1]], i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD3:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = shl i32 [[COUNTED_BY_LOAD3]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], 240 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD3]], 3 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = and i32 [[TMP5]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV5:%.*]] = select i1 [[TMP6]], i32 [[TMP7]], i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX3]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD7:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE9:%.*]] = shl i32 [[COUNTED_BY_LOAD7]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT10:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE9]], 240 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD7]], 3 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i32 [[RESULT10]], 252 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV12:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM7:%.*]] = sext i32 [[ADD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM7]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV5]], ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA2]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD10:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = sext i32 [[COUNTED_BY_LOAD10]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = sext i32 [[FAM_IDX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = sub nsw i64 [[TMP8]], [[TMP9]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp sgt i64 [[TMP10]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = and i1 [[TMP12]], [[TMP11]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP10]] to i32 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = shl i32 [[DOTTR]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = and i32 [[TMP14]], 252 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV12:%.*]] = select i1 [[TMP13]], i32 [[TMP15]], i32 0 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD14:%.*]] = add nsw i32 [[INDEX]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM15:%.*]] = sext i32 [[ADD14]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV12]], ptr [[ARRAYIDX16]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM14:%.*]] = sext i32 [[ADD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM14]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV12]], ptr [[ARRAYIDX15]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM17:%.*]] = sext i32 [[FAM_IDX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD20:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT21:%.*]] = sext i32 [[COUNTED_BY_LOAD20]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = sub nsw i64 [[COUNT21]], [[IDXPROM17]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i64 [[TMP4]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = and i1 [[TMP6]], [[TMP5]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP4]] to i32 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = shl i32 [[DOTTR]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 252 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV26:%.*]] = select i1 [[TMP7]], i32 [[TMP9]], i32 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ADD28:%.*]] = add nsw i32 [[INDEX]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM29:%.*]] = sext i32 [[ADD28]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX30:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM29]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV26]], ptr [[ARRAYIDX30]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test4( @@ -399,40 +416,44 @@ size_t test3_bdos(struct annotated *p) { // void test4(struct annotated *p, int index, int fam_idx) { // This tests calculating the size from a pointer inside the FAM. - p->array[index] = (unsigned char)__builtin_dynamic_object_size(&p->array[3], 1); - p->array[index + 1] = (unsigned char)__builtin_dynamic_object_size(&(p->array[4]), 1); - p->array[index + 2] = (unsigned char)__builtin_dynamic_object_size(&(p->array[fam_idx]), 1); + p->array[index] = (unsigned char)__bdos(&p->array[3]); + p->array[index + 1] = (unsigned char)__bdos(&(p->array[4])); + p->array[index + 2] = (unsigned char)__bdos(&(p->array[fam_idx])); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 8589934589) i64 @test4_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP0]], [[TMP1]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[TMP2]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP2]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[INDEX]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i64 [[TMP3]], i64 0 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP7]] +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp ugt i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], label [[CONT1:%.*]], !prof [[PROF8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[DOTCOUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[TMP1]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nuw nsw i64 [[TMP2]], 2 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP3]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = sub nsw i64 [[TMP0]], [[TMP1]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = shl nsw i64 [[TMP2]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp sgt i64 [[TMP2]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = icmp sgt i32 [[INDEX]], -1 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP4]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i64 [[TMP3]], i64 0 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP7]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = shl nsw i64 [[TMP0]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[TMP0]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDEX]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[RESULT]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test4_bdos( // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { @@ -445,7 +466,7 @@ void test4(struct annotated *p, int index, int fam_idx) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test4_bdos(struct annotated *p, int index) { - return __builtin_dynamic_object_size(&p->array[index], 1); + return __bdos(&p->array[index]); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test5( @@ -457,7 +478,7 @@ size_t test4_bdos(struct annotated *p, int index) { // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[DOTCOUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 @@ -493,11 +514,11 @@ size_t test4_bdos(struct annotated *p, int index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test5(struct anon_struct *p, int index) { - p->array[index] = __builtin_dynamic_object_size(p, 1); + p->array[index] = __bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test5_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // @@ -517,7 +538,7 @@ void test5(struct anon_struct *p, int index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test5_bdos(struct anon_struct *p) { - return __builtin_dynamic_object_size(p, 1); + return __bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( @@ -527,30 +548,30 @@ size_t test5_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT6:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR: cont6: // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP1]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) -// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP2]] to i32 -// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[DOTTR]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nuw i64 [[COUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.smax.i64(i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP2]] to i32 // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP0]] to i32 -// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[DOTTR]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nuw i64 [[COUNTED_BY_LOAD]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.smax.i64(i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0) +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i64 [[TMP1]] to i32 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP1]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[TMP0]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void // @@ -573,26 +594,26 @@ size_t test5_bdos(struct anon_struct *p) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test6(struct anon_struct *p, int index) { - p->array[index] = __builtin_dynamic_object_size(p->array, 1); + p->array[index] = __bdos(p->array); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -9223372036854775808) i64 @test6_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 2 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nuw i64 [[COUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0) +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -9223372036854775808) i64 @test6_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i64, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[COUNTED_BY_LOAD]], i64 0) -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nuw i64 [[COUNTED_BY_LOAD]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], i64 0) +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test6_bdos( // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { @@ -605,7 +626,7 @@ void test6(struct anon_struct *p, int index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test6_bdos(struct anon_struct *p) { - return __builtin_dynamic_object_size(p->array, 1); + return __bdos(p->array); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test7( @@ -618,12 +639,12 @@ size_t test6_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8:![0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA9:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test7( @@ -654,11 +675,11 @@ size_t test6_bdos(struct anon_struct *p) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test7(struct union_of_fams *p, int index) { - p->ints[index] = __builtin_dynamic_object_size(p, 1); + p->ints[index] = __bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test7_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // @@ -678,33 +699,33 @@ void test7(struct union_of_fams *p, int index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test7_bdos(struct union_of_fams *p) { - return __builtin_dynamic_object_size(p, 1); + return __bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT14:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR: cont14: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i8 [[COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: store i8 [[COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA9]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] @@ -729,24 +750,24 @@ size_t test7_bdos(struct union_of_fams *p) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test8(struct union_of_fams *p, int index) { - p->ints[index] = __builtin_dynamic_object_size(p->ints, 1); + p->ints[index] = __bdos(p->ints); } // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[COUNT]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = zext i8 [[COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[COUNT]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test8_bdos( // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { @@ -759,7 +780,7 @@ void test8(struct union_of_fams *p, int index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test8_bdos(struct union_of_fams *p) { - return __builtin_dynamic_object_size(p->ints, 1); + return __bdos(p->ints); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test9( @@ -772,12 +793,12 @@ size_t test8_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB14:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA9]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test9( @@ -808,11 +829,11 @@ size_t test8_bdos(struct union_of_fams *p) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test9(struct union_of_fams *p, int index) { - p->bytes[index] = (unsigned char)__builtin_dynamic_object_size(p, 1); + p->bytes[index] = (unsigned char)__bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test9_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // @@ -832,37 +853,37 @@ void test9(struct union_of_fams *p, int index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test9_bdos(struct union_of_fams *p) { - return __builtin_dynamic_object_size(p, 1); + return __bdos(p); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT14:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB19:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont7: +// SANITIZE-WITH-ATTR: cont14: // SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 -// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] +// SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA9]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] @@ -887,26 +908,26 @@ size_t test9_bdos(struct union_of_fams *p) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test10(struct union_of_fams *p, int index) { - p->bytes[index] = (unsigned char)__builtin_dynamic_object_size(p->bytes, 1); + p->bytes[index] = (unsigned char)__bdos(p->bytes); } // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 -// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext nneg i32 [[NARROW]] to i64 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) -// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext nneg i32 [[NARROW]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test10_bdos( // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { @@ -919,34 +940,44 @@ void test10(struct union_of_fams *p, int index) { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test10_bdos(struct union_of_fams *p) { - return __builtin_dynamic_object_size(p->bytes, 1); + return __bdos(p->bytes); } // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test11( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT6:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR: cont6: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -3 +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl i32 [[COUNTED_BY_LOAD]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 8 +// SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[TMP2]], i32 [[RESULT]], i32 0 +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test11( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl i32 [[COUNTED_BY_LOAD]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add i32 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -3 +// NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = select i1 [[TMP0]], i32 [[RESULT]], i32 0 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test11( @@ -955,44 +986,58 @@ size_t test10_bdos(struct union_of_fams *p) { // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// SANITIZE-WITHOUT-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test11( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 -1, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test11(struct annotated *p, int index) { - p->array[index] = __builtin_dynamic_object_size(&p->count, 1); + p->array[index] = __bdos(&p->count); } -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934584, 8589934597) i64 @test11_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: ret i64 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNT1:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT1]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add nsw i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -3 +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[RESULT]], i64 0 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934584, 8589934597) i64 @test11_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT1:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT1]], 2 +// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add nsw i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[COUNTED_BY_LOAD]], -3 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i64 [[RESULT]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP1]] // -// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test11_bdos( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 4 +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test11_bdos( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test11_bdos( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 4 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test11_bdos(struct annotated *p) { - return __builtin_dynamic_object_size(&p->count, 1); + return __bdos(&p->count); } struct { @@ -1011,16 +1056,16 @@ struct hang { int test12_a, test12_b; // SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12( -// SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] { +// SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 // SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR9:[0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT9:![0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT10:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 6 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB22:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] @@ -1028,19 +1073,19 @@ int test12_a, test12_b; // SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP2]], ptr @test12_b, align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr @test12_foo, align 4 // SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds4: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.type_mismatch6: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12( // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR11:[0-9]+]] +// NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR12:[0-9]+]] // NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT7:![0-9]+]] // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] @@ -1056,13 +1101,13 @@ int test12_a, test12_b; // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR6:[0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR7:[0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT7:![0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 6 // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META9:![0-9]+]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP1]]) #[[ATTR7:[0-9]+]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP1]]) #[[ATTR8:[0-9]+]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont: // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] @@ -1072,17 +1117,17 @@ int test12_a, test12_b; // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds4: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR7]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.type_mismatch6: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR7]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12( // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR9:[0-9]+]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR10:[0-9]+]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT7:![0-9]+]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] @@ -1123,7 +1168,7 @@ struct test13_bar { // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[INDEX]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB28:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 @@ -1150,7 +1195,7 @@ struct test13_bar { // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[INDEX]], [[TMP1]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[INDEX]]) #[[ATTR7]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont5: // SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 @@ -1184,7 +1229,7 @@ struct test14_foo { // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB29:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: ret i32 undef @@ -1209,7 +1254,7 @@ struct test14_foo { // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR7]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont3: // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 undef @@ -1238,7 +1283,7 @@ int test14(int idx) { // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB27:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB31:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont1: // SANITIZE-WITH-ATTR-NEXT: ret i32 undef @@ -1258,7 +1303,7 @@ int test14(int idx) { // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR7]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont1: // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 undef @@ -1280,13 +1325,21 @@ int test15(int idx) { return foo.blah[idx]; } -// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test19( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test19( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 680 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 1 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB32:[0-9]+]], i64 2) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // -// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test19( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test19( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // @@ -1302,107 +1355,107 @@ int test15(int idx) { // size_t test19(struct annotated *p) { // Avoid pointer arithmetic. It could lead to security issues. - return __builtin_dynamic_object_size(&(p + 42)->array[2], 1); + return __bdos(&(p + 42)->array[2]); } // SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test20( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test20( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test20( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test20( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test20(struct annotated *p) { // Avoid side-effects. - return __builtin_dynamic_object_size(&(++p)->array[2], 1); + return __bdos(&(++p)->array[2]); } // SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test21( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test21( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test21( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test21( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test21(struct annotated *p) { // Avoid side-effects. - return __builtin_dynamic_object_size(&(p++)->array[2], 1); + return __bdos(&(p++)->array[2]); } // SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test22( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test22( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test22( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test22( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test22(struct annotated *p) { // Avoid side-effects. - return __builtin_dynamic_object_size(&(--p)->array[2], 1); + return __bdos(&(--p)->array[2]); } // SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test23( -// SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test23( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test23( -// SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test23( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readnone [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 // size_t test23(struct annotated *p) { // Avoid side-effects. - return __builtin_dynamic_object_size(&(p--)->array[2], 1); + return __bdos(&(p--)->array[2]); } struct tests_foo { @@ -1418,7 +1471,7 @@ struct tests_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 10 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB28:[0-9]+]], i64 10) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB33:[0-9]+]], i64 10) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont4: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 84 @@ -1426,7 +1479,7 @@ struct tests_foo { // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test24( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef readonly captures(none) [[VAR:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 84 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] @@ -1440,7 +1493,7 @@ struct tests_foo { // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test24( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef readonly captures(none) [[VAR:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 84 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] @@ -1459,7 +1512,7 @@ int test24(int c, struct tests_foo *var) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 10 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB29:[0-9]+]], i64 10) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB34:[0-9]+]], i64 10) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 44 @@ -1467,7 +1520,7 @@ int test24(int c, struct tests_foo *var) { // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test25( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef readonly captures(none) [[VAR:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA14:![0-9]+]] // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 44 @@ -1483,7 +1536,7 @@ int test24(int c, struct tests_foo *var) { // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test25( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef readonly captures(none) [[VAR:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA14:![0-9]+]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 44 @@ -1511,7 +1564,7 @@ struct test26_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB30:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB35:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 @@ -1520,7 +1573,7 @@ struct test26_foo { // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test26( -// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef readonly captures(none) [[FOO:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[C]] to i64 @@ -1538,7 +1591,7 @@ struct test26_foo { // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test26( -// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[FOO:%.*]]) local_unnamed_addr #[[ATTR6]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef readonly captures(none) [[FOO:%.*]]) local_unnamed_addr #[[ATTR6]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[C]] to i64 @@ -1582,7 +1635,7 @@ struct test27_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB32:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB37:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 @@ -1593,7 +1646,7 @@ struct test27_foo { // SANITIZE-WITH-ATTR-NEXT: ret ptr [[ARRAYIDX5]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local ptr @test27( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 @@ -1615,7 +1668,7 @@ struct test27_foo { // SANITIZE-WITHOUT-ATTR-NEXT: ret ptr [[ARRAYIDX4]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local ptr @test27( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR6]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR6]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 @@ -1648,7 +1701,7 @@ struct test28_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT17:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB34:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB39:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont17: // SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 @@ -1657,7 +1710,7 @@ struct test28_foo { // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP5]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test28( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR8]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR8]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[TBAA18:![0-9]+]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA18]] @@ -1681,7 +1734,7 @@ struct test28_foo { // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP3]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test28( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR7]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[P:%.*]], i32 noundef [[I:%.*]]) local_unnamed_addr #[[ATTR7]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P]], align 8, !tbaa [[TBAA18:![0-9]+]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA18]] @@ -1710,42 +1763,42 @@ struct annotated_struct_array { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB36:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB41:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA23:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 -// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM15:%.*]] = sext i32 [[IDX2]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM27:%.*]] = sext i32 [[IDX2]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM15]], [[TMP3]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT20:%.*]], label [[HANDLER_OUT_OF_BOUNDS16:%.*]], !prof [[PROF3]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: handler.out_of_bounds16: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB37:[0-9]+]], i64 [[IDXPROM15]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM27]], [[TMP3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT32:%.*]], label [[HANDLER_OUT_OF_BOUNDS28:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds28: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB42:[0-9]+]], i64 [[IDXPROM27]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: cont20: +// SANITIZE-WITH-ATTR: cont32: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX30:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM27]] // SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP5]], 2 -// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX30]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test29( -// NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR9:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR9:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX1]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA20:![0-9]+]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP1]], 2 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 -// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[IDX2]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM4]] -// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX5]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM8:%.*]] = sext i32 [[IDX2]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM8]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX9]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret void // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test29( @@ -1755,7 +1808,7 @@ struct annotated_struct_array { // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT21:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP1]]) #[[ATTR7]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont21: // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] @@ -1767,7 +1820,7 @@ struct annotated_struct_array { // SANITIZE-WITHOUT-ATTR-NEXT: ret void // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test29( -// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr nocapture noundef readonly [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readonly captures(none) [[ANN:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX1]] to i64 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[IDXPROM]] @@ -1779,7 +1832,7 @@ struct annotated_struct_array { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test29(struct annotated_struct_array *ann, int idx1, int idx2) { - ann->ann_array[idx1]->array[idx2] = __builtin_dynamic_object_size(ann->ann_array[idx1]->array, 1); + ann->ann_array[idx1]->array[idx2] = __bdos(ann->ann_array[idx1]->array); } typedef struct { @@ -1794,10 +1847,10 @@ struct test30_struct { }; // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR4]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB39:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB44:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30( @@ -1813,7 +1866,7 @@ struct test30_struct { // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP0]]) #[[ATTR7]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30( @@ -1826,7 +1879,7 @@ struct test30_struct { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void // void test30(struct test30_struct *ptr, int idx) { - ptr->pcpu_refcnt.__padding[idx] = __builtin_dynamic_object_size(ptr, 1); + ptr->pcpu_refcnt.__padding[idx] = __bdos(ptr); } struct test31_empty {}; @@ -1838,7 +1891,7 @@ struct test31_struct { }; // SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test31( -// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: ret i32 -1 // @@ -1858,5 +1911,339 @@ struct test31_struct { // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 -1 // int test31(struct test31_struct *ptr, int idx) { - return __builtin_dynamic_object_size(ptr, 0); + return __bdos(ptr); +} + +struct annotated_with_array { + unsigned long flags[42]; + int count; + size_t array[] __counted_by(count); +}; + +// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test32( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[IDX2]], 43 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX2]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB46:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 336 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[IDX1]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = zext i32 [[COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = icmp ult i64 [[IDXPROM4]], [[TMP2]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP3]], label [[CONT9:%.*]], label [[HANDLER_OUT_OF_BOUNDS5:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds5: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB48:[0-9]+]], i64 [[IDXPROM4]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont9: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 344 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw [0 x i64], ptr [[ARRAY]], i64 0, i64 [[IDXPROM4]] +// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = shl nuw nsw i32 [[IDX2]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[FIELD_OFFSET:%.*]] = zext nneg i32 [[TMP4]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[REASS_SUB:%.*]] = sub nsw i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], [[FIELD_OFFSET]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = tail call i64 @llvm.smax.i64(i64 [[REASS_SUB]], i64 -344) +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = add nsw i64 [[TMP5]], 344 +// SANITIZE-WITH-ATTR-NEXT: store i64 [[TMP6]], ptr [[ARRAYIDX7]], align 8, !tbaa [[TBAA25:![0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: ret void +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test32( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef captures(none) [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX2]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 336 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[REASS_SUB:%.*]] = shl nsw i64 [[TMP0]], 3 +// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add nsw i64 [[REASS_SUB]], 344 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[TMP0]], -44 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[IDX2]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[RESULT]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 344 +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM1:%.*]] = sext i32 [[IDX1]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [0 x i64], ptr [[ARRAY]], i64 0, i64 [[IDXPROM1]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i64 [[TMP4]], ptr [[ARRAYIDX2]], align 8, !tbaa [[TBAA22:![0-9]+]] +// NO-SANITIZE-WITH-ATTR-NEXT: ret void +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test32( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[IDX2]], 43 +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX2]] to i64, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB17:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: cont7: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 344 +// SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[IDX1]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [0 x i64], ptr [[ARRAY]], i64 0, i64 [[IDXPROM4]] +// SANITIZE-WITHOUT-ATTR-NEXT: store i64 -1, ptr [[ARRAYIDX5]], align 8, !tbaa [[TBAA25:![0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: ret void +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test32( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 344 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM1:%.*]] = sext i32 [[IDX1]] to i64 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [0 x i64], ptr [[ARRAY]], i64 0, i64 [[IDXPROM1]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i64 -1, ptr [[ARRAYIDX2]], align 8, !tbaa [[TBAA22:![0-9]+]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void +// +void test32(struct annotated_with_array *ptr, int idx1, int idx2) { + ptr->array[idx1] = __bdos(&ptr->flags[idx2]); +} + +// SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 17179869521) i64 @test32_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 43 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB49:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 336 +// SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[FLEXIBLE_ARRAY_MEMBER_SIZE:%.*]] = shl nsw i64 [[COUNT]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[INDEX]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[FIELD_OFFSET:%.*]] = zext nneg i32 [[TMP2]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[REASS_SUB:%.*]] = sub nsw i64 [[FLEXIBLE_ARRAY_MEMBER_SIZE]], [[FIELD_OFFSET]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = tail call i64 @llvm.smax.i64(i64 [[REASS_SUB]], i64 -344) +// SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add nsw i64 [[TMP3]], 344 +// SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -34359738016, 34359738705) i64 @test32_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readonly captures(none) [[PTR:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[PTR]], i64 336 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNTED_BY_LOAD:%.*]] = load i32, ptr [[COUNTED_BY_GEP]], align 4 +// NO-SANITIZE-WITH-ATTR-NEXT: [[COUNT:%.*]] = sext i32 [[COUNTED_BY_LOAD]] to i64 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sub nsw i64 [[COUNT]], [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[REASS_SUB:%.*]] = shl nsw i64 [[TMP0]], 3 +// NO-SANITIZE-WITH-ATTR-NEXT: [[RESULT:%.*]] = add nsw i64 [[REASS_SUB]], 344 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[TMP0]], -44 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[INDEX]], -1 +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = and i1 [[TMP2]], [[TMP1]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[RESULT]], i64 0 +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP4]] +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test32_bdos( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 43 +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test32_bdos( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[PTR:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +size_t test32_bdos(struct annotated_with_array *ptr, int index) { + return __bdos(&ptr->flags[index]); +} + +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test33( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test33( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[PTR:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test33( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test33( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[PTR:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +size_t test33(struct annotated *ptr) { + // Don't handle '&ptr->array' like normal. + return __bdos(&*&*&*&ptr->array); +} + +struct multi_subscripts { + unsigned long flags[42][42]; + int count; + int array[] __counted_by(count); +}; + +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test34( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[IDX1]], 42 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB51:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX2]], 43 +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS2:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds2: +// SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[IDX2]] to i64 +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB52:[0-9]+]], i64 [[TMP3]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test34( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test34( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[IDX1]], 42 +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i32 [[IDX2]], 43 +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS2:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: handler.out_of_bounds2: +// SANITIZE-WITHOUT-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[IDX2]] to i64 +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 [[TMP3]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test34( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone [[PTR:%.*]], i32 noundef [[IDX1:%.*]], i32 noundef [[IDX2:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +size_t test34(struct multi_subscripts *ptr, int idx1, int idx2) { + return __bdos(&ptr->flags[idx1][idx2]); +} + +// SANITIZE-WITH-ATTR-LABEL: define dso_local void @test35( +// SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: handler.out_of_bounds: +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB53:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// SANITIZE-WITH-ATTR-NEXT: store i32 0, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] +// SANITIZE-WITH-ATTR-NEXT: ret void +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test35( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef writeonly captures(none) [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// NO-SANITIZE-WITH-ATTR-NEXT: store i32 0, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITH-ATTR-NEXT: ret void +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test35( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// SANITIZE-WITHOUT-ATTR-NEXT: store i32 0, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// SANITIZE-WITHOUT-ATTR-NEXT: ret void +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test35( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef writeonly captures(none) [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[INDEX]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 0, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret void +// +void test35(struct annotated *p, size_t index) { + p->array[index] = __bdos(&p->array[-42]); +} + +// SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test35_bdos( +// SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: ret i64 0 +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i64 @test35_bdos( +// NO-SANITIZE-WITH-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR3]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 0 +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test35_bdos( +// SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 0 +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i64 @test35_bdos( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ptr noundef readnone captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR1]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 0 +// +size_t test35_bdos(struct annotated *p) { + return __bdos(&p->array[-42]); +} + +// See https://github.com/llvm/llvm-project/pull/122198#issuecomment-2627868702 + +typedef struct { + char __padding[0]; +} spinlock_t; + +struct { + int priv_len; + spinlock_t addr_list_lock; + char *dev_addr; + char priv[] __attribute__((__counted_by__(priv_len))); +} x; + +// SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test36( +// SANITIZE-WITH-ATTR-SAME: ) local_unnamed_addr #[[ATTR6:[0-9]+]] { +// SANITIZE-WITH-ATTR-NEXT: entry: +// SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// +// NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i64 @test36( +// NO-SANITIZE-WITH-ATTR-SAME: ) local_unnamed_addr #[[ATTR10:[0-9]+]] { +// NO-SANITIZE-WITH-ATTR-NEXT: entry: +// NO-SANITIZE-WITH-ATTR-NEXT: ret i64 -1 +// +// SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test36( +// SANITIZE-WITHOUT-ATTR-SAME: ) local_unnamed_addr #[[ATTR6:[0-9]+]] { +// SANITIZE-WITHOUT-ATTR-NEXT: entry: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +// NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i64 @test36( +// NO-SANITIZE-WITHOUT-ATTR-SAME: ) local_unnamed_addr #[[ATTR9:[0-9]+]] { +// NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: +// NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i64 -1 +// +size_t test36() { + return __builtin_dynamic_object_size(&x.dev_addr[4], 1); } diff --git a/clang/test/CodeGen/blocks-windows.c b/clang/test/CodeGen/blocks-windows.c index 4379cd2e6b63a..4deccfa931720 100644 --- a/clang/test/CodeGen/blocks-windows.c +++ b/clang/test/CodeGen/blocks-windows.c @@ -1,44 +1,50 @@ // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DECL -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DECL // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DEFN -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DEFN // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS +// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN -// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT -// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT +// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT +// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DECL -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DECL // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DEFN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DEFN // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS +// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -Os -static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS // RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN -// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT -// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT +// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT +// RUN: %clang_cc1 -triple thumbv7-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DECL -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DECL // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DEFN -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DEFN // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS +// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN -// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT -// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT +// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT +// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DECL -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DECL // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DEFN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DEFN // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS +// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -Os -static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS // RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN -// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT -// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT +// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT +// RUN: %clang_cc1 -triple i686-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DECL -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DECL // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DEFN -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DEFN // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS +// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN -// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT -// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT +// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT +// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DECL -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DECL // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_IN_BLOCKS_DEFN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-IN-BLOCKS-DEFN // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS +// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -Os -static-libclosure -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS // RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN -// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT -// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLCOKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT +// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_EXTERN_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT +// RUN: %clang_cc1 -triple x86_64-windows -fblocks -fdeclspec -DBLOCKS_NOT_IN_BLOCKS_DLLIMPORT -Os -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT void *_Block_copy(void *); @@ -70,6 +76,7 @@ int (*g(void))(void) { // CHECK-BLOCKS-IN-BLOCKS-DECL: @_NSConcreteStackBlock = external dso_local dllexport global ptr // CHECK-BLOCKS-IN-BLOCKS-DEFN: @_NSConcreteStackBlock = dso_local dllexport global [5 x i32] // CHECK-BLOCKS-NOT-IN-BLOCKS: @_NSConcreteStackBlock = external dllimport global ptr +// CHECK-BLOCKS-NOT-IN-STATIC-BLOCKS: @_NSConcreteStackBlock = external dso_local global ptr // CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN: @_NSConcreteStackBlock = external dllimport global ptr // CHECK-BLOCKS-NOT-IN-BLOCKS-EXTERN-DLLIMPORT: @_NSConcreteStackBlock = external dllimport global ptr // CHECK-BLOCKS-NOT-IN-BLOCKS-DLLIMPORT: @_NSConcreteStackBlock = external dllimport global ptr diff --git a/clang/test/CodeGen/builtins-elementwise-math.c b/clang/test/CodeGen/builtins-elementwise-math.c index 7f6b5f26eb930..5661bbc6008a0 100644 --- a/clang/test/CodeGen/builtins-elementwise-math.c +++ b/clang/test/CodeGen/builtins-elementwise-math.c @@ -14,10 +14,18 @@ __attribute__((address_space(1))) int int_as_one; typedef int bar; bar b; +struct StructWithBitfield { + int i : 5; + short s : 3; + char c: 2; + long long int lli : 3; +}; + void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2, float4 vf1, float4 vf2, si8 vi1, si8 vi2, long long int i1, long long int i2, short si, - _BitInt(31) bi1, _BitInt(31) bi2) { + _BitInt(31) bi1, _BitInt(31) bi2, int i, + char ci) { // CHECK-LABEL: define void @test_builtin_elementwise_abs( // CHECK: [[F1:%.+]] = load float, ptr %f1.addr, align 4 // CHECK-NEXT: call float @llvm.fabs.f32(float [[F1]]) @@ -35,6 +43,11 @@ void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2, // CHECK-NEXT: call i64 @llvm.abs.i64(i64 [[I1]], i1 false) i2 = __builtin_elementwise_abs(i1); + // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 + // CHECK: [[S1:%.+]] = trunc i64 [[I1]] to i16 + // CHECK-NEXT: call i16 @llvm.abs.i16(i16 [[S1]], i1 false) + i1 = __builtin_elementwise_abs((short)i1); + // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 // CHECK-NEXT: call <8 x i16> @llvm.abs.v8i16(<8 x i16> [[VI1]], i1 false) vi2 = __builtin_elementwise_abs(vi1); @@ -57,10 +70,37 @@ void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2, b = __builtin_elementwise_abs(-10); // CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2 - // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32 - // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.abs.i32(i32 [[SI_EXT]], i1 false) - // CHECK-NEXT: = trunc i32 [[RES]] to i16 + // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.abs.i16(i16 [[SI]], i1 false) si = __builtin_elementwise_abs(si); + + struct StructWithBitfield t; + + // CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8 + // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 11 + // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 11 + // CHECK-NEXT: [[BFCAST:%.+]] = sext i16 [[BFASHR]] to i32 + // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.abs.i32(i32 [[BFCAST]], i1 false) + i = __builtin_elementwise_abs(t.i); + + // CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8 + // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 8 + // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 13 + // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.abs.i16(i16 [[BFASHR]], i1 false) + si = __builtin_elementwise_abs(t.s); + + // CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8 + // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 6 + // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 14 + // CHECK-NEXT: [[BFCAST:%.+]] = trunc i16 [[BFASHR]] to i8 + // CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.abs.i8(i8 [[BFCAST]], i1 false) + ci = __builtin_elementwise_abs(t.c); + + // CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8 + // CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 3 + // CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 13 + // CHECK-NEXT: [[BFCAST:%.+]] = sext i16 [[BFASHR]] to i64 + // CHECK-NEXT: [[RES:%.+]] = call i64 @llvm.abs.i64(i64 [[BFCAST]], i1 false) + i1 = __builtin_elementwise_abs(t.lli); } void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2, @@ -68,7 +108,10 @@ void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2, long long int i2, si8 vi1, si8 vi2, unsigned u1, unsigned u2, u4 vu1, u4 vu2, _BitInt(31) bi1, _BitInt(31) bi2, - unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2) { + unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2, + char c1, char c2, unsigned char uc1, + unsigned char uc2, short s1, short s2, + unsigned short us1, unsigned short us2) { // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8 // CHECK-NEXT: call i64 @llvm.sadd.sat.i64(i64 [[I1]], i64 [[I2]]) @@ -76,7 +119,7 @@ void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2, // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 // CHECK-NEXT: call i64 @llvm.sadd.sat.i64(i64 [[I1]], i64 10) - i1 = __builtin_elementwise_add_sat(i1, 10); + i1 = __builtin_elementwise_add_sat(i1, 10ll); // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16 @@ -114,6 +157,33 @@ void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2, // CHECK: store i64 98, ptr %i1.addr, align 8 i1 = __builtin_elementwise_add_sat(1, 'a'); + + // CHECK: [[C1:%.+]] = load i8, ptr %c1.addr, align 1 + // CHECK-NEXT: [[C2:%.+]] = load i8, ptr %c2.addr, align 1 + // CHECK-NEXT: call i8 @llvm.sadd.sat.i8(i8 [[C1]], i8 [[C2]]) + c1 = __builtin_elementwise_add_sat(c1, c2); + + // CHECK: [[UC1:%.+]] = load i8, ptr %uc1.addr, align 1 + // CHECK-NEXT: [[UC2:%.+]] = load i8, ptr %uc2.addr, align 1 + // CHECK-NEXT: call i8 @llvm.uadd.sat.i8(i8 [[UC1]], i8 [[UC2]]) + uc1 = __builtin_elementwise_add_sat(uc1, uc2); + + // CHECK: [[S1:%.+]] = load i16, ptr %s1.addr, align 2 + // CHECK-NEXT: [[S2:%.+]] = load i16, ptr %s2.addr, align 2 + // CHECK-NEXT: call i16 @llvm.sadd.sat.i16(i16 [[S1]], i16 [[S2]]) + s1 = __builtin_elementwise_add_sat(s1, s2); + + // CHECK: [[S1:%.+]] = load i16, ptr %s1.addr, align 2 + // CHECK: [[I1:%.+]] = sext i16 [[S1]] to i32 + // CHECK-NEXT: [[S2:%.+]] = load i16, ptr %s2.addr, align 2 + // CHECK: [[I2:%.+]] = sext i16 [[S2]] to i32 + // CHECK-NEXT: call i32 @llvm.sadd.sat.i32(i32 [[I1]], i32 [[I2]]) + s1 = __builtin_elementwise_add_sat((int)s1, (int)s2); + + // CHECK: [[US1:%.+]] = load i16, ptr %us1.addr, align 2 + // CHECK-NEXT: [[US2:%.+]] = load i16, ptr %us2.addr, align 2 + // CHECK-NEXT: call i16 @llvm.uadd.sat.i16(i16 [[US1]], i16 [[US2]]) + us1 = __builtin_elementwise_add_sat(us1, us2); } void test_builtin_elementwise_sub_sat(float f1, float f2, double d1, double d2, @@ -121,7 +191,10 @@ void test_builtin_elementwise_sub_sat(float f1, float f2, double d1, double d2, long long int i2, si8 vi1, si8 vi2, unsigned u1, unsigned u2, u4 vu1, u4 vu2, _BitInt(31) bi1, _BitInt(31) bi2, - unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2) { + unsigned _BitInt(55) bu1, unsigned _BitInt(55) bu2, + char c1, char c2, unsigned char uc1, + unsigned char uc2, short s1, short s2, + unsigned short us1, unsigned short us2) { // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8 // CHECK-NEXT: call i64 @llvm.ssub.sat.i64(i64 [[I1]], i64 [[I2]]) @@ -129,7 +202,7 @@ void test_builtin_elementwise_sub_sat(float f1, float f2, double d1, double d2, // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 // CHECK-NEXT: call i64 @llvm.ssub.sat.i64(i64 [[I1]], i64 10) - i1 = __builtin_elementwise_sub_sat(i1, 10); + i1 = __builtin_elementwise_sub_sat(i1, 10ll); // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16 @@ -167,6 +240,26 @@ void test_builtin_elementwise_sub_sat(float f1, float f2, double d1, double d2, // CHECK: store i64 -96, ptr %i1.addr, align 8 i1 = __builtin_elementwise_sub_sat(1, 'a'); + + // CHECK: [[C1:%.+]] = load i8, ptr %c1.addr, align 1 + // CHECK-NEXT: [[C2:%.+]] = load i8, ptr %c2.addr, align 1 + // CHECK-NEXT: call i8 @llvm.ssub.sat.i8(i8 [[C1]], i8 [[C2]]) + c1 = __builtin_elementwise_sub_sat(c1, c2); + + // CHECK: [[UC1:%.+]] = load i8, ptr %uc1.addr, align 1 + // CHECK-NEXT: [[UC2:%.+]] = load i8, ptr %uc2.addr, align 1 + // CHECK-NEXT: call i8 @llvm.usub.sat.i8(i8 [[UC1]], i8 [[UC2]]) + uc1 = __builtin_elementwise_sub_sat(uc1, uc2); + + // CHECK: [[S1:%.+]] = load i16, ptr %s1.addr, align 2 + // CHECK-NEXT: [[S2:%.+]] = load i16, ptr %s2.addr, align 2 + // CHECK-NEXT: call i16 @llvm.ssub.sat.i16(i16 [[S1]], i16 [[S2]]) + s1 = __builtin_elementwise_sub_sat(s1, s2); + + // CHECK: [[US1:%.+]] = load i16, ptr %us1.addr, align 2 + // CHECK-NEXT: [[US2:%.+]] = load i16, ptr %us2.addr, align 2 + // CHECK-NEXT: call i16 @llvm.usub.sat.i16(i16 [[US1]], i16 [[US2]]) + us1 = __builtin_elementwise_sub_sat(us1, us2); } void test_builtin_elementwise_maximum(float f1, float f2, double d1, double d2, @@ -278,7 +371,7 @@ void test_builtin_elementwise_max(float f1, float f2, double d1, double d2, // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 // CHECK-NEXT: call i64 @llvm.smax.i64(i64 [[I1]], i64 10) - i1 = __builtin_elementwise_max(i1, 10); + i1 = __builtin_elementwise_max(i1, 10ll); // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16 @@ -362,7 +455,14 @@ void test_builtin_elementwise_min(float f1, float f2, double d1, double d2, // CHECK: [[I2:%.+]] = load i64, ptr %i2.addr, align 8 // CHECK-NEXT: call i64 @llvm.smin.i64(i64 -11, i64 [[I2]]) - i1 = __builtin_elementwise_min(-11, i2); + i1 = __builtin_elementwise_min(-11ll, i2); + + // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 + // CHECK: [[S1:%.+]] = trunc i64 [[I1]] to i16 + // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8 + // CHECK: [[S2:%.+]] = trunc i64 [[I2]] to i16 + // CHECK-NEXT: call i16 @llvm.smin.i16(i16 [[S1]], i16 [[S2]]) + i1 = __builtin_elementwise_min((short)i1, (short)i2); // CHECK: [[VI1:%.+]] = load <8 x i16>, ptr %vi1.addr, align 16 // CHECK-NEXT: [[VI2:%.+]] = load <8 x i16>, ptr %vi2.addr, align 16 @@ -374,12 +474,6 @@ void test_builtin_elementwise_min(float f1, float f2, double d1, double d2, // CHECK-NEXT: call i32 @llvm.umin.i32(i32 [[U1]], i32 [[U2]]) u1 = __builtin_elementwise_min(u1, u2); - // CHECK: [[U1:%.+]] = load i32, ptr %u1.addr, align 4 - // CHECK-NEXT: [[ZEXT_U1:%.+]] = zext i32 [[U1]] to i64 - // CHECK-NEXT: [[I2:%.+]] = load i64, ptr %i2.addr, align 8 - // CHECK-NEXT: call i64 @llvm.smin.i64(i64 [[ZEXT_U1]], i64 [[I2]]) - u1 = __builtin_elementwise_min(u1, i2); - // CHECK: [[VU1:%.+]] = load <4 x i32>, ptr %vu1.addr, align 16 // CHECK-NEXT: [[VU2:%.+]] = load <4 x i32>, ptr %vu2.addr, align 16 // CHECK-NEXT: call <4 x i32> @llvm.umin.v4i32(<4 x i32> [[VU1]], <4 x i32> [[VU2]]) @@ -418,7 +512,8 @@ void test_builtin_elementwise_min(float f1, float f2, double d1, double d2, void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2, long long int i1, long long int i2, short si, - _BitInt(31) bi1, _BitInt(31) bi2) { + _BitInt(31) bi1, _BitInt(31) bi2, + char ci) { // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 @@ -447,10 +542,24 @@ void test_builtin_elementwise_bitreverse(si8 vi1, si8 vi2, b = __builtin_elementwise_bitreverse(-10); // CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2 - // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32 - // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.bitreverse.i32(i32 [[SI_EXT]]) - // CHECK-NEXT: = trunc i32 [[RES]] to i16 + // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.bitreverse.i16(i16 [[SI]]) si = __builtin_elementwise_bitreverse(si); + + // CHECK: store i16 28671, ptr %si.addr, align 2 + si = __builtin_elementwise_bitreverse((short)-10); + + // CHECK: store i16 28671, ptr %si.addr, align 2 + si = __builtin_elementwise_bitreverse((unsigned short)-10); + + // CHECK: [[CI:%.+]] = load i8, ptr %ci.addr, align 1 + // CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.bitreverse.i8(i8 [[CI]]) + ci = __builtin_elementwise_bitreverse(ci); + + // CHECK: store i8 111, ptr %ci.addr, align 1 + ci = __builtin_elementwise_bitreverse((unsigned char)-10); + + // CHECK: store i8 111, ptr %ci.addr, align 1 + ci = __builtin_elementwise_bitreverse((char)-10); } void test_builtin_elementwise_ceil(float f1, float f2, double d1, double d2, @@ -668,7 +777,8 @@ void test_builtin_elementwise_log2(float f1, float f2, double d1, double d2, void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, long long int i1, long long int i2, short si, - _BitInt(31) bi1, _BitInt(31) bi2) { + _BitInt(31) bi1, _BitInt(31) bi2, + char ci) { // CHECK: [[I1:%.+]] = load i64, ptr %i1.addr, align 8 // CHECK-NEXT: call i64 @llvm.ctpop.i64(i64 [[I1]]) i2 = __builtin_elementwise_popcount(i1); @@ -695,10 +805,24 @@ void test_builtin_elementwise_popcount(si8 vi1, si8 vi2, long long int i1, b = __builtin_elementwise_popcount(-10); // CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2 - // CHECK-NEXT: [[SI_EXT:%.+]] = sext i16 [[SI]] to i32 - // CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.ctpop.i32(i32 [[SI_EXT]]) - // CHECK-NEXT: = trunc i32 [[RES]] to i16 + // CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.ctpop.i16(i16 [[SI]]) si = __builtin_elementwise_popcount(si); + + // CHECK: store i16 3, ptr %si.addr, align 2 + si = __builtin_elementwise_popcount((unsigned short)32771); + + // CHECK: store i16 3, ptr %si.addr, align 2 + si = __builtin_elementwise_popcount((short)32771); + + // CHECK: [[CI:%.+]] = load i8, ptr %ci.addr, align 1 + // CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.ctpop.i8(i8 [[CI]]) + ci = __builtin_elementwise_popcount(ci); + + // CHECK: store i8 2, ptr %ci.addr, align 1 + ci = __builtin_elementwise_popcount((unsigned char)192); + + // CHECK: store i8 2, ptr %ci.addr, align 1 + ci = __builtin_elementwise_popcount((char)192); } void test_builtin_elementwise_fmod(float f1, float f2, double d1, double d2, diff --git a/clang/test/CodeGen/builtins-nvptx.c b/clang/test/CodeGen/builtins-nvptx.c index 163aee4799ff0..ffa41c85c2734 100644 --- a/clang/test/CodeGen/builtins-nvptx.c +++ b/clang/test/CodeGen/builtins-nvptx.c @@ -28,6 +28,11 @@ // RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown -target-cpu sm_89 -target-feature +ptx81 \ // RUN: -fcuda-is-device -emit-llvm -o - -x cuda %s \ // RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PTX81_SM89 %s +// ### The last run to check with the highest SM and PTX version available +// ### to make sure target builtins are still accepted. +// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown -target-cpu sm_100a -target-feature +ptx87 \ +// RUN: -fcuda-is-device -emit-llvm -o - -x cuda %s \ +// RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PTX81_SM89 %s #define __device__ __attribute__((device)) #define __global__ __attribute__((global)) @@ -202,7 +207,7 @@ __device__ void exit() { // NVVM intrinsics // The idea is not to test all intrinsics, just that Clang is recognizing the -// builtins defined in BuiltinsNVPTX.def +// builtins defined in BuiltinsNVPTX.td __device__ void nvvm_math(float f1, float f2, double d1, double d2) { // CHECK: call float @llvm.nvvm.fmax.f float t1 = __nvvm_fmax_f(f1, f2); diff --git a/clang/test/CodeGen/debug-info-enum-extensibility.c b/clang/test/CodeGen/debug-info-enum-extensibility.c new file mode 100644 index 0000000000000..4f8a42bff3f01 --- /dev/null +++ b/clang/test/CodeGen/debug-info-enum-extensibility.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck %s + +// CHECK-NOT: enumKind +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "ClosedEnum" +// CHECK-SAME: enumKind: DW_APPLE_ENUM_KIND_Closed) +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "OpenEnum" +// CHECK-SAME: enumKind: DW_APPLE_ENUM_KIND_Open) +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "ClosedFlagEnum" +// CHECK-SAME: enumKind: DW_APPLE_ENUM_KIND_Closed) +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "OpenFlagEnum" +// CHECK-SAME: enumKind: DW_APPLE_ENUM_KIND_Open) +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "MixedEnum" +// CHECK-SAME: enumKind: DW_APPLE_ENUM_KIND_Open) + +enum Enum { + E0, E1 +}; + +enum FlagEnum { + FE0 = 1 << 0, FE1 = 1 << 1 +}; + +enum __attribute__((enum_extensibility(closed))) ClosedEnum { + A0, A1 +}; + +enum __attribute__((enum_extensibility(open))) OpenEnum { + B0, B1 +}; + +enum __attribute__((enum_extensibility(closed),flag_enum)) ClosedFlagEnum { + C0 = 1 << 0, C1 = 1 << 1 +}; + +enum __attribute__((enum_extensibility(open),flag_enum)) OpenFlagEnum { + D0 = 1 << 0, D1 = 1 << 1 +}; + +enum __attribute__((enum_extensibility(open), enum_extensibility(closed))) MixedEnum { + M0, M1 +}; + +enum Enum e; +enum FlagEnum fe; +enum ClosedEnum ce; +enum OpenEnum oe; +enum ClosedFlagEnum cfe; +enum OpenFlagEnum ofe; +enum MixedEnum me; diff --git a/clang/test/CodeGen/extend-variable-liveness-except.cpp b/clang/test/CodeGen/extend-variable-liveness-except.cpp new file mode 100644 index 0000000000000..c3a29f57bdae5 --- /dev/null +++ b/clang/test/CodeGen/extend-variable-liveness-except.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -fextend-variable-liveness -fcxx-exceptions -fexceptions -o - | FileCheck %s +// This test checks that the fake uses can be generated in exception handling +// blocks and that we can emit fake uses for the __int128 data type. + +extern int bar(); + +/// Try block: fake use ends at try-block scope. +// [[BAR_VAL::%[a-zA-Z0-9\.]+]] = invoke{{.*}} i32 @_Z3barv() +// store i32 %[[BAR_VAL]], ptr [[K_ALLOC_VAL:%[a-zA-Z0-9\.]+]], align 4 +// [[K_FAKE_USE:%[a-zA-Z0-9\.]+]] = load i32, ptr [[K_ALLOC_VAL]], align 4 +// call void (...) @llvm.fake.use(i32 [[K_FAKE_USE]]) #2 +// br label + +/// Catch block: fetching the caught value... +// CHECK: [[CATCH_PTR:%[a-zA-Z0-9\.]+]] = call ptr @__cxa_begin_catch( +// CHECK: [[L_VAL:%[a-zA-Z0-9\.]+]] = load i32, ptr [[CATCH_PTR]], align 4 + +/// Storing to allocas... +// CHECK-DAG: store i32 8, ptr [[M_ALLOC_VAL:%[a-zA-Z0-9\.]+]] +// CHECK-DAG: store i32 [[L_VAL]], ptr [[L_ALLOC_VAL:%[a-zA-Z0-9\.]+]], align 4 + +/// Load into fake uses - expect M to precede L. +// CHECK: [[M_FAKE_VAL:%[a-zA-Z0-9\.]+]] = load i32, ptr [[M_ALLOC_VAL]] +// CHECK: call void (...) @llvm.fake.use(i32 [[M_FAKE_VAL]]) +// CHECK: [[L_FAKE_VAL:%[a-zA-Z0-9\.]+]] = load i32, ptr [[L_ALLOC_VAL]] +// CHECK: call void (...) @llvm.fake.use(i32 [[L_FAKE_VAL]]) +void foo() { + try { + int k = bar(); + } catch (int l) { + /// The catch block contains a fake use for the local within its scope. + int m = 8; + } +} diff --git a/clang/test/CodeGen/extend-variable-liveness-wide-scalar.cpp b/clang/test/CodeGen/extend-variable-liveness-wide-scalar.cpp new file mode 100644 index 0000000000000..42b893cc3cdf7 --- /dev/null +++ b/clang/test/CodeGen/extend-variable-liveness-wide-scalar.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -fextend-variable-liveness -triple x86_64-unknown-linux -o - | FileCheck %s +// REQUIRES: x86-registered-target +// This test checks that the fake uses can be generated in exception handling +// blocks and that we can emit fake uses for the __int128 data type. + +void bar(); + +// CHECK: call void (...) @llvm.fake.use(i128 % +void foo(__int128 wide_int) { + bar(); +} diff --git a/clang/test/CodeGen/extend-variable-liveness.c b/clang/test/CodeGen/extend-variable-liveness.c new file mode 100644 index 0000000000000..c6bca48e6469c --- /dev/null +++ b/clang/test/CodeGen/extend-variable-liveness.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -fextend-variable-liveness -o - | FileCheck %s --implicit-check-not=llvm.fake.use +// Check that fake use calls are emitted at the correct locations, i.e. +// at the end of lexical blocks and at the end of the function. + +int glob_i; +char glob_c; +float glob_f; + +int foo(int i) { + // CHECK-LABEL: define{{.*}}foo + if (i < 4) { + char j = i * 3; + if (glob_i > 3) { + float f = glob_f; + j = f; + glob_c = j; + // CHECK: call void (...) @llvm.fake.use(float % + // CHECK-NEXT: br label % + } + glob_i = j; + // CHECK: call void (...) @llvm.fake.use(i8 % + // CHECK-NEXT: br label % + } + // CHECK: call void (...) @llvm.fake.use(i32 % + // CHECK-NEXT: ret + return 4; +} + +// CHECK: declare void @llvm.fake.use(...) diff --git a/clang/test/CodeGen/fake-use-determinism.c b/clang/test/CodeGen/fake-use-determinism.c new file mode 100644 index 0000000000000..039d8de692431 --- /dev/null +++ b/clang/test/CodeGen/fake-use-determinism.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fextend-variable-liveness %s -o - | FileCheck %s +// +// We are checking that the fake.use calls for i, j and k appear +// in a particular order. It is not the order itself that is important +// but that it remains the same between different test runs. + +// CHECK: [[K_FAKE_USE:%[a-zA-Z0-9\.]+]] = load i32, ptr %k.addr +// CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[K_FAKE_USE]]) #2 +// CHECK-NEXT: [[J_FAKE_USE:%[a-zA-Z0-9\.]+]] = load i32, ptr %j.addr +// CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[J_FAKE_USE]]) #2 +// CHECK-NEXT: [[I_FAKE_USE:%[a-zA-Z0-9\.]+]] = load i32, ptr %i.addr +// CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[I_FAKE_USE]]) #2 + +void bar(); +void foo(int i, int j, int k) +{ + for (int l = 0; l < i; l++) { + bar(); + } +} diff --git a/clang/test/CodeGen/fake-use-lambda.cpp b/clang/test/CodeGen/fake-use-lambda.cpp new file mode 100644 index 0000000000000..aaf25caab6a39 --- /dev/null +++ b/clang/test/CodeGen/fake-use-lambda.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 %s -triple=%itanium_abi_triple -O1 -emit-llvm -fextend-variable-liveness -o - | FileCheck %s +// Make sure we don't crash compiling a lambda that is not nested in a function. +// We also check that fake uses are properly issued in lambdas. + +int glob; + +extern int foo(); + +struct S { + static const int a; +}; + +const int S::a = [](int b) __attribute__((noinline)) { + return b * foo(); +} +(glob); + +int func(int param) { + return ([=](int lambdaparm) __attribute__((noinline))->int { + int lambdalocal = lambdaparm * 2; + return lambdalocal; + }(glob)); +} + +// We are looking for the first lambda's call operator, which should contain +// 2 fake uses, one for 'b' and one for its 'this' pointer (in that order). +// The mangled function name contains a $_0, followed by 'cl'. +// This lambda is an orphaned lambda, i.e. one without lexical parent. +// +// CHECK-LABEL: define internal {{.+\"_Z.+\$_0.*cl.*\"}} +// CHECK-NOT: ret +// CHECK: fake.use(i32 +// CHECK-NOT: ret +// CHECK: fake.use(ptr + +// The second lambda. We are looking for 3 fake uses. +// CHECK-LABEL: define internal {{.+\"_Z.+\$_0.*cl.*\"}} +// CHECK-NOT: ret +// CHECK: fake.use(i32 +// CHECK-NOT: ret +// CHECK: fake.use(i32 +// CHECK-NOT: ret +// CHECK: fake.use(ptr diff --git a/clang/test/CodeGen/fake-use-landingpad.c b/clang/test/CodeGen/fake-use-landingpad.c new file mode 100644 index 0000000000000..ffaf3975ef33f --- /dev/null +++ b/clang/test/CodeGen/fake-use-landingpad.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -emit-llvm -fextend-variable-liveness -fexceptions -o - | FileCheck %s --implicit-check-not="landingpad {" + +// Check that fake uses do not mistakenly cause a landing pad to be generated when +// exceptions are enabled. + +extern void bar(int); +void foo(int p) { + int a = 17; + bar(a); +} + +// CHECK: define {{.*}} @foo +// CHECK-NOT: personality +// CHECK: call void (...) @llvm.fake.use diff --git a/clang/test/CodeGen/fake-use-noreturn.cpp b/clang/test/CodeGen/fake-use-noreturn.cpp new file mode 100644 index 0000000000000..db7f27735b1d3 --- /dev/null +++ b/clang/test/CodeGen/fake-use-noreturn.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -fextend-variable-liveness -o - | FileCheck %s +// +// Check we can correctly produce fake uses for function-level variables even +// when we have a return in a nested conditional and there is no code at the end +// of the function. + +// CHECK-LABEL: define{{.*}}@_Z3fooi +// CHECK: [[I_FAKE_USE:%[a-zA-Z0-9\.]+]] = load i32, ptr %i.addr +// CHECK: call void (...) @llvm.fake.use(i32 [[I_FAKE_USE]]) +// CHECK-LABEL: define{{.*}}@_ZN1C3barEi +// CHECK: [[J_FAKE_USE:%[a-zA-Z0-9\.]+]] = load i32, ptr %j.addr +// CHECK: call void (...) @llvm.fake.use(i32 [[J_FAKE_USE]]) + +void foo(int i) { + while (0) + if (1) + return; +} + +class C { + void bar(int j); +}; + +void C::bar(int j) { + while (0) + if (1) + return; +} diff --git a/clang/test/CodeGen/fake-use-return-line.c b/clang/test/CodeGen/fake-use-return-line.c new file mode 100644 index 0000000000000..50d5885c28348 --- /dev/null +++ b/clang/test/CodeGen/fake-use-return-line.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -fextend-variable-liveness -o - %s | FileCheck %s + +// Clang adjusts the line numbers of returns based on the line numbers of +// dominating stores to %retval; we test that fake use intrinsics do not affect +// this, and the return is given the correct line. + +// CHECK: define{{.*}}@main +// CHECK: call void (...) @llvm.fake.use(i32 +// CHECK-NEXT: ret i32{{.*}}!dbg ![[MDINDEX:[0-9]*]] +// CHECK: ![[MDINDEX]] = !DILocation(line: [[# @LINE + 5]] +int main() +{ + volatile int a = 1; + int b = a + 2; + return b; +} diff --git a/clang/test/CodeGen/fake-use-sanitizer.cpp b/clang/test/CodeGen/fake-use-sanitizer.cpp new file mode 100644 index 0000000000000..e808c645b9c60 --- /dev/null +++ b/clang/test/CodeGen/fake-use-sanitizer.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -fextend-variable-liveness -fsanitize=null -fsanitize-trap=null -o - | FileCheck --check-prefixes=CHECK,NULL --implicit-check-not=ubsantrap %s +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -fextend-variable-liveness -o - | FileCheck %s + +// With -fextend-variable-liveness, the compiler previously generated a fake.use of any +// reference variable at the end of the scope in which its alloca exists. This +// caused two issues, where we would get fake uses for uninitialized variables +// if that variable was declared after an early-return, and UBSan's null checks +// would complain about this. +// This test verifies that UBSan does not produce null-checks for arguments to +// llvm.fake.use, and that fake uses are not emitted for a variable on paths +// it has not been declared. + +struct A { short s1, s2; }; +extern long& getA(); + +void foo() +{ + auto& va = getA(); + if (va < 5) + return; + + auto& vb = getA(); +} + +// CHECK-LABEL: define{{.*}}foo +// CHECK: [[VA_CALL:%.+]] = call{{.*}} ptr @_Z4getAv() + +/// We check here for the first UBSan check for "va". +// NULL: [[VA_ISNULL:%.+]] = icmp ne ptr [[VA_CALL]], null +// NULL: br i1 [[VA_ISNULL]], label %{{[^,]+}}, label %[[VA_TRAP:[^,]+]] +// NULL: [[VA_TRAP]]: +// NULL: call void @llvm.ubsantrap( + +// CHECK: [[VA_PTR:%.+]] = load ptr, ptr %va +// CHECK-NEXT: [[VA_CMP:%.+]] = load i64, ptr [[VA_PTR]] +// CHECK-NEXT: [[VA_CMP_RES:%.+]] = icmp slt i64 [[VA_CMP]], 5 +// CHECK-NEXT: br i1 [[VA_CMP_RES]], label %[[EARLY_EXIT:[^,]+]], label %[[NOT_EARLY_EXIT:[^,]+]] + +// CHECK: [[EARLY_EXIT]]: +// CHECK: br label %cleanup + +/// The fake use for "vb" only appears on the path where its declaration is +/// reached. +// CHECK: [[NOT_EARLY_EXIT]]: +// CHECK: [[VB_CALL:%.+]] = call{{.*}} ptr @_Z4getAv() + +/// We check here for the second UBSan check for "vb". +// NULL: [[VB_ISNULL:%.+]] = icmp ne ptr [[VB_CALL]], null +// NULL: br i1 [[VB_ISNULL]], label %{{[^,]+}}, label %[[VB_TRAP:[^,]+]] +// NULL: [[VB_TRAP]]: +// NULL: call void @llvm.ubsantrap( + +// CHECK: [[VB_FAKE_USE:%.+]] = load ptr, ptr %vb +// CHECK-NEXT: call void (...) @llvm.fake.use(ptr [[VB_FAKE_USE]]) +// CHECK: br label %cleanup + +// CHECK: cleanup: +// CHECK: [[VA_FAKE_USE:%.+]] = load ptr, ptr %va +// CHECK-NEXT: call void (...) @llvm.fake.use(ptr [[VA_FAKE_USE]]) + +// NULL: declare void @llvm.ubsantrap diff --git a/clang/test/CodeGen/fake-use-scalar.c b/clang/test/CodeGen/fake-use-scalar.c new file mode 100644 index 0000000000000..8514d57958920 --- /dev/null +++ b/clang/test/CodeGen/fake-use-scalar.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 %s -emit-llvm -fextend-variable-liveness -o - | FileCheck %s --implicit-check-not=fake.use +// Make sure we don't generate fake.use for non-scalar variables, unless they +// are small enough that they may be represented as a scalar in LLVM IR. +// Make sure we don't generate fake.use for volatile variables +// and parameters even when they are scalar. + +struct BigAggr { + unsigned long t; + char c[1024]; + unsigned char r[32]; +}; + +struct SmallAggr { + int i; + int j; +}; + +int foo(volatile int vol_param, int param) +{ + struct BigAggr big; + struct SmallAggr small; + volatile int vol_local; + int local; + unsigned long_arr[5]; + unsigned short_arr[4]; + return 0; +} + +// CHECK: [[SMALL_ARR_FAKE_USE:%.+]] = load [4 x i[[#UINT_SIZE:]]], ptr %short_arr +// CHECK: call void (...) @llvm.fake.use([4 x i[[#UINT_SIZE]]] [[SMALL_ARR_FAKE_USE]]) + +// CHECK: [[LOCAL_FAKE_USE:%.+]] = load i32, ptr %local +// CHECK: call void (...) @llvm.fake.use(i32 [[LOCAL_FAKE_USE]]) + +// CHECK: [[SMALL_FAKE_USE:%.+]] = load %struct.SmallAggr, ptr %small +// CHECK: call void (...) @llvm.fake.use(%struct.SmallAggr [[SMALL_FAKE_USE]]) + +// CHECK: [[PARAM_FAKE_USE:%.+]] = load i32, ptr %param.addr +// CHECK: call void (...) @llvm.fake.use(i32 [[PARAM_FAKE_USE]]) + +// CHECK: declare void @llvm.fake.use diff --git a/clang/test/CodeGen/fake-use-this.cpp b/clang/test/CodeGen/fake-use-this.cpp new file mode 100644 index 0000000000000..a0ed93d222d50 --- /dev/null +++ b/clang/test/CodeGen/fake-use-this.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -emit-llvm -fextend-variable-liveness=this -o - | FileCheck %s --implicit-check-not=fake.use +// Check that we generate a fake_use call with the 'this' pointer as argument, +// and no other fake uses. +// The call should appear after the call to bar(). + +void bar(); + +class C +{ +public: + bool test(int p); + C(int v): v(v) {} + +private: + int v; +}; + +bool C::test(int p) +{ +// CHECK-LABEL: define{{.*}}_ZN1C4testEi(ptr{{[^,]*}} %this, i32{{.*}} %p) +// CHECK: %this.addr = alloca ptr +// CHECK: store ptr %this, ptr %this.addr + int res = p - v; + + bar(); +// CHECK: call{{.*}}bar + + return res != 0; +// CHECK: [[FAKE_USE:%.+]] = load ptr, ptr %this.addr +// CHECK-NEXT: call void (...) @llvm.fake.use(ptr{{.*}} [[FAKE_USE]]) +// CHECK-NEXT: ret +} + +// CHECK: declare void @llvm.fake.use diff --git a/clang/test/CodeGen/fake-use-while.c b/clang/test/CodeGen/fake-use-while.c new file mode 100644 index 0000000000000..a74887d979528 --- /dev/null +++ b/clang/test/CodeGen/fake-use-while.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -emit-llvm -fextend-variable-liveness -o - | FileCheck %s +// +// Check we don't assert when there is no more code after a while statement +// and the body of the while statement ends in a return, i.e. no insertion point +// is available. + +// CHECK: define{{.*}}foo +// CHECK: call{{.*}}llvm.fake.use + +void foo() { + { + while (1) { + int ret; + if (1) + return; + } + } +} diff --git a/clang/test/CodeGen/fat-lto-objects-cfi.cpp b/clang/test/CodeGen/fat-lto-objects-cfi.cpp index 628951847053a..4055c5bee9b8a 100644 --- a/clang/test/CodeGen/fat-lto-objects-cfi.cpp +++ b/clang/test/CodeGen/fat-lto-objects-cfi.cpp @@ -2,20 +2,20 @@ // RUN: %clang_cc1 -triple x86_64-unknown-fuchsia -O2 -flto -ffat-lto-objects \ // RUN: -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fvisibility=hidden -emit-llvm -o - %s \ -// RUN: | FileCheck %s +// RUN: | FileCheck %s --check-prefix=TYPE_TEST -// CHECK: llvm.embedded.object -// CHECK-SAME: section ".llvm.lto" +// TYPE_TEST: llvm.embedded.object +// TYPE_TEST-SAME: section ".llvm.lto" -// CHECK-LABEL: define hidden void @foo -// CHECK: entry: -// CHECK-NEXT: %cmp14.not = icmp eq i64 %len, 0 -// CHECK-NEXT: br i1 %cmp14.not, label %for.end7, label %for.cond1.preheader.preheader -// CHECK: for.cond1.preheader.preheader: ; preds = %entry -// CHECK-NEXT: %arrayidx.1 = getelementptr inbounds nuw i8, ptr %ptr, i64 4 -// CHECK-NEXT: br label %for.cond1.preheader +// TYPE_TEST-LABEL: define hidden void @foo +// TYPE_TEST: entry: +// TYPE_TEST-NEXT: %cmp14.not = icmp eq i64 %len, 0 +// TYPE_TEST-NEXT: br i1 %cmp14.not, label %for.end7, label %for.cond1.preheader.preheader +// TYPE_TEST: for.cond1.preheader.preheader: ; preds = %entry +// TYPE_TEST-NEXT: %arrayidx.1 = getelementptr inbounds nuw i8, ptr %ptr, i64 4 +// TYPE_TEST-NEXT: br label %for.cond1.preheader -// CHECK-NOT: @llvm.type.test +// TYPE_TEST-NOT: @llvm.type.test // The code below is a reduced case from https://github.com/llvm/llvm-project/issues/112053 #define __PRINTFLIKE(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs))) diff --git a/clang/test/CodeGen/import-call-optimization.c b/clang/test/CodeGen/import-call-optimization.c new file mode 100644 index 0000000000000..cc4e37fda7bb1 --- /dev/null +++ b/clang/test/CodeGen/import-call-optimization.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -import-call-optimization -emit-llvm %s -o - | FileCheck %s + +void f(void) {} + +// CHECK: !"import-call-optimization", i32 1} diff --git a/clang/test/CodeGen/integer-overflow.c b/clang/test/CodeGen/integer-overflow.c index 9e8cde8b33b16..a3a66e6137bed 100644 --- a/clang/test/CodeGen/integer-overflow.c +++ b/clang/test/CodeGen/integer-overflow.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=WRAPV // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=TRAPV -// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=CATCH_UB,CATCH_UB_POINTER +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow | FileCheck %s --check-prefixes=CATCH_UB,NOCATCH_UB_POINTER // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fsanitize=signed-integer-overflow -fwrapv | FileCheck %s --check-prefixes=CATCH_UB,NOCATCH_UB_POINTER // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv -ftrapv-handler foo | FileCheck %s --check-prefix=TRAPV_HANDLER @@ -57,14 +57,14 @@ void test1(void) { // TRAPV_HANDLER: foo( --a; - // -fwrapv should turn off inbounds for GEP's, PR9256 + // -fwrapv does not affect inbounds for GEP's. + // This is controlled by -fwrapv-pointer instead. extern int* P; ++P; // DEFAULT: getelementptr inbounds nuw i32, ptr - // WRAPV: getelementptr i32, ptr + // WRAPV: getelementptr inbounds nuw i32, ptr // TRAPV: getelementptr inbounds nuw i32, ptr - // CATCH_UB_POINTER: getelementptr inbounds nuw i32, ptr - // NOCATCH_UB_POINTER: getelementptr i32, ptr + // NOCATCH_UB_POINTER: getelementptr inbounds nuw i32, ptr // PR9350: char pre-increment never overflows. extern volatile signed char PR9350_char_inc; diff --git a/clang/test/CodeGen/isfpclass.c b/clang/test/CodeGen/isfpclass.c index 1bf60b8fbca17..26dd846a2bf20 100644 --- a/clang/test/CodeGen/isfpclass.c +++ b/clang/test/CodeGen/isfpclass.c @@ -160,7 +160,7 @@ int4 check_isfpclass_nan_strict_v4f32(float4 x) { } // CHECK-LABEL: define dso_local void @check_isfpclass_nan_v4f64 -// CHECK-SAME: (ptr dead_on_unwind noalias nocapture writable writeonly sret(<4 x i64>) align 16 initializes((0, 32)) [[AGG_RESULT:%.*]], ptr nocapture noundef readonly [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +// CHECK-SAME: (ptr dead_on_unwind noalias writable writeonly sret(<4 x i64>) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X:%.*]] = load <4 x double>, ptr [[TMP0]], align 16, !tbaa [[TBAA2:![0-9]+]] // CHECK-NEXT: [[TMP1:%.*]] = fcmp uno <4 x double> [[X]], zeroinitializer diff --git a/clang/test/CodeGen/kcfi-arity.c b/clang/test/CodeGen/kcfi-arity.c new file mode 100644 index 0000000000000..220d444eca30e --- /dev/null +++ b/clang/test/CodeGen/kcfi-arity.c @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-kcfi-arity -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-kcfi-arity -x c++ -o - %s | FileCheck %s +#if !__has_feature(kcfi_arity) +#error Missing kcfi_arity? +#endif + +// CHECK: ![[#]] = !{i32 4, !"kcfi-arity", i32 1} diff --git a/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c b/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c index 440db83fef5da..eb706154300a2 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c +++ b/clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c @@ -53,7 +53,7 @@ long double powl(long double a, long double b); // CHECK-SPIR: [[CALL:%.*]] = tail call spir_func double @powl(double noundef [[A]], double noundef [[B]]) #[[ATTR3:[0-9]+]], !tbaa [[TBAA2:![0-9]+]] // // CHECK-MINGW32-LABEL: define dso_local void @test_powl( -// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret(x86_fp80) align 16 initializes((0, 10)) [[AGG_RESULT:%.*]], ptr nocapture noundef readonly [[TMP0:%.*]], ptr nocapture noundef readonly [[TMP1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias writable writeonly sret(x86_fp80) align 16 captures(none) initializes((0, 10)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) [[TMP0:%.*]], ptr noundef readonly captures(none) [[TMP1:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-MINGW32: [[A:%.*]] = load x86_fp80, ptr [[TMP0]], align 16, !tbaa [[TBAA3:![0-9]+]] // CHECK-MINGW32: [[B:%.*]] = load x86_fp80, ptr [[TMP1]], align 16, !tbaa [[TBAA3]] // CHECK-MINGW32: store x86_fp80 [[A]], ptr [[BYVAL_TEMP:%.*]], align 16, !tbaa [[TBAA3]] @@ -67,7 +67,7 @@ long double test_powl(long double a, long double b) { } // CHECK-LABEL: define dso_local { x86_fp80, x86_fp80 } @test_cargl( -// CHECK-SAME: ptr nocapture noundef readonly byval({ x86_fp80, x86_fp80 }) align 16 [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// CHECK-SAME: ptr noundef readonly byval({ x86_fp80, x86_fp80 }) align 16 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK: [[CLD_REAL:%.*]] = load x86_fp80, ptr [[CLD]], align 16 // CHECK: [[CLD_IMAG:%.*]] = load x86_fp80, ptr [[CLD_IMAGP:%.*]], align 16 // CHECK: store x86_fp80 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16 @@ -75,7 +75,7 @@ long double test_powl(long double a, long double b) { // CHECK: [[CALL:%.*]] = tail call x86_fp80 @cargl(ptr noundef nonnull byval({ x86_fp80, x86_fp80 }) align 16 [[BYVAL_TEMP]]) #[[ATTR5]] // // CHECK-WIN64-LABEL: define dso_local { x86_fp80, x86_fp80 } @test_cargl( -// CHECK-WIN64-SAME: ptr nocapture noundef readonly byval({ x86_fp80, x86_fp80 }) align 16 [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// CHECK-WIN64-SAME: ptr noundef readonly byval({ x86_fp80, x86_fp80 }) align 16 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-WIN64: [[CLD_REAL:%.*]] = load x86_fp80, ptr [[CLD]], align 16 // CHECK-WIN64: [[CLD_IMAG:%.*]] = load x86_fp80, ptr [[CLD_IMAGP:%.*]], align 16 // CHECK-WIN64: store x86_fp80 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16 @@ -83,7 +83,7 @@ long double test_powl(long double a, long double b) { // CHECK-WIN64: [[CALL:%.*]] = tail call x86_fp80 @cargl(ptr noundef nonnull byval({ x86_fp80, x86_fp80 }) align 16 [[BYVAL_TEMP]]) #[[ATTR5]] // // CHECK-I686-LABEL: define dso_local void @test_cargl( -// CHECK-I686-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret({ x86_fp80, x86_fp80 }) align 4 initializes((0, 10), (12, 22)) [[AGG_RESULT:%.*]], ptr nocapture noundef readonly byval({ x86_fp80, x86_fp80 }) align 4 [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// CHECK-I686-SAME: ptr dead_on_unwind noalias writable writeonly sret({ x86_fp80, x86_fp80 }) align 4 captures(none) initializes((0, 10), (12, 22)) [[AGG_RESULT:%.*]], ptr noundef readonly byval({ x86_fp80, x86_fp80 }) align 4 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-I686: [[CLD_REAL:%.*]] = load x86_fp80, ptr [[CLD]], align 4 // CHECK-I686: [[CLD_IMAG:%.*]] = load x86_fp80, ptr [[CLD_IMAGP:%.*]], align 4 // CHECK-I686: store x86_fp80 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 4 @@ -93,7 +93,7 @@ long double test_powl(long double a, long double b) { // CHECK-I686: store x86_fp80 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 4 // // CHECK-PPC-LABEL: define dso_local void @test_cargl( -// CHECK-PPC-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret({ ppc_fp128, ppc_fp128 }) align 16 initializes((0, 32)) [[AGG_RESULT:%.*]], ptr nocapture noundef readonly byval({ ppc_fp128, ppc_fp128 }) align 16 [[CLD:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// CHECK-PPC-SAME: ptr dead_on_unwind noalias writable writeonly sret({ ppc_fp128, ppc_fp128 }) align 16 captures(none) initializes((0, 32)) [[AGG_RESULT:%.*]], ptr noundef readonly byval({ ppc_fp128, ppc_fp128 }) align 16 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // CHECK-PPC: [[CLD_REAL:%.*]] = load ppc_fp128, ptr [[CLD]], align 16 // CHECK-PPC: [[CLD_IMAG:%.*]] = load ppc_fp128, ptr [[CLD_IMAGP:%.*]], align 16 // CHECK-PPC: store ppc_fp128 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16 @@ -103,7 +103,7 @@ long double test_powl(long double a, long double b) { // CHECK-PPC: store ppc_fp128 [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 16 // // CHECK-ARM-LABEL: define dso_local void @test_cargl( -// CHECK-ARM-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret({ double, double }) align 8 initializes((0, 16)) [[AGG_RESULT:%.*]], [2 x i64] noundef [[CLD_COERCE:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// CHECK-ARM-SAME: ptr dead_on_unwind noalias writable writeonly sret({ double, double }) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], [2 x i64] noundef [[CLD_COERCE:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // CHECK-ARM: [[CALL:%.*]] = tail call double @cargl([2 x i64] noundef [[CLD_COERCE]]) #[[ATTR2]], !tbaa [[TBAA3]] // CHECK-ARM: store double [[MUL_RL:%.*]], ptr [[AGG_RESULT]], align 8 // CHECK-ARM: store double [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 8 @@ -121,7 +121,7 @@ long double test_powl(long double a, long double b) { // CHECK-AARCH: [[CALL:%.*]] = tail call fp128 @cargl([2 x fp128] noundef alignstack(16) [[CLD_COERCE]]) #[[ATTR2]], !tbaa [[TBAA2]] // // CHECK-SPIR-LABEL: define dso_local spir_func void @test_cargl( -// CHECK-SPIR-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret({ double, double }) align 8 initializes((0, 16)) [[AGG_RESULT:%.*]], ptr nocapture noundef readonly byval({ double, double }) align 8 [[CLD:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// CHECK-SPIR-SAME: ptr dead_on_unwind noalias writable writeonly sret({ double, double }) align 8 captures(none) initializes((0, 16)) [[AGG_RESULT:%.*]], ptr noundef readonly byval({ double, double }) align 8 captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // CHECK-SPIR: [[CLD_REAL:%.*]] = load double, ptr [[CLD]], align 8 // CHECK-SPIR: [[CLD_IMAG:%.*]] = load double, ptr [[CLD_IMAGP:%.*]], align 8 // CHECK-SPIR: store double [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 8 @@ -131,7 +131,7 @@ long double test_powl(long double a, long double b) { // CHECK-SPIR: store double [[MUL_IR:%.*]], ptr [[AGG_RESULT_IMAGP:%.*]], align 8 // // CHECK-MINGW32-LABEL: define dso_local void @test_cargl( -// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias nocapture writable writeonly sret({ x86_fp80, x86_fp80 }) align 16 initializes((0, 10), (16, 26)) [[AGG_RESULT:%.*]], ptr nocapture noundef readonly [[CLD:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-MINGW32-SAME: ptr dead_on_unwind noalias writable writeonly sret({ x86_fp80, x86_fp80 }) align 16 captures(none) initializes((0, 10), (16, 26)) [[AGG_RESULT:%.*]], ptr noundef readonly captures(none) [[CLD:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-MINGW32: [[CLD_REAL:%.*]] = load x86_fp80, ptr [[CLD]], align 16 // CHECK-MINGW32: [[CLD_IMAG:%.*]] = load x86_fp80, ptr [[CLD_IMAGP:%.*]], align 16 // CHECK-MINGW32: store x86_fp80 [[CLD_REAL]], ptr [[BYVAL_TEMP:%.*]], align 16 @@ -189,7 +189,7 @@ int ilogbl(long double a); // CHECK-SPIR: [[CALL:%.*]] = tail call spir_func i32 @ilogbl(double noundef [[A]]) #[[ATTR3]], !tbaa [[TBAA2]] // // CHECK-MINGW32-LABEL: define dso_local i32 @test_ilogb( -// CHECK-MINGW32-SAME: ptr nocapture noundef readonly [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-MINGW32-SAME: ptr noundef readonly captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-MINGW32: [[A:%.*]] = load x86_fp80, ptr [[TMP0]], align 16, !tbaa [[TBAA3]] // CHECK-MINGW32: store x86_fp80 [[A]], ptr [[BYVAL_TEMP:%.*]], align 16, !tbaa [[TBAA3]] // CHECK-MINGW32: [[CALL:%.*]] = call i32 @ilogbl(ptr noundef nonnull [[BYVAL_TEMP]]) #[[ATTR3]] diff --git a/clang/test/CodeGen/math-libcalls-tbaa.c b/clang/test/CodeGen/math-libcalls-tbaa.c index 17a93ed2aed2d..f4e81ea6dff17 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.c +++ b/clang/test/CodeGen/math-libcalls-tbaa.c @@ -14,7 +14,7 @@ float crealf(float _Complex); // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis // CHECK-LABEL: define dso_local float @test_expf( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 40 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] @@ -29,7 +29,7 @@ float test_expf (float num[]) { } // CHECK-LABEL: define dso_local float @test_builtin_expf( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 40 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] @@ -46,7 +46,7 @@ float test_builtin_expf (float num[]) { // // Negative test: fabs cannot set errno // CHECK-LABEL: define dso_local double @test_fabs( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[NUM:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 80 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] @@ -61,7 +61,7 @@ double test_fabs (double num[]) { } // CHECK-LABEL: define dso_local double @test_remainder( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 80 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] @@ -79,7 +79,7 @@ double test_remainder (double num[], double a) { // TODO: frexp is not subject to any errors, but also writes to // its int pointer out argument, so it could emit int TBAA metadata. // CHECK-LABEL: define dso_local double @test_frexp( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] @@ -101,7 +101,7 @@ double test_frexp (double num[]) { // Negative test: sincos is a library function, but is not a builtin function // checked in CodeGenFunction::EmitCallExpr. // CHECK-LABEL: define dso_local float @test_sincos( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[NUM:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[SIN:%.*]] = alloca float, align 4 // CHECK-NEXT: [[COS:%.*]] = alloca float, align 4 @@ -128,7 +128,7 @@ float test_sincos (float num[]) { // TODO: The builtin return a complex type // CHECK-LABEL: define dso_local float @test_cacoshf( -// CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7]] { +// CHECK-SAME: ptr noundef readonly captures(none) [[NUM:%.*]]) local_unnamed_addr #[[ATTR7]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 8 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] diff --git a/clang/test/CodeGen/nofpclass.c b/clang/test/CodeGen/nofpclass.c index 75aa0318421de..8e61ae22ef87f 100644 --- a/clang/test/CodeGen/nofpclass.c +++ b/clang/test/CodeGen/nofpclass.c @@ -920,7 +920,7 @@ _Complex _Float16 defined_complex_func_f16_ret(_Complex _Float16 c) { // // CLFINITEONLY: Function Attrs: convergent norecurse nounwind // CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_variadic -// CLFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr nocapture noundef readonly byval({ half, half }) align 8 [[CF16:%.*]]) local_unnamed_addr #[[ATTR5]] { +// CLFINITEONLY-SAME: (float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr noundef readonly byval({ half, half }) align 8 captures(none) [[CF16:%.*]]) local_unnamed_addr #[[ATTR5]] { // CLFINITEONLY-NEXT: entry: // CLFINITEONLY-NEXT: [[BYVAL_TEMP:%.*]] = alloca { double, double }, align 8 // CLFINITEONLY-NEXT: [[CONV:%.*]] = fpext nnan ninf float [[F32]] to double @@ -1173,7 +1173,7 @@ float call_variadic(float f32, double f64, _Float16 f16, // // CLFINITEONLY: Function Attrs: convergent norecurse nounwind // CLFINITEONLY-LABEL: define dso_local nofpclass(nan inf) float @call_variadic_indirect -// CLFINITEONLY-SAME: (ptr nocapture noundef readonly [[FPTR:%.*]], float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr nocapture noundef readonly byval({ half, half }) align 8 [[CF16:%.*]]) local_unnamed_addr #[[ATTR5]] { +// CLFINITEONLY-SAME: (ptr noundef readonly captures(none) [[FPTR:%.*]], float noundef nofpclass(nan inf) [[F32:%.*]], double noundef nofpclass(nan inf) [[F64:%.*]], half noundef nofpclass(nan inf) [[F16:%.*]], double noundef nofpclass(nan inf) [[V2F32_COERCE:%.*]], <2 x double> noundef nofpclass(nan inf) [[V2F64:%.*]], i32 noundef [[V2F16_COERCE:%.*]], <2 x float> noundef nofpclass(nan inf) [[CF32_COERCE:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE0:%.*]], double noundef nofpclass(nan inf) [[CF64_COERCE1:%.*]], ptr noundef readonly byval({ half, half }) align 8 captures(none) [[CF16:%.*]]) local_unnamed_addr #[[ATTR5]] { // CLFINITEONLY-NEXT: entry: // CLFINITEONLY-NEXT: [[BYVAL_TEMP:%.*]] = alloca { double, double }, align 8 // CLFINITEONLY-NEXT: [[CONV:%.*]] = fpext nnan ninf float [[F32]] to double diff --git a/clang/test/CodeGen/pointer-overflow.c b/clang/test/CodeGen/pointer-overflow.c new file mode 100644 index 0000000000000..9c7821b841980 --- /dev/null +++ b/clang/test/CodeGen/pointer-overflow.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -ftrapv | FileCheck %s --check-prefix=DEFAULT +// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - -fwrapv-pointer | FileCheck %s --check-prefix=FWRAPV-POINTER + +void test(void) { + // -fwrapv-pointer should turn off inbounds for GEP's + extern int* P; + ++P; + // DEFAULT: getelementptr inbounds nuw i32, ptr + // FWRAPV-POINTER: getelementptr i32, ptr +} diff --git a/clang/test/CodeGen/profile-continuous.c b/clang/test/CodeGen/profile-continuous.c new file mode 100644 index 0000000000000..86fa1d149b971 --- /dev/null +++ b/clang/test/CodeGen/profile-continuous.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -fprofile-instrument=llvm -fprofile-continuous %s -o - | FileCheck %s --check-prefix=IRPGO +// RUN: %clang_cc1 -emit-llvm -fprofile-instrument=llvm -fprofile-continuous -fprofile-instrument-path=mydir/default_%m.profraw -mllvm -runtime-counter-relocation %s -o - \ +// RUN: | FileCheck %s --check-prefix=IRPGO_EQ +// RUN: %clang_cc1 -emit-llvm -O2 -fprofile-instrument=csllvm -fprofile-continuous %s -o - | FileCheck %s --check-prefix=CSIRPGO +// RUN: %clang_cc1 -emit-llvm -fprofile-instrument=clang -fprofile-continuous -fprofile-instrument-path=default.profraw %s -o - | FileCheck %s --check-prefix=CLANG_PGO + +// IRPGO: @__llvm_profile_filename = {{.*}} c"%cdefault_%m.profraw\00" +// IRPGO_EQ: @__llvm_profile_filename = {{.*}} c"%cmydir/default_%m.profraw\00" +// CSIRPGO: @__llvm_profile_filename = {{.*}} c"%cdefault_%m.profraw\00" +// CLANG_PGO: @__llvm_profile_filename = {{.*}} c"%cdefault.profraw\00" +void foo(){} diff --git a/clang/test/CodeGen/sanitize-metadata-nosanitize.c b/clang/test/CodeGen/sanitize-metadata-nosanitize.c index fd2fdce31b52f..eabcbd1409fe2 100644 --- a/clang/test/CodeGen/sanitize-metadata-nosanitize.c +++ b/clang/test/CodeGen/sanitize-metadata-nosanitize.c @@ -23,7 +23,7 @@ __attribute__((noinline, not_tail_called)) void escape(const volatile void *p) { // CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) // CHECK-LABEL: define dso_local i32 @normal_function -// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] { +// CHECK-SAME: (ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] !pcsections [[META4:![0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6:![0-9]+]] @@ -40,7 +40,7 @@ int normal_function(int *x, int *y) { // CHECK: Function Attrs: disable_sanitizer_instrumentation mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) // CHECK-LABEL: define dso_local i32 @test_disable_sanitize_instrumentation -// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// CHECK-SAME: (ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]] @@ -57,7 +57,7 @@ __attribute__((disable_sanitizer_instrumentation)) int test_disable_sanitize_ins // CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) // CHECK-LABEL: define dso_local i32 @test_no_sanitize_thread -// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections [[META14:![0-9]+]] { +// CHECK-SAME: (ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] !pcsections [[META14:![0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]] @@ -74,7 +74,7 @@ __attribute__((no_sanitize("thread"))) int test_no_sanitize_thread(int *x, int * // CHECK: Function Attrs: mustprogress nofree norecurse nounwind willreturn memory(write, argmem: readwrite, inaccessiblemem: none) // CHECK-LABEL: define dso_local i32 @test_no_sanitize_all -// CHECK-SAME: (ptr noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections [[META14]] { +// CHECK-SAME: (ptr noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR3]] !pcsections [[META14]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[X_ADDR:%.*]] = alloca ptr, align 8 // CHECK-NEXT: store ptr [[X]], ptr [[X_ADDR]], align 8, !tbaa [[TBAA6]] diff --git a/clang/test/CodeGen/struct-copy.c b/clang/test/CodeGen/struct-copy.c index bb4166c9464ff..299f98833a309 100644 --- a/clang/test/CodeGen/struct-copy.c +++ b/clang/test/CodeGen/struct-copy.c @@ -8,7 +8,7 @@ void foo(struct x *P, struct x *Q) { *P = *Q; } -// CHECK: declare void @llvm.memcpy.p0.p0{{.*}}(ptr noalias nocapture writeonly, ptr noalias nocapture readonly +// CHECK: declare void @llvm.memcpy.p0.p0{{.*}}(ptr noalias writeonly captures(none), ptr noalias readonly void bar(struct x *P, struct x *Q) { // CHECK-LABEL: @bar( diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c index 71eb849433ed4..fe29aadb1dd53 100644 --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -160,11 +160,11 @@ // RUN: %clang_cc1 -triple nvptx-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=NVPTX -// NVPTX: target datalayout = "e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64" +// NVPTX: target datalayout = "e-p:32:32-p6:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64" // RUN: %clang_cc1 -triple nvptx64-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=NVPTX64 -// NVPTX64: target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64" +// NVPTX64: target datalayout = "e-p6:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64" // RUN: %clang_cc1 -triple r600-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=R600 diff --git a/clang/test/CodeGen/tbaa-pointers.c b/clang/test/CodeGen/tbaa-pointers.c index 4aae2552f107a..48adac503357f 100644 --- a/clang/test/CodeGen/tbaa-pointers.c +++ b/clang/test/CodeGen/tbaa-pointers.c @@ -208,12 +208,9 @@ int void_ptrs(void **ptr) { // COMMON-LABEL: define i32 @void_ptrs( // COMMON-SAME: ptr noundef [[PTRA:%.+]]) // COMMON: [[PTR_ADDR:%.+]] = alloca ptr, align 8 -// DISABLE-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] -// DISABLE-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] -// DISABLE-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[ANYPTR]] -// DEFAULT-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID:!.+]] -// DEFAULT-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[P2VOID]] -// DEFAULT-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[P1VOID:!.+]] +// COMMON-NEXT: store ptr [[PTRA]], ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] +// COMMON-NEXT: [[L0:%.+]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa [[ANYPTR]] +// COMMON-NEXT: [[L1:%.+]] = load ptr, ptr [[L0]], align 8, !tbaa [[ANYPTR]] // COMMON-NEXT: [[BOOL:%.+]] = icmp ne ptr [[L1]], null // COMMON-NEXT: [[BOOL_EXT:%.+]] = zext i1 [[BOOL]] to i64 // COMMON-NEXT: [[COND:%.+]] = select i1 [[BOOL]], i32 0, i32 1 @@ -254,7 +251,3 @@ int void_ptrs(void **ptr) { // COMMON: [[INT_TAG]] = !{[[INT_TY:!.+]], [[INT_TY]], i64 0} // COMMON: [[INT_TY]] = !{!"int", [[CHAR]], i64 0} // DEFAULT: [[ANYPTR]] = !{[[ANY_POINTER]], [[ANY_POINTER]], i64 0} -// DEFAULT: [[P2VOID]] = !{[[P2VOID_TY:!.+]], [[P2VOID_TY]], i64 0} -// DEFAULT: [[P2VOID_TY]] = !{!"p2 void", [[ANY_POINTER]], i64 0} -// DEFAULT: [[P1VOID]] = !{[[P1VOID_TY:!.+]], [[P1VOID_TY]], i64 0} -// DEFAULT: [[P1VOID_TY]] = !{!"p1 void", [[ANY_POINTER]], i64 0} diff --git a/clang/test/CodeGen/tbaa-struct-bitfield-endianness.cpp b/clang/test/CodeGen/tbaa-struct-bitfield-endianness.cpp index 7173b6e8fbe2a..1177691ca511e 100644 --- a/clang/test/CodeGen/tbaa-struct-bitfield-endianness.cpp +++ b/clang/test/CodeGen/tbaa-struct-bitfield-endianness.cpp @@ -16,7 +16,7 @@ struct NamedBitfields { }; // CHECK-LABEL: _Z4copyP14NamedBitfieldsS0_ -// CHECK-SAME: ptr nocapture noundef writeonly initializes((0, 16)) [[A1:%.*]], ptr nocapture noundef readonly [[A2:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: ptr noundef writeonly captures(none) initializes((0, 16)) [[A1:%.*]], ptr noundef readonly captures(none) [[A2:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) [[A1]], ptr noundef nonnull align 8 dereferenceable(16) [[A2]], i64 16, i1 false), !tbaa.struct [[TBAA_STRUCT2:![0-9]+]] // CHECK-NEXT: ret void diff --git a/clang/test/CodeGen/transparent-union-type.c b/clang/test/CodeGen/transparent-union-type.c index f7fac25dc0984..5c81b8a02477f 100644 --- a/clang/test/CodeGen/transparent-union-type.c +++ b/clang/test/CodeGen/transparent-union-type.c @@ -53,7 +53,7 @@ void ftest0(tu_c_t uc) { } void ftest1(tu_s_t uc) { } // CHECK-LABEL: define{{.*}} void @ftest1b( -// CHECK-SAME: ptr nocapture noundef readnone [[UC:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: ptr noundef readnone captures(none) [[UC:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret void // @@ -94,14 +94,14 @@ typedef union tu_ptr { } tu_ptr_t __attribute__((transparent_union)); // CHECK-LABEL: define{{.*}} void @ftest5( -// CHECK-SAME: ptr nocapture readnone [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: ptr readnone captures(none) [[UC_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret void // void ftest5(tu_ptr_t uc) { } // CHECK-LABEL: define{{.*}} void @ftest6( -// CHECK-SAME: ptr nocapture noundef readnone [[UC:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: ptr noundef readnone captures(none) [[UC:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: ret void // diff --git a/clang/test/CodeGen/union-tbaa1.c b/clang/test/CodeGen/union-tbaa1.c index 0f7a67cb7eccd..1e2f384c29a5b 100644 --- a/clang/test/CodeGen/union-tbaa1.c +++ b/clang/test/CodeGen/union-tbaa1.c @@ -8,7 +8,7 @@ typedef union __attribute__((aligned(4))) { void bar(vect32 p[][2]); // CHECK-LABEL: define dso_local void @fred -// CHECK-SAME: (i32 noundef [[NUM:%.*]], ptr nocapture noundef writeonly initializes((0, 8)) [[VEC:%.*]], ptr nocapture noundef readonly [[INDEX:%.*]], ptr nocapture noundef readonly [[ARR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: (i32 noundef [[NUM:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[VEC:%.*]], ptr noundef readonly captures(none) [[INDEX:%.*]], ptr noundef readonly captures(none) [[ARR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP:%.*]] = alloca [4 x [2 x %union.vect32]], align 8 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[TMP]]) #[[ATTR3:[0-9]+]] diff --git a/clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp b/clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp new file mode 100644 index 0000000000000..80067500284b1 --- /dev/null +++ b/clang/test/CodeGen/xfail-alloc-align-fn-pointers.cpp @@ -0,0 +1,10 @@ + +// RUN: %clang_cc1 %s + +// FIXME: These should not crash! +// XFAIL: * + +void aa_fn_ptr(char* (*member)(char*) __attribute__((alloc_align(1)))); + +struct Test; +void aa_member_fn_ptr(char* (Test::*member)(char*) __attribute__((alloc_align(1)))); diff --git a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu index 19730e3925515..a48affaec3c8a 100644 --- a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu +++ b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu @@ -50,7 +50,7 @@ // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel1Pi( -// OPT-SAME: ptr addrspace(1) nocapture noundef [[X_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// OPT-SAME: ptr addrspace(1) noundef captures(none) [[X_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(1) [[X_COERCE]], align 4 // OPT-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 @@ -118,7 +118,7 @@ __global__ void kernel1(int *x) { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel2Ri( -// OPT-SAME: ptr addrspace(1) nocapture noundef nonnull align 4 dereferenceable(4) [[X_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// OPT-SAME: ptr addrspace(1) noundef nonnull align 4 captures(none) dereferenceable(4) [[X_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(1) [[X_COERCE]], align 4 // OPT-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 @@ -188,14 +188,14 @@ __global__ void kernel2(int &x) { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel3PU3AS2iPU3AS1i( -// OPT-SAME: ptr addrspace(2) nocapture noundef readonly [[X:%.*]], ptr addrspace(1) nocapture noundef writeonly initializes((0, 4)) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// OPT-SAME: ptr addrspace(2) noundef readonly captures(none) [[X:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 4)) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(2) [[X]], align 4 // OPT-NEXT: store i32 [[TMP0]], ptr addrspace(1) [[Y]], align 4 // OPT-NEXT: ret void // // OPT-SPIRV-LABEL: define spir_kernel void @_Z7kernel3PU3AS2iPU3AS1i( -// OPT-SPIRV-SAME: ptr addrspace(2) nocapture noundef readonly [[X:%.*]], ptr addrspace(1) nocapture noundef writeonly initializes((0, 4)) [[Y:%.*]]) local_unnamed_addr addrspace(4) #[[ATTR1:[0-9]+]] !max_work_group_size [[META5]] { +// OPT-SPIRV-SAME: ptr addrspace(2) noundef readonly captures(none) [[X:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 4)) [[Y:%.*]]) local_unnamed_addr addrspace(4) #[[ATTR1:[0-9]+]] !max_work_group_size [[META5]] { // OPT-SPIRV-NEXT: [[ENTRY:.*:]] // OPT-SPIRV-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(2) [[X]], align 4 // OPT-SPIRV-NEXT: store i32 [[TMP0]], ptr addrspace(1) [[Y]], align 4 @@ -253,7 +253,7 @@ __global__ void kernel3(__attribute__((address_space(2))) int *x, // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local void @_Z4funcPi( -// OPT-SAME: ptr nocapture noundef [[X:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// OPT-SAME: ptr noundef captures(none) [[X:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load i32, ptr [[X]], align 4 // OPT-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 @@ -261,7 +261,7 @@ __global__ void kernel3(__attribute__((address_space(2))) int *x, // OPT-NEXT: ret void // // OPT-SPIRV-LABEL: define spir_func void @_Z4funcPi( -// OPT-SPIRV-SAME: ptr addrspace(4) nocapture noundef [[X:%.*]]) local_unnamed_addr addrspace(4) #[[ATTR2:[0-9]+]] { +// OPT-SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[X:%.*]]) local_unnamed_addr addrspace(4) #[[ATTR2:[0-9]+]] { // OPT-SPIRV-NEXT: [[ENTRY:.*:]] // OPT-SPIRV-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(4) [[X]], align 4 // OPT-SPIRV-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 @@ -327,7 +327,7 @@ struct S { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel41S( -// OPT-SAME: ptr addrspace(4) nocapture noundef readonly byref([[STRUCT_S:%.*]]) align 8 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { +// OPT-SAME: ptr addrspace(4) noundef readonly byref([[STRUCT_S:%.*]]) align 8 captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[COERCE_SROA_0_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(4) [[TMP0]], align 8, !amdgpu.noclobber [[META4:![0-9]+]] // OPT-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[COERCE_SROA_0_0_COPYLOAD]] to ptr addrspace(1) @@ -432,7 +432,7 @@ __global__ void kernel4(struct S s) { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel5P1S( -// OPT-SAME: ptr addrspace(1) nocapture noundef readonly [[S_COERCE:%.*]]) local_unnamed_addr #[[ATTR2]] { +// OPT-SAME: ptr addrspace(1) noundef readonly captures(none) [[S_COERCE:%.*]]) local_unnamed_addr #[[ATTR2]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load ptr, ptr addrspace(1) [[S_COERCE]], align 8 // OPT-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 @@ -535,7 +535,7 @@ struct T { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel61T( -// OPT-SAME: ptr addrspace(4) nocapture noundef readonly byref([[STRUCT_T:%.*]]) align 8 [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { +// OPT-SAME: ptr addrspace(4) noundef readonly byref([[STRUCT_T:%.*]]) align 8 captures(none) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[COERCE_SROA_0_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(4) [[TMP0]], align 8, !amdgpu.noclobber [[META4]] // OPT-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[COERCE_SROA_0_0_COPYLOAD]] to ptr addrspace(1) @@ -623,7 +623,7 @@ __global__ void kernel6(struct T t) { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel7Pi( -// OPT-SAME: ptr addrspace(1) noalias nocapture noundef [[X_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// OPT-SAME: ptr addrspace(1) noalias noundef captures(none) [[X_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(1) [[X_COERCE]], align 4 // OPT-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 @@ -692,7 +692,7 @@ struct SS { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel82SS( -// OPT-SAME: ptr addrspace(1) nocapture [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { +// OPT-SAME: ptr addrspace(1) captures(none) [[A_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load float, ptr addrspace(1) [[A_COERCE]], align 4 // OPT-NEXT: [[ADD:%.*]] = fadd contract float [[TMP0]], 3.000000e+00 diff --git a/clang/test/CodeGenCUDA/offloading-entries.cu b/clang/test/CodeGenCUDA/offloading-entries.cu index d46a25969e3ec..c053cf586f8f5 100644 --- a/clang/test/CodeGenCUDA/offloading-entries.cu +++ b/clang/test/CodeGenCUDA/offloading-entries.cu @@ -18,64 +18,62 @@ //. // CUDA: @managed = global i32 undef, align 4 -// CUDA: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading", align 1 -// CUDA: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__foov, ptr @.offloading.entry_name, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries", align 1 -// CUDA: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading", align 1 -// CUDA: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z21__device_stub__kernelv, ptr @.offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries", align 1 -// CUDA: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading", align 1 -// CUDA: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries", align 1 -// CUDA: @.offloading.entry_name.3 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading", align 1 -// CUDA: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { ptr @managed, ptr @.offloading.entry_name.3, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries", align 1 -// CUDA: @.offloading.entry_name.4 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading", align 1 -// CUDA: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.offloading.entry_name.4, i64 4, i32 2, i32 1 }, section "cuda_offloading_entries", align 1 -// CUDA: @.offloading.entry_name.5 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading", align 1 -// CUDA: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.offloading.entry_name.5, i64 4, i32 3, i32 1 }, section "cuda_offloading_entries", align 1 +// CUDA: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading" +// CUDA: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @_Z18__device_stub__foov, ptr @.offloading.entry_name, i64 0, i64 0, ptr null }, section "llvm_offload_entries" +// CUDA: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading" +// CUDA: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @_Z21__device_stub__kernelv, ptr @.offloading.entry_name.1, i64 0, i64 0, ptr null }, section "llvm_offload_entries" +// CUDA: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading" +// CUDA: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @var, ptr @.offloading.entry_name.2, i64 4, i64 0, ptr null }, section "llvm_offload_entries" +// CUDA: @.offloading.entry_name.3 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading" +// CUDA: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @managed, ptr @.offloading.entry_name.3, i64 4, i64 0, ptr null }, section "llvm_offload_entries" +// CUDA: @.offloading.entry_name.4 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading" +// CUDA: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 2, ptr @surf, ptr @.offloading.entry_name.4, i64 4, i64 1, ptr null }, section "llvm_offload_entries" +// CUDA: @.offloading.entry_name.5 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading" +// CUDA: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 3, ptr @tex, ptr @.offloading.entry_name.5, i64 4, i64 1, ptr null }, section "llvm_offload_entries" //. // HIP: @managed.managed = global i32 0, align 4 // HIP: @managed = externally_initialized global ptr null -// HIP: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading", align 1 -// HIP: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z3foov, ptr @.offloading.entry_name, i64 0, i32 0, i32 0 }, section "hip_offloading_entries", align 1 -// HIP: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading", align 1 -// HIP: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z6kernelv, ptr @.offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries", align 1 -// HIP: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading", align 1 -// HIP: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries", align 1 -// HIP: @managed.managed.3 = private constant %struct.__managed_var { ptr @managed, ptr @managed.managed } -// HIP: @.offloading.entry_name.4 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading", align 1 -// HIP: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { ptr @managed.managed.3, ptr @.offloading.entry_name.4, i64 4, i32 1, i32 4 }, section "hip_offloading_entries", align 1 -// HIP: @.offloading.entry_name.5 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading", align 1 -// HIP: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.offloading.entry_name.5, i64 4, i32 2, i32 1 }, section "hip_offloading_entries", align 1 -// HIP: @.offloading.entry_name.6 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading", align 1 -// HIP: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.offloading.entry_name.6, i64 4, i32 3, i32 1 }, section "hip_offloading_entries", align 1 +// HIP: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading" +// HIP: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 0, ptr @_Z3foov, ptr @.offloading.entry_name, i64 0, i64 0, ptr null }, section "llvm_offload_entries" +// HIP: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading" +// HIP: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 0, ptr @_Z6kernelv, ptr @.offloading.entry_name.1, i64 0, i64 0, ptr null }, section "llvm_offload_entries" +// HIP: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading" +// HIP: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 0, ptr @var, ptr @.offloading.entry_name.2, i64 4, i64 0, ptr null }, section "llvm_offload_entries" +// HIP: @.offloading.entry_name.3 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading" +// HIP: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 1, ptr @managed.managed, ptr @.offloading.entry_name.3, i64 4, i64 4, ptr @managed }, section "llvm_offload_entries" +// HIP: @.offloading.entry_name.4 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading" +// HIP: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 2, ptr @surf, ptr @.offloading.entry_name.4, i64 4, i64 1, ptr null }, section "llvm_offload_entries" +// HIP: @.offloading.entry_name.5 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading" +// HIP: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 3, ptr @tex, ptr @.offloading.entry_name.5, i64 4, i64 1, ptr null }, section "llvm_offload_entries" //. // CUDA-COFF: @managed = dso_local global i32 undef, align 4 -// CUDA-COFF: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading", align 1 -// CUDA-COFF: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__foov, ptr @.offloading.entry_name, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1 -// CUDA-COFF: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading", align 1 -// CUDA-COFF: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z21__device_stub__kernelv, ptr @.offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1 -// CUDA-COFF: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading", align 1 -// CUDA-COFF: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1 -// CUDA-COFF: @.offloading.entry_name.3 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading", align 1 -// CUDA-COFF: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { ptr @managed, ptr @.offloading.entry_name.3, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1 -// CUDA-COFF: @.offloading.entry_name.4 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading", align 1 -// CUDA-COFF: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.offloading.entry_name.4, i64 4, i32 2, i32 1 }, section "cuda_offloading_entries$OE", align 1 -// CUDA-COFF: @.offloading.entry_name.5 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading", align 1 -// CUDA-COFF: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.offloading.entry_name.5, i64 4, i32 3, i32 1 }, section "cuda_offloading_entries$OE", align 1 +// CUDA-COFF: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading" +// CUDA-COFF: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @_Z18__device_stub__foov, ptr @.offloading.entry_name, i64 0, i64 0, ptr null }, section "llvm_offload_entries$OE" +// CUDA-COFF: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading" +// CUDA-COFF: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @_Z21__device_stub__kernelv, ptr @.offloading.entry_name.1, i64 0, i64 0, ptr null }, section "llvm_offload_entries$OE" +// CUDA-COFF: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading" +// CUDA-COFF: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @var, ptr @.offloading.entry_name.2, i64 4, i64 0, ptr null }, section "llvm_offload_entries$OE" +// CUDA-COFF: @.offloading.entry_name.3 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading" +// CUDA-COFF: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 0, ptr @managed, ptr @.offloading.entry_name.3, i64 4, i64 0, ptr null }, section "llvm_offload_entries$OE" +// CUDA-COFF: @.offloading.entry_name.4 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading" +// CUDA-COFF: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 2, ptr @surf, ptr @.offloading.entry_name.4, i64 4, i64 1, ptr null }, section "llvm_offload_entries$OE" +// CUDA-COFF: @.offloading.entry_name.5 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading" +// CUDA-COFF: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 2, i32 3, ptr @tex, ptr @.offloading.entry_name.5, i64 4, i64 1, ptr null }, section "llvm_offload_entries$OE" //. // HIP-COFF: @managed.managed = dso_local global i32 0, align 4 // HIP-COFF: @managed = dso_local externally_initialized global ptr null -// HIP-COFF: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading", align 1 -// HIP-COFF: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z3foov, ptr @.offloading.entry_name, i64 0, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1 -// HIP-COFF: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading", align 1 -// HIP-COFF: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z6kernelv, ptr @.offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1 -// HIP-COFF: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading", align 1 -// HIP-COFF: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1 -// HIP-COFF: @managed.managed.3 = private constant %struct.__managed_var { ptr @managed, ptr @managed.managed } -// HIP-COFF: @.offloading.entry_name.4 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading", align 1 -// HIP-COFF: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { ptr @managed.managed.3, ptr @.offloading.entry_name.4, i64 4, i32 1, i32 4 }, section "hip_offloading_entries$OE", align 1 -// HIP-COFF: @.offloading.entry_name.5 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading", align 1 -// HIP-COFF: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.offloading.entry_name.5, i64 4, i32 2, i32 1 }, section "hip_offloading_entries$OE", align 1 -// HIP-COFF: @.offloading.entry_name.6 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading", align 1 -// HIP-COFF: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.offloading.entry_name.6, i64 4, i32 3, i32 1 }, section "hip_offloading_entries$OE", align 1 +// HIP-COFF: @.offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00", section ".llvm.rodata.offloading" +// HIP-COFF: @.offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 0, ptr @_Z3foov, ptr @.offloading.entry_name, i64 0, i64 0, ptr null }, section "llvm_offload_entries$OE" +// HIP-COFF: @.offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00", section ".llvm.rodata.offloading" +// HIP-COFF: @.offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 0, ptr @_Z6kernelv, ptr @.offloading.entry_name.1, i64 0, i64 0, ptr null }, section "llvm_offload_entries$OE" +// HIP-COFF: @.offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00", section ".llvm.rodata.offloading" +// HIP-COFF: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 0, ptr @var, ptr @.offloading.entry_name.2, i64 4, i64 0, ptr null }, section "llvm_offload_entries$OE" +// HIP-COFF: @.offloading.entry_name.3 = internal unnamed_addr constant [8 x i8] c"managed\00", section ".llvm.rodata.offloading" +// HIP-COFF: @.offloading.entry.managed = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 1, ptr @managed.managed, ptr @.offloading.entry_name.3, i64 4, i64 4, ptr @managed }, section "llvm_offload_entries$OE" +// HIP-COFF: @.offloading.entry_name.4 = internal unnamed_addr constant [5 x i8] c"surf\00", section ".llvm.rodata.offloading" +// HIP-COFF: @.offloading.entry.surf = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 2, ptr @surf, ptr @.offloading.entry_name.4, i64 4, i64 1, ptr null }, section "llvm_offload_entries$OE" +// HIP-COFF: @.offloading.entry_name.5 = internal unnamed_addr constant [4 x i8] c"tex\00", section ".llvm.rodata.offloading" +// HIP-COFF: @.offloading.entry.tex = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 3, i32 3, ptr @tex, ptr @.offloading.entry_name.5, i64 4, i64 1, ptr null }, section "llvm_offload_entries$OE" //. // CUDA-LABEL: @_Z18__device_stub__foov( // CUDA-NEXT: entry: diff --git a/clang/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp b/clang/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp index 3b4a309327fe6..9b855698f57fd 100644 --- a/clang/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp +++ b/clang/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp @@ -11,6 +11,7 @@ typedef unsigned short poly16_t; typedef __fp16 float16_t; typedef float float32_t; typedef double float64_t; +typedef __mfp8 mfloat8_t; typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t; typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t; @@ -26,6 +27,8 @@ typedef __attribute__((neon_vector_type(8))) uint16_t uint16x8_t; typedef __attribute__((neon_vector_type(2))) unsigned int uint32x2_t; typedef __attribute__((neon_vector_type(4))) unsigned int uint32x4_t; typedef __attribute__((neon_vector_type(2))) uint64_t uint64x2_t; +typedef __attribute__((neon_vector_type(8))) mfloat8_t mfloat8x8_t; +typedef __attribute__((neon_vector_type(16))) mfloat8_t mfloat8x16_t; typedef __attribute__((neon_vector_type(4))) float16_t float16x4_t; typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t; typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t; @@ -82,3 +85,7 @@ void f21(int64x2_t) {} void f22(uint64x2_t) {} // CHECK: 13__Float64x2_t void f23(float64x2_t) {} +// CHECK: 13__Mfloat8x8_t +void f24(mfloat8x8_t) {} +// CHECK: 14__Mfloat8x16_t +void f25(mfloat8x16_t) {} diff --git a/clang/test/CodeGenCXX/aarch64-ms-mangle-mfp8.cpp b/clang/test/CodeGenCXX/aarch64-ms-mangle-mfp8.cpp new file mode 100644 index 0000000000000..b5fd9171ad81a --- /dev/null +++ b/clang/test/CodeGenCXX/aarch64-ms-mangle-mfp8.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple aarch64-windows-msvc -emit-llvm -o - %s | FileCheck %s + +typedef __mfp8 mf8; +typedef __attribute__((neon_vector_type(8))) __mfp8 mf8x8_t; +typedef __attribute__((neon_vector_type(16))) __mfp8 mf8x16_t; + +// CHECK: "?f@@YAXU__mfp8@__clang@@@Z" +void f(mf8 v) {} + +// CHECK: "?f@@YAXT?$__vector@U__mfp8@__clang@@$07@__clang@@@Z" +void f(mf8x8_t v) {} + +// CHECK: "?f@@YAXT?$__vector@U__mfp8@__clang@@$0BA@@__clang@@@Z" +void f(mf8x16_t v) {} diff --git a/clang/test/CodeGenCXX/attr-annotate2.cpp b/clang/test/CodeGenCXX/attr-annotate2.cpp index 1c9c39c9efb83..0b57af1b42a05 100644 --- a/clang/test/CodeGenCXX/attr-annotate2.cpp +++ b/clang/test/CodeGenCXX/attr-annotate2.cpp @@ -4,18 +4,28 @@ // CHECK: @[[STR:.*]] = private unnamed_addr constant [45 x i8] c"_Generic selection expression should be fine\00", section "llvm.metadata" // CHECK-NEXT: @[[FILENAME:.*]] = private unnamed_addr constant {{.*}}, section "llvm.metadata" // CHECK-NEXT: @[[ARGS:.*]] = private unnamed_addr constant { i32 } zeroinitializer, section "llvm.metadata" +// CHECK-NEXT: @[[STR2:.*]] = private unnamed_addr constant [14 x i8] c"void is undef\00", section "llvm.metadata" +// CHECK-NEXT: @[[ARGS3:.*]] = private unnamed_addr constant { i8, i8, i32 } { i8 undef, i8 undef, i32 7 }, section "llvm.metadata" + + // CHECK-LABEL: @_Z1fv( // CHECK-NEXT: entry: // CHECK-NEXT: [[N:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[J:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[K:%.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 10, ptr [[N]], align 4 // CHECK-NEXT: call void @llvm.var.annotation.p0.p0(ptr [[J]], ptr @[[STR]], ptr @[[FILENAME]], i32 {{.*}}, ptr @[[ARGS]]) // CHECK-NEXT: store i32 0, ptr [[J]], align 4 +// CHECK-NEXT: call void @llvm.var.annotation.p0.p0(ptr [[K]], ptr @[[STR2]], ptr @[[FILENAME]], i32 {{.*}}, ptr @[[ARGS3]]) +// CHECK-NEXT: store i32 0, ptr [[K]], align 4 // CHECK-NEXT: ret void // void f() { int n = 10; [[clang::annotate("_Generic selection expression should be fine", _Generic(n, int : 0, default : 1))]] int j = 0; // second arg should resolve to 0 fine + + [[clang::annotate("void is undef", (void)2, (void)4, 7)]] + int k = 0; } diff --git a/clang/test/CodeGenCXX/bitfield-ir.cpp b/clang/test/CodeGenCXX/bitfield-ir.cpp index d91b089d09621..8fc4375a4f414 100644 --- a/clang/test/CodeGenCXX/bitfield-ir.cpp +++ b/clang/test/CodeGenCXX/bitfield-ir.cpp @@ -21,7 +21,7 @@ struct Int { // CHECK-LABEL: define dso_local void @_Z1AP4Tail -// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-SAME: (ptr noundef captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[P]], align 4 // CHECK-NEXT: [[INC:%.*]] = add i16 [[BF_LOAD]], 1 @@ -33,7 +33,7 @@ void A (Tail *p) { } // CHECK-LABEL: define dso_local void @_Z1BP4Tail -// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (ptr noundef captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 2 // CHECK-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[B]], align 2 @@ -46,7 +46,7 @@ void B (Tail *p) { } // CHECK-LABEL: define dso_local void @_Z1AP4Char -// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (ptr noundef captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[P]], align 4 // CHECK-NEXT: [[INC:%.*]] = add i16 [[BF_LOAD]], 1 @@ -58,7 +58,7 @@ void A (Char *p) { } // CHECK-LABEL: define dso_local void @_Z1BP4Char -// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (ptr noundef captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[B:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 2 // CHECK-NEXT: [[BF_LOAD:%.*]] = load i8, ptr [[B]], align 2 @@ -71,7 +71,7 @@ void B (Char *p) { } // CHECK-LABEL: define dso_local void @_Z1AP3Int -// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (ptr noundef captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[P]], align 4 // CHECK-NEXT: [[INC:%.*]] = add i32 [[BF_LOAD]], 1 @@ -86,7 +86,7 @@ void A (Int *p) { } // CHECK-LABEL: define dso_local void @_Z1BP3Int -// CHECK-SAME: (ptr nocapture noundef [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (ptr noundef captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[BF_LOAD:%.*]] = load i32, ptr [[P]], align 4 // CHECK-NEXT: [[BF_VALUE:%.*]] = add i32 [[BF_LOAD]], 65536 diff --git a/clang/test/CodeGenCXX/cxx2c-decomposition.cpp b/clang/test/CodeGenCXX/cxx2c-decomposition.cpp new file mode 100644 index 0000000000000..27562524fd4b0 --- /dev/null +++ b/clang/test/CodeGenCXX/cxx2c-decomposition.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -std=c++26 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s + +namespace std { + using size_t = decltype(sizeof(0)); + template struct tuple_size; + template struct tuple_element; +} + +struct Y { int n; }; +struct X { X(); X(Y); X(const X&); ~X(); }; + +struct A { int a : 13; bool b; }; + +struct B {}; +template<> struct std::tuple_size { enum { value = 2 }; }; +template<> struct std::tuple_element<0,B> { using type = X; }; +template<> struct std::tuple_element<1,B> { using type = const int&; }; +template auto get(B) { + if constexpr (N == 0) + return Y(); + else + return 0.0; +} + +using C = int[2]; + +template T &make(); + +// CHECK-LABEL: define {{.*}} @_Z8big_testIiEiv() +template +int big_test() { + A& a = make(); +A: + auto &[...an] = a; + an...[0] = 5; + // CHECK: %[[a1:.*]].load = load i16, ptr %[[BITFIELD:.*]], + // CHECK: %[[a1]].clear = and i16 %[[a1]].load, -8192 + // CHECK: %[[a1]].set = or i16 %[[a1]].clear, 5 + // CHECK: store i16 %[[a1]].set, ptr %[[BITFIELD]], +B: + auto [b1, ...bn] = make(); + // CHECK: @_Z4makeI1BERT_v() + // CHECK: call i32 @_Z3getILi0EEDa1B() + // CHECK: call void @_ZN1XC1E1Y(ptr {{[^,]*}} %[[b1:.*]], i32 + // + // CHECK: call noundef double @_Z3getILi1EEDa1B() + // CHECK: %[[cvt:.*]] = fptosi double %{{.*}} to i32 + // CHECK: store i32 %[[cvt]], ptr %[[b2:.*]], + // CHECK: store ptr %[[b2]], ptr %[[b2ref:.*]], + int bn2 = bn...[0]; + // CHECK load ptr, ptr %[[b2ref]] + + return 0; +} + +int g = big_test(); diff --git a/clang/test/CodeGenCXX/debug-info-ms-novtable.cpp b/clang/test/CodeGenCXX/debug-info-ms-novtable.cpp new file mode 100644 index 0000000000000..d8800608f8b87 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-ms-novtable.cpp @@ -0,0 +1,16 @@ +// RUN: %clang -g -S -emit-llvm -fms-extensions -fms-compatibility -target x86_64-pc-windows-msvc -o - %s | FileCheck %s + +// CHECK-DAG: ![[FOO:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "Foo", file: !{{[0-9]+}}, line: {{[0-9]+}}, size: 128, flags: DIFlagTypePassByReference | DIFlagNonTrivial, elements: ![[FOO_ELEMENTS:[0-9]+]], vtableHolder: ![[FOO]], identifier: ".?AVFoo@@") +// CHECK-DAG: ![[FOO_ELEMENTS]] = !{![[FOO_VTBL_TY:[0-9]+]], ![[FOO_VTBL_MEMBER:[0-9]+]], ![[FOO_MEMBER:[0-9]+]], ![[FOO_DUMMY:[0-9]+]]} +// CHECK-DAG: ![[FOO_VTBL_TY]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 64) +// CHECK-DAG: ![[FOO_VTBL_MEMBER]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Foo", scope: !10, file: !{{[0-9]+}}, baseType: ![[FOO_VTBL_PTR_TY:[0-9]+]], size: 64, flags: DIFlagArtificial) +// CHECK-DAG: ![[FOO_VTBL_PTR_TY]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[FOO_VTBL_TY]], size: 64) +// CHECK-DAG: ![[FOO_MEMBER]] = !DIDerivedType(tag: DW_TAG_member, name: "member", scope: ![[FOO]], file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: !{{[0-9]+}}, size: 32, offset: 64) +// CHECK-DAG: ![[FOO_DUMMY]] = !DISubprogram(name: "dummy", linkageName: "?dummy@Foo@@EEAAXXZ", scope: ![[FOO]], file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, scopeLine: {{[0-9]+}}, containingType: ![[FOO]], virtualIndex: 0, flags: DIFlagPrototyped | DIFlagIntroducedVirtual, spFlags: DISPFlagVirtual) +class __declspec(novtable) Foo { + virtual void dummy() noexcept {}; + + int member = 1; +}; + +void foo(Foo) {} diff --git a/clang/test/CodeGenCXX/gh119046.cpp b/clang/test/CodeGenCXX/gh119046.cpp new file mode 100644 index 0000000000000..cad76879f0862 --- /dev/null +++ b/clang/test/CodeGenCXX/gh119046.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -std=c++2a -triple x86_64-elf-gnu %s -emit-llvm -o - | FileCheck %s + +struct S { + consteval void operator()() {} +}; + +template +constexpr void dispatch(Fn fn) { + fn(); +} + +template +struct value_visitor { + constexpr void operator()() { visitor(); } + Visitor&& visitor; +}; + +template +constexpr auto make_dispatch() { + return dispatch>; +} + +template +constexpr void visit(Visitor&&) { + make_dispatch(); +} + +void f() { visit(S{}); } + +// CHECK: define {{.*}} @_Z1fv +// CHECK-NOT: define {{.*}} @_Z5visitI1SEvOT_ +// CHECK-NOT: define {{.*}} @_Z13make_dispatchI1SEDav diff --git a/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp b/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp index 855787731c8b0..5f83545f78127 100644 --- a/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp +++ b/clang/test/CodeGenCXX/inline-then-fold-variadics.cpp @@ -101,14 +101,14 @@ extern "C" { typedef uint64_t ulong2 __attribute__((__vector_size__(16), __aligned__(16))); // CHECK-LABEL: define {{[^@]+}}@first_i32_ulong2 -// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[X]] // int first_i32_ulong2(int x, ulong2 *y) { return first(x, *y); } // CHECK-LABEL: define {{[^@]+}}@second_i32_ulong2 -// CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 16)) [[R:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// CHECK-SAME: (i32 noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]], ptr noundef writeonly captures(none) initializes((0, 16)) [[R:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[Y]], align 16, !tbaa [[TBAA2:![0-9]+]] // CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]] @@ -119,7 +119,7 @@ void second_i32_ulong2(int x, ulong2 *y, ulong2 *r) { } // CHECK-LABEL: define {{[^@]+}}@first_ulong2_i32 -// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 16)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-SAME: (ptr noundef readonly captures(none) [[X:%.*]], i32 noundef [[Y:%.*]], ptr noundef writeonly captures(none) initializes((0, 16)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[X]], align 16, !tbaa [[TBAA2]] // CHECK-NEXT: store <2 x i64> [[TMP0]], ptr [[R]], align 16, !tbaa [[TBAA2]] @@ -130,7 +130,7 @@ void first_ulong2_i32(ulong2 *x, int y, ulong2 *r) { } // CHECK-LABEL: define {{[^@]+}}@second_ulong2_i32 -// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (ptr noundef readonly captures(none) [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[Y]] // @@ -150,14 +150,14 @@ typedef struct { extern "C" { // CHECK-LABEL: define {{[^@]+}}@first_i32_asc -// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (i32 noundef returned [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[X]] // int first_i32_asc(int x, asc *y) { return first(x, *y); } // CHECK-LABEL: define {{[^@]+}}@second_i32_asc -// CHECK-SAME: (i32 noundef [[X:%.*]], ptr nocapture noundef readonly [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 24)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-SAME: (i32 noundef [[X:%.*]], ptr noundef readonly captures(none) [[Y:%.*]], ptr noundef writeonly captures(none) initializes((0, 24)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[Y]], i32 24, i1 false) // CHECK-NEXT: ret void @@ -165,7 +165,7 @@ int first_i32_asc(int x, asc *y) { return first(x, *y); } void second_i32_asc(int x, asc *y, asc *r) { *r = second(x, *y); } // CHECK-LABEL: define {{[^@]+}}@first_asc_i32 -// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef [[Y:%.*]], ptr nocapture noundef writeonly initializes((0, 24)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-SAME: (ptr noundef readonly captures(none) [[X:%.*]], i32 noundef [[Y:%.*]], ptr noundef writeonly captures(none) initializes((0, 24)) [[R:%.*]]) local_unnamed_addr #[[ATTR1]] { // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(24) [[R]], ptr noundef nonnull align 1 dereferenceable(24) [[X]], i32 24, i1 false) // CHECK-NEXT: ret void @@ -173,7 +173,7 @@ void second_i32_asc(int x, asc *y, asc *r) { *r = second(x, *y); } void first_asc_i32(asc *x, int y, asc *r) { *r = first(*x, y); } // CHECK-LABEL: define {{[^@]+}}@second_asc_i32 -// CHECK-SAME: (ptr nocapture noundef readonly [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// CHECK-SAME: (ptr noundef readonly captures(none) [[X:%.*]], i32 noundef returned [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: ret i32 [[Y]] // diff --git a/clang/test/CodeGenCXX/mangle-neon-vectors.cpp b/clang/test/CodeGenCXX/mangle-neon-vectors.cpp index cb5e40be6a6df..2139a8ae98caf 100644 --- a/clang/test/CodeGenCXX/mangle-neon-vectors.cpp +++ b/clang/test/CodeGenCXX/mangle-neon-vectors.cpp @@ -9,6 +9,7 @@ typedef __fp16 float16_t; #if defined(__aarch64__) typedef unsigned char poly8_t; typedef unsigned short poly16_t; +typedef __mfp8 mfloat8_t; #else typedef signed char poly8_t; typedef short poly16_t; @@ -29,6 +30,8 @@ typedef __attribute__((neon_vector_type(4))) float16_t float16x4_t; typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t; #ifdef __aarch64__ typedef __attribute__((neon_vector_type(2))) float64_t float64x2_t; +typedef __attribute__((neon_vector_type(8))) mfloat8_t mfloat8x8_t; +typedef __attribute__((neon_vector_type(16))) mfloat8_t mfloat8x16_t; #endif typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t; typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t; @@ -86,3 +89,11 @@ void f11(float64x2_t v) { } // CHECK-AARCH64-BF16: 14__Bfloat16x4_t void f12(bfloat16x4_t v) {} #endif + + +#ifdef __aarch64__ +// CHECK-AARCH64: 13__Mfloat8x8_t +void f13(mfloat8x8_t v) { } +// CHECK-AARCH64: 14__Mfloat8x16_t +void f14(mfloat8x16_t v) { } +#endif diff --git a/clang/test/CodeGenCXX/noescape.cpp b/clang/test/CodeGenCXX/noescape.cpp index e6d7a727ebb36..c3fc90e2ea54d 100644 --- a/clang/test/CodeGenCXX/noescape.cpp +++ b/clang/test/CodeGenCXX/noescape.cpp @@ -8,26 +8,26 @@ struct S { virtual void vm1(int *, int * __attribute__((noescape))); }; -// CHECK: define{{.*}} void @_ZN1SC2EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} nocapture noundef {{%.*}}) -// CHECK: define{{.*}} void @_ZN1SC1EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} nocapture noundef {{%.*}}) {{.*}} { -// CHECK: call void @_ZN1SC2EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) +// CHECK: define{{.*}} void @_ZN1SC2EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{%.*}}) +// CHECK: define{{.*}} void @_ZN1SC1EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{%.*}}) {{.*}} { +// CHECK: call void @_ZN1SC2EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} captures(none) {{.*}}) S::S(int *, int * __attribute__((noescape))) {} -// CHECK: define {{.*}} ptr @_ZN1SaSEPi(ptr {{.*}}, {{.*}} nocapture noundef {{%.*}}) +// CHECK: define {{.*}} ptr @_ZN1SaSEPi(ptr {{.*}}, {{.*}} noundef captures(none) {{%.*}}) S &S::operator=(int * __attribute__((noescape))) { return *this; } -// CHECK: define{{.*}} void @_ZN1S2m0EPiS0_(ptr {{.*}}, {{.*}} nocapture noundef {{%.*}}) +// CHECK: define{{.*}} void @_ZN1S2m0EPiS0_(ptr {{.*}}, {{.*}} noundef captures(none) {{%.*}}) void S::m0(int *, int * __attribute__((noescape))) {} -// CHECK: define{{.*}} void @_ZN1S3vm1EPiS0_(ptr {{.*}}, {{.*}} nocapture noundef {{%.*}}) +// CHECK: define{{.*}} void @_ZN1S3vm1EPiS0_(ptr {{.*}}, {{.*}} noundef captures(none) {{%.*}}) void S::vm1(int *, int * __attribute__((noescape))) {} // CHECK-LABEL: define{{.*}} void @_Z5test0P1SPiS1_( -// CHECK: call void @_ZN1SC1EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} nocapture noundef {{.*}}) -// CHECK: call {{.*}} ptr @_ZN1SaSEPi(ptr {{.*}}, {{.*}} nocapture noundef {{.*}}) -// CHECK: call void @_ZN1S2m0EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} nocapture noundef {{.*}}) -// CHECK: call void {{.*}}(ptr {{.*}}, {{.*}}, {{.*}} nocapture noundef {{.*}}) +// CHECK: call void @_ZN1SC1EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{.*}}) +// CHECK: call {{.*}} ptr @_ZN1SaSEPi(ptr {{.*}}, {{.*}} noundef captures(none) {{.*}}) +// CHECK: call void @_ZN1S2m0EPiS0_(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{.*}}) +// CHECK: call void {{.*}}(ptr {{.*}}, {{.*}}, {{.*}} noundef captures(none) {{.*}}) void test0(S *s, int *p0, int *p1) { S t(p0, p1); t = p1; @@ -39,27 +39,27 @@ namespace std { typedef decltype(sizeof(0)) size_t; } -// CHECK: define {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}}) +// CHECK: define {{.*}} @_ZnwmPv({{.*}}, {{.*}} captures(none) {{.*}}) void *operator new(std::size_t, void * __attribute__((noescape)) p) { return p; } // CHECK-LABEL: define{{.*}} ptr @_Z5test1Pv( -// CHECK: %call = call {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}}) +// CHECK: %call = call {{.*}} @_ZnwmPv({{.*}}, {{.*}} captures(none) {{.*}}) void *test1(void *p0) { return ::operator new(16, p0); } // CHECK-LABEL: define{{.*}} void @_Z5test2PiS_( -// CHECK: call void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) -// CHECK: define internal void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture noundef {{%.*}}) +// CHECK: call void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} captures(none) {{.*}}) +// CHECK: define internal void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} noundef captures(none) {{%.*}}) void test2(int *p0, int *p1) { auto t = [](int *, int * __attribute__((noescape))){}; t(p0, p1); } // CHECK-LABEL: define{{.*}} void @_Z5test3PFvU8noescapePiES_( -// CHECK: call void {{.*}}(ptr nocapture noundef {{.*}}) +// CHECK: call void {{.*}}(ptr noundef captures(none) {{.*}}) typedef void (*NoEscapeFunc)(__attribute__((noescape)) int *); void test3(NoEscapeFunc f, int *p) { diff --git a/clang/test/CodeGenCXX/template-param-objects.cpp b/clang/test/CodeGenCXX/template-param-objects.cpp index 11ebd21521e83..ff6acc438d137 100644 --- a/clang/test/CodeGenCXX/template-param-objects.cpp +++ b/clang/test/CodeGenCXX/template-param-objects.cpp @@ -5,6 +5,9 @@ struct S { char buf[32]; }; template constexpr const char *begin() { return s.buf; } template constexpr const char *end() { return s.buf + __builtin_strlen(s.buf); } +namespace { struct T { char buf[32]; }; } +template constexpr const char* begin_anon() { return t.buf; } + // ITANIUM: [[HELLO:@_ZTAXtl1StlA32_cLc104ELc101ELc108ELc108ELc111ELc32ELc119ELc111ELc114ELc108ELc100EEEE]] // MSABI: [[HELLO:@"[?][?]__N2US@@3D0GI@@0GF@@0GM@@0GM@@0GP@@0CA@@0HH@@0GP@@0HC@@0GM@@0GE@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@0A@@@@@"]] // ITANIUM-SAME: = linkonce_odr constant { <{ [11 x i8], [21 x i8] }> } { <{ [11 x i8], [21 x i8] }> <{ [11 x i8] c"hello world", [21 x i8] zeroinitializer }> }, comdat @@ -19,3 +22,10 @@ const char *p = begin(); // MSABI: @"?q@@3PEBDEB" // CHECK-SAME: global ptr getelementptr (i8, ptr [[HELLO]], i64 11) const char *q = end(); + + +// CHECK: internal constant { <{ [10 x i8], [22 x i8] }> } { <{ [10 x i8], [22 x i8] }> <{ [10 x i8] c"hello anon", [22 x i8] zeroinitializer }> } +// CHECK-NOT: comdat +// ITANIUM: @r +// MSABI: @"?r@@3PEBDEB" +const char *r = begin_anon(); diff --git a/clang/test/CodeGenCXX/wasm-args-returns.cpp b/clang/test/CodeGenCXX/wasm-args-returns.cpp index b57896b0e0ffe..fbb152ac1bb3d 100644 --- a/clang/test/CodeGenCXX/wasm-args-returns.cpp +++ b/clang/test/CodeGenCXX/wasm-args-returns.cpp @@ -30,7 +30,7 @@ struct two_fields { double d, e; }; test(two_fields); -// CHECK: define void @_Z7forward10two_fields(ptr dead_on_unwind noalias nocapture writable writeonly sret(%struct.two_fields) align 8 initializes((0, 16)) %{{.*}}, ptr nocapture readonly byval(%struct.two_fields) align 8 %{{.*}}) +// CHECK: define void @_Z7forward10two_fields(ptr dead_on_unwind noalias writable writeonly sret(%struct.two_fields) align 8 captures(none) initializes((0, 16)) %{{.*}}, ptr readonly byval(%struct.two_fields) align 8 captures(none) %{{.*}}) // // CHECK: define void @_Z15test_two_fieldsv() // CHECK: %[[tmp:.*]] = alloca %struct.two_fields, align 8 diff --git a/clang/test/CodeGenHLSL/BasicFeatures/ArrayElementwiseCast.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/ArrayElementwiseCast.hlsl new file mode 100644 index 0000000000000..18f82bff3b308 --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/ArrayElementwiseCast.hlsl @@ -0,0 +1,144 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s + +// array truncation to a scalar +// CHECK-LABEL: define void {{.*}}call0 +// CHECK: [[A:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[B:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G1]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[B]], align 4 +export void call0() { + int A[2] = {0,1}; + float B = (float)A; +} + +// array truncation +// CHECK-LABEL: define void {{.*}}call1 +// CHECK: [[A:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[B:%.*]] = alloca [1 x i32], align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[B]], ptr align 4 {{.*}}, i32 4, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [1 x i32], ptr [[B]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G2]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 4 +export void call1() { + int A[2] = {0,1}; + int B[1] = {4}; + B = (int[1])A; +} + +// just a cast +// CHECK-LABEL: define void {{.*}}call2 +// CHECK: [[A:%.*]] = alloca [1 x i32], align 4 +// CHECK-NEXT: [[B:%.*]] = alloca [1 x float], align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [1 x i32], align 4 +// CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 4 [[A]], i8 0, i32 4, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[B]], ptr align 4 {{.*}}, i32 4, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 4, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [1 x float], ptr [[B]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [1 x i32], ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G2]], align 4 +// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[L]] to float +// CHECK-NEXT: store float [[C]], ptr [[G1]], align 4 +export void call2() { + int A[1] = {0}; + float B[1] = {1.0}; + B = (float[1])A; +} + +// vector to array +// CHECK-LABEL: define void {{.*}}call3 +// CHECK: [[A:%.*]] = alloca <1 x float>, align 4 +// CHECK-NEXT: [[B:%.*]] = alloca [1 x i32], align 4 +// CHECK-NEXT: store <1 x float> splat (float 0x3FF3333340000000), ptr [[A]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[B]], ptr align 4 {{.*}}, i32 4, i1 false) +// CHECK-NEXT: [[C:%.*]] = load <1 x float>, ptr [[A]], align 4 +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [1 x i32], ptr [[B]], i32 0, i32 0 +// CHECK-NEXT: [[V:%.*]] = extractelement <1 x float> [[C]], i64 0 +// CHECK-NEXT: [[C:%.*]] = fptosi float [[V]] to i32 +// CHECK-NEXT: store i32 [[C]], ptr [[G1]], align 4 +export void call3() { + float1 A = {1.2}; + int B[1] = {1}; + B = (int[1])A; +} + +// flatten array of vector to array with cast +// CHECK-LABEL: define void {{.*}}call5 +// CHECK: [[A:%.*]] = alloca [1 x <2 x float>], align 8 +// CHECK-NEXT: [[B:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [1 x <2 x float>], align 8 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[A]], ptr align 8 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[B]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[Tmp]], ptr align 8 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [2 x i32], ptr [[B]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [2 x i32], ptr [[B]], i32 0, i32 1 +// CHECK-NEXT: [[VG:%.*]] = getelementptr inbounds [1 x <2 x float>], ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[L:%.*]] = load <2 x float>, ptr [[VG]], align 8 +// CHECK-NEXT: [[VL:%.*]] = extractelement <2 x float> [[L]], i32 0 +// CHECK-NEXT: [[C:%.*]] = fptosi float [[VL]] to i32 +// CHECK-NEXT: store i32 [[C]], ptr [[G1]], align 4 +// CHECK-NEXT: [[L4:%.*]] = load <2 x float>, ptr [[VG]], align 8 +// CHECK-NEXT: [[VL5:%.*]] = extractelement <2 x float> [[L4]], i32 1 +// CHECK-NEXT: [[C6:%.*]] = fptosi float [[VL5]] to i32 +// CHECK-NEXT: store i32 [[C6]], ptr [[G2]], align 4 +export void call5() { + float2 A[1] = {{1.2,3.4}}; + int B[2] = {1,2}; + B = (int[2])A; +} + +// flatten 2d array +// CHECK-LABEL: define void {{.*}}call6 +// CHECK: [[A:%.*]] = alloca [2 x [1 x i32]], align 4 +// CHECK-NEXT: [[B:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x [1 x i32]], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[B]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [2 x i32], ptr [[B]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [2 x i32], ptr [[B]], i32 0, i32 1 +// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [2 x [1 x i32]], ptr [[Tmp]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [2 x [1 x i32]], ptr [[Tmp]], i32 0, i32 1, i32 0 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G3]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 4 +// CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[G4]], align 4 +// CHECK-NEXT: store i32 [[L4]], ptr [[G2]], align 4 +export void call6() { + int A[2][1] = {{1},{3}}; + int B[2] = {1,2}; + B = (int[2])A; +} + +struct S { + int X; + float Y; +}; + +// flatten and truncate from a struct +// CHECK-LABEL: define void {{.*}}call7 +// CHECK: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[A:%.*]] = alloca [1 x i32], align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[s]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 4, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[s]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [1 x i32], ptr [[A]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G2]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 4 +export void call7() { + S s = {1, 2.9}; + int A[1] = {1}; + A = (int[1])s; +} + diff --git a/clang/test/CodeGenHLSL/BasicFeatures/StructElementwiseCast.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/StructElementwiseCast.hlsl new file mode 100644 index 0000000000000..26fde37c901dd --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/StructElementwiseCast.hlsl @@ -0,0 +1,140 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +struct S { + int X; + float Y; +}; + +// struct truncation to a scalar +// CHECK-LABEL: define void {{.*}}call0 +// CHECK: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[s]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[s]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G1]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[A]], align 4 +export void call0() { + S s = {1,2}; + int A = (int)s; +} + +// struct from vector +// CHECK-LABEL: define void {{.*}}call1 +// CHECK: [[A:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: store <2 x i32> , ptr [[A]], align 8 +// CHECK-NEXT: [[L:%.*]] = load <2 x i32>, ptr [[A]], align 8 +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 1 +// CHECK-NEXT: [[VL:%.*]] = extractelement <2 x i32> [[L]], i64 0 +// CHECK-NEXT: store i32 [[VL]], ptr [[G1]], align 4 +// CHECK-NEXT: [[VL2:%.*]] = extractelement <2 x i32> [[L]], i64 1 +// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[VL2]] to float +// CHECK-NEXT: store float [[C]], ptr [[G2]], align 4 +export void call1() { + int2 A = {1,2}; + S s = (S)A; +} + + +// struct from array +// CHECK-LABEL: define void {{.*}}call2 +// CHECK: [[A:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 1 +// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G3]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 4 +// CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[G4]], align 4 +// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[L4]] to float +// CHECK-NEXT: store float [[C]], ptr [[G2]], align 4 +export void call2() { + int A[2] = {1,2}; + S s = (S)A; +} + +struct Q { + int Z; +}; + +struct R { + Q q; + float F; +}; + +// struct from nested struct? +// CHECK-LABEL: define void {{.*}}call6 +// CHECK: [[r:%.*]] = alloca %struct.R, align 4 +// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.R, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[r]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[r]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 1 +// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds %struct.R, ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds %struct.R, ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G3]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 4 +// CHECK-NEXT: [[L4:%.*]] = load float, ptr [[G4]], align 4 +// CHECK-NEXT: store float [[L4]], ptr [[G2]], align 4 +export void call6() { + R r = {{1}, 2.0}; + S s = (S)r; +} + +// nested struct from array? +// CHECK-LABEL: define void {{.*}}call7 +// CHECK: [[A:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[r:%.*]] = alloca %struct.R, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.R, ptr [[r]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.R, ptr [[r]], i32 0, i32 1 +// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G4:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G3]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[G1]], align 4 +// CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[G4]], align 4 +// CHECK-NEXT: [[C:%.*]] = sitofp i32 [[L4]] to float +// CHECK-NEXT: store float [[C]], ptr [[G2]], align 4 +export void call7() { + int A[2] = {1,2}; + R r = (R)A; +} + +struct T { + int A; + int B; + int C; +}; + +// struct truncation +// CHECK-LABEL: define void {{.*}}call8 +// CHECK: [[t:%.*]] = alloca %struct.T, align 4 +// CHECK-NEXT: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.T, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[t]], ptr align 4 {{.*}}, i32 12, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[t]], i32 12, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[s]], i32 0, i32 1 +// CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds %struct.T, ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: %gep3 = getelementptr inbounds %struct.T, ptr %agg-temp, i32 0, i32 1 +// CHECK-NEXT: %gep4 = getelementptr inbounds %struct.T, ptr %agg-temp, i32 0, i32 2 +// CHECK-NEXT: %load = load i32, ptr %gep2, align 4 +// CHECK-NEXT: store i32 %load, ptr %gep, align 4 +// CHECK-NEXT: %load5 = load i32, ptr %gep3, align 4 +// CHECK-NEXT: %conv = sitofp i32 %load5 to float +// CHECK-NEXT: store float %conv, ptr %gep1, align 4 +export void call8() { + T t = {1,2,3}; + S s = (S)t; +} diff --git a/clang/test/CodeGenHLSL/BasicFeatures/VectorElementwiseCast.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/VectorElementwiseCast.hlsl new file mode 100644 index 0000000000000..f579dfb377de5 --- /dev/null +++ b/clang/test/CodeGenHLSL/BasicFeatures/VectorElementwiseCast.hlsl @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + +// vector flat cast from array +// CHECK-LABEL: define void {{.*}}call2 +// CHECK: [[A:%.*]] = alloca [2 x [1 x i32]], align 4 +// CHECK-NEXT: [[B:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x [1 x i32]], align 4 +// CHECK-NEXT: [[Tmp2:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [2 x [1 x i32]], ptr [[Tmp]], i32 0, i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [2 x [1 x i32]], ptr [[Tmp]], i32 0, i32 1, i32 0 +// CHECK-NEXT: [[C:%.*]] = load <2 x i32>, ptr [[Tmp2]], align 8 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G1]], align 4 +// CHECK-NEXT: [[D:%.*]] = insertelement <2 x i32> [[C]], i32 [[L]], i64 0 +// CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[G2]], align 4 +// CHECK-NEXT: [[E:%.*]] = insertelement <2 x i32> [[D]], i32 [[L2]], i64 1 +// CHECK-NEXT: store <2 x i32> [[E]], ptr [[B]], align 8 +export void call2() { + int A[2][1] = {{1},{2}}; + int2 B = (int2)A; +} + +struct S { + int X; + float Y; +}; + +// vector flat cast from struct +// CHECK-LABEL: define void {{.*}}call3 +// CHECK: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[A:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[Tmp2:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[s]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[s]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[B:%.*]] = load <2 x i32>, ptr [[Tmp2]], align 8 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G1]], align 4 +// CHECK-NEXT: [[C:%.*]] = insertelement <2 x i32> [[B]], i32 [[L]], i64 0 +// CHECK-NEXT: [[L2:%.*]] = load float, ptr [[G2]], align 4 +// CHECK-NEXT: [[D:%.*]] = fptosi float [[L2]] to i32 +// CHECK-NEXT: [[E:%.*]] = insertelement <2 x i32> [[C]], i32 [[D]], i64 1 +// CHECK-NEXT: store <2 x i32> [[E]], ptr [[A]], align 8 +export void call3() { + S s = {1, 2.0}; + int2 A = (int2)s; +} + +// truncate array to scalar +// CHECK-LABEL: define void {{.*}}call4 +// CHECK: [[A:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: [[B:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca [2 x i32], align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[A]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds [2 x i32], ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G1]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[B]], align 4 +export void call4() { + int A[2] = {1,2}; + int B = (int)A; +} + +// truncate struct to scalar +// CHECK-LABEL: define void {{.*}}call5 +// CHECK: [[s:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[Tmp:%.*]] = alloca %struct.S, align 4 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[s]], ptr align 4 {{.*}}, i32 8, i1 false) +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[Tmp]], ptr align 4 [[s]], i32 8, i1 false) +// CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 0 +// CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds %struct.S, ptr [[Tmp]], i32 0, i32 1 +// CHECK-NEXT: [[L:%.*]] = load i32, ptr [[G1]], align 4 +// CHECK-NEXT: store i32 [[L]], ptr [[A]], align 4 +export void call5() { + S s = {1, 2.0}; + int A = (int)s; +} diff --git a/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl b/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl new file mode 100644 index 0000000000000..e1832bdbbf33f --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/AddUint64.hlsl @@ -0,0 +1,58 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK + + +// CHECK-LABEL: define noundef <2 x i32> @_Z20test_AddUint64_uint2Dv2_jS_( +// CHECK-SAME: <2 x i32> noundef [[A:%.*]], <2 x i32> noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: store <2 x i32> [[A]], ptr [[A_ADDR]], align 8 +// CHECK-NEXT: store <2 x i32> [[B]], ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[LOWA:%.*]] = extractelement <2 x i32> [[TMP0]], i64 0 +// CHECK-NEXT: [[HIGHA:%.*]] = extractelement <2 x i32> [[TMP0]], i64 1 +// CHECK-NEXT: [[LOWB:%.*]] = extractelement <2 x i32> [[TMP1]], i64 0 +// CHECK-NEXT: [[HIGHB:%.*]] = extractelement <2 x i32> [[TMP1]], i64 1 +// CHECK-NEXT: [[TMP2:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[LOWA]], i32 [[LOWB]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0 +// CHECK-NEXT: [[CARRYZEXT:%.*]] = zext i1 [[TMP3]] to i32 +// CHECK-NEXT: [[HIGHSUM:%.*]] = add i32 [[HIGHA]], [[HIGHB]] +// CHECK-NEXT: [[HIGHSUMPLUSCARRY:%.*]] = add i32 [[HIGHSUM]], [[CARRYZEXT]] +// CHECK-NEXT: [[HLSL_ADDUINT64_UPTO0:%.*]] = insertelement <2 x i32> poison, i32 [[TMP4]], i64 0 +// CHECK-NEXT: [[HLSL_ADDUINT64:%.*]] = insertelement <2 x i32> [[HLSL_ADDUINT64_UPTO0]], i32 [[HIGHSUMPLUSCARRY]], i64 1 +// CHECK-NEXT: ret <2 x i32> [[HLSL_ADDUINT64]] +// +uint2 test_AddUint64_uint2(uint2 a, uint2 b) { + return AddUint64(a, b); +} + +// CHECK-LABEL: define noundef <4 x i32> @_Z20test_AddUint64_uint4Dv4_jS_( +// CHECK-SAME: <4 x i32> noundef [[A:%.*]], <4 x i32> noundef [[B:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <4 x i32>, align 16 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <4 x i32>, align 16 +// CHECK-NEXT: store <4 x i32> [[A]], ptr [[A_ADDR]], align 16 +// CHECK-NEXT: store <4 x i32> [[B]], ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[A_ADDR]], align 16 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[LOWA:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[HIGHA:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[LOWB:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[HIGHB:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <2 x i32> +// CHECK-NEXT: [[TMP2:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[LOWA]], <2 x i32> [[LOWB]]) +// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP2]], 1 +// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP2]], 0 +// CHECK-NEXT: [[CARRYZEXT:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32> +// CHECK-NEXT: [[HIGHSUM:%.*]] = add <2 x i32> [[HIGHA]], [[HIGHB]] +// CHECK-NEXT: [[HIGHSUMPLUSCARRY:%.*]] = add <2 x i32> [[HIGHSUM]], [[CARRYZEXT]] +// CHECK-NEXT: [[HLSL_ADDUINT64:%.*]] = shufflevector <2 x i32> [[TMP4]], <2 x i32> [[HIGHSUMPLUSCARRY]], <4 x i32> +// CHECK-NEXT: ret <4 x i32> [[HLSL_ADDUINT64]] +// +uint4 test_AddUint64_uint4(uint4 a, uint4 b) { + return AddUint64(a, b); +} diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl new file mode 100644 index 0000000000000..7891cfc1989af --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveMax.hlsl @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \ +// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \ +// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV + +// Test basic lowering to runtime function call. + +// CHECK-LABEL: test_int +int test_int(int expr) { + // CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.reduce.max.i32([[TY]] %[[#]]) + // CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.reduce.max.i32([[TY]] %[[#]]) + // CHECK: ret [[TY]] %[[RET]] + return WaveActiveMax(expr); +} + +// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.max.i32([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.reduce.max.i32([[TY]]) #[[#attr:]] + +// CHECK-LABEL: test_uint64_t +uint64_t test_uint64_t(uint64_t expr) { + // CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.reduce.umax.i64([[TY]] %[[#]]) + // CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.reduce.umax.i64([[TY]] %[[#]]) + // CHECK: ret [[TY]] %[[RET]] + return WaveActiveMax(expr); +} + +// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.umax.i64([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare spir_func [[TY]] @llvm.spv.wave.reduce.umax.i64([[TY]]) #[[#attr:]] + +// Test basic lowering to runtime function call with array and float value. + +// CHECK-LABEL: test_floatv4 +float4 test_floatv4(float4 expr) { + // CHECK-SPIRV: %[[RET1:.*]] = call reassoc nnan ninf nsz arcp afn spir_func [[TY1:.*]] @llvm.spv.wave.reduce.max.v4f32([[TY1]] %[[#]] + // CHECK-DXIL: %[[RET1:.*]] = call reassoc nnan ninf nsz arcp afn [[TY1:.*]] @llvm.dx.wave.reduce.max.v4f32([[TY1]] %[[#]]) + // CHECK: ret [[TY1]] %[[RET1]] + return WaveActiveMax(expr); +} + +// CHECK-DXIL: declare [[TY1]] @llvm.dx.wave.reduce.max.v4f32([[TY1]]) #[[#attr]] +// CHECK-SPIRV: declare spir_func [[TY1]] @llvm.spv.wave.reduce.max.v4f32([[TY1]]) #[[#attr]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} + diff --git a/clang/test/CodeGenHLSL/builtins/dot-builtin.hlsl b/clang/test/CodeGenHLSL/builtins/dot-builtin.hlsl index 4045169d6516c..36c73f875e944 100644 --- a/clang/test/CodeGenHLSL/builtins/dot-builtin.hlsl +++ b/clang/test/CodeGenHLSL/builtins/dot-builtin.hlsl @@ -6,7 +6,7 @@ // CHECK: %conv2 = fptrunc reassoc nnan ninf nsz arcp afn double %hlsl.dot to float // CHECK: ret float %conv2 float builtin_bool_to_float_type_promotion ( float p0, bool p1 ) { - return __builtin_hlsl_dot ( p0, p1 ); + return __builtin_hlsl_dot ( (double)p0, (double)p1 ); } // CHECK-LABEL: builtin_bool_to_float_arg1_type_promotion @@ -16,7 +16,7 @@ float builtin_bool_to_float_type_promotion ( float p0, bool p1 ) { // CHECK: %conv2 = fptrunc reassoc nnan ninf nsz arcp afn double %hlsl.dot to float // CHECK: ret float %conv2 float builtin_bool_to_float_arg1_type_promotion ( bool p0, float p1 ) { - return __builtin_hlsl_dot ( p0, p1 ); + return __builtin_hlsl_dot ( (double)p0, (double)p1 ); } // CHECK-LABEL: builtin_dot_int_to_float_promotion @@ -26,5 +26,5 @@ float builtin_bool_to_float_arg1_type_promotion ( bool p0, float p1 ) { // CHECK: %conv2 = fptrunc reassoc nnan ninf nsz arcp afn double %hlsl.dot to float // CHECK: ret float %conv2 float builtin_dot_int_to_float_promotion ( float p0, int p1 ) { - return __builtin_hlsl_dot ( p0, p1 ); + return __builtin_hlsl_dot ( (double)p0, (double)p1 ); } diff --git a/clang/test/CodeGenHLSL/cbuf.hlsl b/clang/test/CodeGenHLSL/cbuf.hlsl index 3f9d4514967dd..825e7b8161a60 100644 --- a/clang/test/CodeGenHLSL/cbuf.hlsl +++ b/clang/test/CodeGenHLSL/cbuf.hlsl @@ -1,7 +1,14 @@ -// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ -// RUN: dxil-pc-shadermodel6.3-library %s \ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// CHECK: @a = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @b = external addrspace(2) externally_initialized global double, align 8 +// CHECK: @c = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @d = external addrspace(2) externally_initialized global double, align 8 + // CHECK: @[[CB:.+]] = external constant { float, double } cbuffer A : register(b0, space2) { float a; @@ -15,10 +22,10 @@ tbuffer A : register(t2, space1) { } float foo() { -// CHECK: load float, ptr @[[CB]], align 4 -// CHECK: load double, ptr getelementptr ({ float, double }, ptr @[[CB]], i32 0, i32 1), align 8 -// CHECK: load float, ptr @[[TB]], align 4 -// CHECK: load double, ptr getelementptr ({ float, double }, ptr @[[TB]], i32 0, i32 1), align 8 +// CHECK: load float, ptr addrspace(2) @a, align 4 +// CHECK: load double, ptr addrspace(2) @b, align 8 +// CHECK: load float, ptr addrspace(2) @c, align 4 +// CHECK: load double, ptr addrspace(2) @d, align 8 return a + b + c*d; } diff --git a/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl b/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl index 73dc376942dfb..13c401d428331 100644 --- a/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl +++ b/clang/test/CodeGenHLSL/cbuf_in_namespace.hlsl @@ -1,8 +1,14 @@ -// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \ -// RUN: dxil-pc-shadermodel6.3-library %s \ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s // Make sure cbuffer inside namespace works. + +// CHECK: @_ZN2n02n11aE = external addrspace(2) externally_initialized global float, align 4 +// CHECK: @_ZN2n01bE = external addrspace(2) externally_initialized global float, align 4 + // CHECK: @[[CB:.+]] = external constant { float } // CHECK: @[[TB:.+]] = external constant { float } namespace n0 { @@ -17,7 +23,7 @@ namespace n1 { } float foo() { -// CHECK: load float, ptr @[[CB]], align 4 -// CHECK: load float, ptr @[[TB]], align 4 +// CHECK: load float, ptr addrspace(2) @_ZN2n02n11aE, align 4 +// CHECK: load float, ptr addrspace(2) @_ZN2n01bE, align 4 return n0::n1::a + n0::b; } diff --git a/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl b/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl index ca01960678175..a8ab6ce98ae7e 100644 --- a/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl +++ b/clang/test/CodeGenHLSL/implicit-norecurse-attrib.hlsl @@ -37,7 +37,7 @@ uint Find(Node SortedTree[MAX], uint key) { // Imagine the inout works export bool InitTree(/*inout*/ Node tree[MAX], RWBuffer encodedTree, uint maxDepth) { - uint size = pow(2.f, maxDepth) - 1; + uint size = pow(2.f, (float)maxDepth) - 1; if (size > MAX) return false; for (uint i = 1; i < size; i++) { tree[i].value = encodedTree[i].x; diff --git a/clang/test/CodeGenHLSL/inline-functions.hlsl b/clang/test/CodeGenHLSL/inline-functions.hlsl index fa9c88db26dfc..4748eeee7475f 100644 --- a/clang/test/CodeGenHLSL/inline-functions.hlsl +++ b/clang/test/CodeGenHLSL/inline-functions.hlsl @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,INLINE -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE,OPT_ATTR +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,INLINE,OPT_ATTR +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE,NOOPT_ATTR // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s --check-prefixes=CHECK,NOINLINE -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,INLINE -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O0 -o - | FileCheck %s --check-prefixes=CHECK,INLINE,OPT_ATTR +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute %s -emit-llvm -O1 -o - | FileCheck %s --check-prefixes=CHECK,INLINE,NOOPT_ATTR // Tests that user functions will always be inlined. // This includes exported functions and mangled entry point implementation functions. @@ -43,7 +43,7 @@ void BubbleSort(unsigned Buf[MAX], unsigned size) { // Note ExtAttr is the inlined export set of attribs // CHECK: Function Attrs: alwaysinline -// CHECK: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 %Buf, i32 noundef %size) {{[a-z_ ]*}}[[ExtAttr:\#[0-9]+]] +// CHECK: define noundef i32 @_Z11RemoveDupesA100_jj(ptr {{[a-z_ ]*}}noundef byval([100 x i32]) align 4 {{.*}}%Buf, i32 noundef %size) {{[a-z_ ]*}}[[ExtAttr:\#[0-9]+]] // CHECK: ret i32 // Sort Buf and remove any duplicate values // returns the number of values left @@ -71,7 +71,8 @@ RWBuffer Indices; // NOINLINE: ret void // The unmangled version is not inlined, EntryAttr reflects that -// CHECK: Function Attrs: {{.*}}noinline +// OPT_ATTR: Function Attrs: {{.*}}optnone +// NOOPT_ATTR-NOT: Function Attrs: {{.*}}optnone // CHECK: define void @main() {{[a-z_ ]*}}[[EntryAttr:\#[0-9]+]] // Make sure function calls are inlined when AlwaysInline is run // This only leaves calls to llvm. intrinsics @@ -98,7 +99,8 @@ void main(unsigned int GI : SV_GroupIndex) { // NOINLINE: ret void // The unmangled version is not inlined, EntryAttr reflects that -// CHECK: Function Attrs: {{.*}}noinline +// OPT_ATTR: Function Attrs: {{.*}}optnone +// NOOPT_ATTR-NOT: Function Attrs: {{.*}}optnone // CHECK: define void @main10() {{[a-z_ ]*}}[[EntryAttr]] // Make sure function calls are inlined when AlwaysInline is run // This only leaves calls to llvm. intrinsics diff --git a/clang/test/CodeGenHLSL/resource-bindings.hlsl b/clang/test/CodeGenHLSL/resource-bindings.hlsl index bfa7896bd9811..57e8cc29572b1 100644 --- a/clang/test/CodeGenHLSL/resource-bindings.hlsl +++ b/clang/test/CodeGenHLSL/resource-bindings.hlsl @@ -2,14 +2,17 @@ // CHECK: define internal void @_init_resource_U0S0() // CHECK: %U0S0_h = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_v4f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false) +// CHECK: store target("dx.TypedBuffer", <4 x float>, 1, 0, 0) %U0S0_h, ptr @U0S0, align 4 RWBuffer U0S0 : register(u0); // CHECK: define internal void @_init_resource_U5S3() // CHECK: %U5S3_h = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 3, i32 5, i32 1, i32 0, i1 false) +// CHECK: store target("dx.TypedBuffer", float, 1, 0, 0) %U5S3_h, ptr @U5S3, align 4 RWBuffer U5S3 : register(u5, space3); // CHECK: define internal void @_init_resource_T2S2() // CHECK: %T2S2_h = call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 2, i32 2, i32 1, i32 0, i1 false) +// CHECK: store target("dx.RawBuffer", i32, 0, 0) %T2S2_h, ptr @T2S2, align 4 StructuredBuffer T2S2 : register(t2, space2); struct S { float4 f; @@ -18,6 +21,7 @@ struct S { // CHECK: define internal void @_init_resource_T3S0() // CHECK: %T3S0_h = call target("dx.RawBuffer", %struct.S, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_s_struct.Ss_0_0t(i32 0, i32 3, i32 1, i32 0, i1 false) +// CHECK: store target("dx.RawBuffer", %struct.S, 0, 0) %T3S0_h, ptr @T3S0, align 4 StructuredBuffer T3S0 : register(t3); // CHECK: define void @main() diff --git a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl index f85bab2113170..25f51cce2017d 100644 --- a/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl +++ b/clang/test/CodeGenHLSL/static_global_and_function_in_cb.hlsl @@ -1,16 +1,21 @@ // RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library %s \ // RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s -// CHECK-DAG: @[[CB:.+]] = external constant { float } +// RUN: %clang_cc1 -finclude-default-header -triple spirv-pc-vulkan-library %s \ +// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s cbuffer A { - float a; - // CHECK-DAG:@_ZL1b = internal global float 3.000000e+00, align 4 + // CHECK: @a = external addrspace(2) externally_initialized global float, align 4 + float a; + // CHECK: @_ZL1b = internal global float 3.000000e+00, align 4 static float b = 3; - // CHECK:load float, ptr @[[CB]], align 4 - // CHECK:load float, ptr @_ZL1b, align 4 float foo() { return a + b; } } +// CHECK: @[[CB:.+]] = external constant { float } + +// CHECK:define {{.*}} float @_Z3foov() +// CHECK:load float, ptr addrspace(2) @a, align 4 +// CHECK:load float, ptr @_ZL1b, align 4 float bar() { return foo(); diff --git a/clang/test/CodeGenObjC/noescape.m b/clang/test/CodeGenObjC/noescape.m index 395f110251f3c..e1dbc0eb92e54 100644 --- a/clang/test/CodeGenObjC/noescape.m +++ b/clang/test/CodeGenObjC/noescape.m @@ -26,37 +26,37 @@ // CHECK: @[[BLOCK_DESCIPTOR_TMP_2:.*ls32l8"]] = linkonce_odr hidden unnamed_addr constant { i64, i64, ptr, i64 } { i64 0, i64 40, ptr @{{.*}}, i64 256 }, align 8 // CHECK-LABEL: define{{.*}} void @test0( -// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc0(ptr noundef, {{.*}} nocapture noundef) +// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} captures(none) {{.*}}) +// CHECK: declare void @noescapeFunc0(ptr noundef, {{.*}} noundef captures(none)) void test0(BlockTy b) { noescapeFunc0(0, b); } // CHECK-LABEL: define{{.*}} void @test1( -// CHECK: call void @noescapeFunc1({{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc1({{.*}} nocapture noundef) +// CHECK: call void @noescapeFunc1({{.*}} captures(none) {{.*}}) +// CHECK: declare void @noescapeFunc1({{.*}} noundef captures(none)) void test1(int *i) { noescapeFunc1(i); } // CHECK-LABEL: define{{.*}} void @test2( -// CHECK: call void @noescapeFunc2({{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc2({{.*}} nocapture noundef) +// CHECK: call void @noescapeFunc2({{.*}} captures(none) {{.*}}) +// CHECK: declare void @noescapeFunc2({{.*}} noundef captures(none)) void test2(id i) { noescapeFunc2(i); } // CHECK-LABEL: define{{.*}} void @test3( -// CHECK: call void @noescapeFunc3({{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc3({{.*}} nocapture) +// CHECK: call void @noescapeFunc3({{.*}} captures(none) {{.*}}) +// CHECK: declare void @noescapeFunc3({{.*}} captures(none)) void test3(union U u) { noescapeFunc3(u); } -// CHECK: define internal void @"\01-[C0 m0:]"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) +// CHECK: define internal void @"\01-[C0 m0:]"({{.*}}, {{.*}}, {{.*}} captures(none) {{.*}}) // CHECK-LABEL: define{{.*}} void @test4( -// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}, ptr nocapture {{.*}}) +// CHECK: call void @objc_msgSend(ptr {{.*}}, ptr {{.*}}, ptr noundef captures(none) {{.*}}) @interface C0 -(void) m0:(int*)__attribute__((noescape)) p0; @@ -72,9 +72,9 @@ void test4(C0 *c0, int *p) { } // CHECK-LABEL: define{{.*}} void @test5( -// CHECK: call void {{.*}}(ptr noundef @{{.*}}, ptr nocapture {{.*}}) -// CHECK: call void {{.*}}(ptr {{.*}}, ptr nocapture {{.*}}) -// CHECK: define internal void @{{.*}}(ptr {{.*}}, ptr nocapture {{.*}}) +// CHECK: call void {{.*}}(ptr noundef @{{.*}}, ptr noundef captures(none) {{.*}}) +// CHECK: call void {{.*}}(ptr {{.*}}, ptr noundef captures(none) {{.*}}) +// CHECK: define internal void @{{.*}}(ptr {{.*}}, ptr noundef captures(none) {{.*}}) typedef void (^BlockTy2)(__attribute__((noescape)) int *); diff --git a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl index 35a08a90d8cf9..6776e2227847e 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-abi-struct-coerce.cl @@ -307,7 +307,7 @@ void func_single_struct_element_struct_arg(single_struct_element_struct_arg_t ar // CHECK: void @func_different_size_type_pair_arg(i64 %arg1.coerce0, i32 %arg1.coerce1) void func_different_size_type_pair_arg(different_size_type_pair arg1) { } -// CHECK: void @func_flexible_array_arg(ptr addrspace(5) nocapture noundef readnone byval(%struct.flexible_array) align 4 %arg) +// CHECK: void @func_flexible_array_arg(ptr addrspace(5) noundef readnone byval(%struct.flexible_array) align 4 captures(none) %arg) void func_flexible_array_arg(flexible_array arg) { } // CHECK: define{{.*}} float @func_f32_ret() @@ -402,14 +402,14 @@ struct_arr16 func_ret_struct_arr16() return s; } -// CHECK: define{{.*}} void @func_ret_struct_arr32(ptr addrspace(5) dead_on_unwind noalias nocapture writable writeonly sret(%struct.struct_arr32) align 4 initializes((0, 128)) %agg.result) +// CHECK: define{{.*}} void @func_ret_struct_arr32(ptr addrspace(5) dead_on_unwind noalias writable writeonly sret(%struct.struct_arr32) align 4 captures(none) initializes((0, 128)) %agg.result) struct_arr32 func_ret_struct_arr32() { struct_arr32 s = { 0 }; return s; } -// CHECK: define{{.*}} void @func_ret_struct_arr33(ptr addrspace(5) dead_on_unwind noalias nocapture writable writeonly sret(%struct.struct_arr33) align 4 initializes((0, 132)) %agg.result) +// CHECK: define{{.*}} void @func_ret_struct_arr33(ptr addrspace(5) dead_on_unwind noalias writable writeonly sret(%struct.struct_arr33) align 4 captures(none) initializes((0, 132)) %agg.result) struct_arr33 func_ret_struct_arr33() { struct_arr33 s = { 0 }; @@ -438,7 +438,7 @@ different_size_type_pair func_different_size_type_pair_ret() return s; } -// CHECK: define{{.*}} void @func_flexible_array_ret(ptr addrspace(5) dead_on_unwind noalias nocapture writable writeonly sret(%struct.flexible_array) align 4 initializes((0, 4)) %agg.result) +// CHECK: define{{.*}} void @func_flexible_array_ret(ptr addrspace(5) dead_on_unwind noalias writable writeonly sret(%struct.flexible_array) align 4 captures(none) initializes((0, 4)) %agg.result) flexible_array func_flexible_array_ret() { flexible_array s = { 0 }; @@ -448,11 +448,11 @@ flexible_array func_flexible_array_ret() // CHECK: define{{.*}} void @func_reg_state_lo(<4 x i32> noundef %arg0, <4 x i32> noundef %arg1, <4 x i32> noundef %arg2, i32 noundef %arg3, i32 %s.coerce0, float %s.coerce1, i32 %s.coerce2) void func_reg_state_lo(int4 arg0, int4 arg1, int4 arg2, int arg3, struct_arg_t s) { } -// CHECK: define{{.*}} void @func_reg_state_hi(<4 x i32> noundef %arg0, <4 x i32> noundef %arg1, <4 x i32> noundef %arg2, i32 noundef %arg3, i32 noundef %arg4, ptr addrspace(5) nocapture noundef readnone byref(%struct.struct_arg) align 4 %{{.*}}) +// CHECK: define{{.*}} void @func_reg_state_hi(<4 x i32> noundef %arg0, <4 x i32> noundef %arg1, <4 x i32> noundef %arg2, i32 noundef %arg3, i32 noundef %arg4, ptr addrspace(5) noundef readnone byref(%struct.struct_arg) align 4 captures(none) %{{.*}}) void func_reg_state_hi(int4 arg0, int4 arg1, int4 arg2, int arg3, int arg4, struct_arg_t s) { } // XXX - Why don't the inner structs flatten? -// CHECK: define{{.*}} void @func_reg_state_num_regs_nested_struct(<4 x i32> noundef %arg0, i32 noundef %arg1, i32 %arg2.coerce0, %struct.nested %arg2.coerce1, i32 %arg3.coerce0, %struct.nested %arg3.coerce1, ptr addrspace(5) nocapture noundef readnone byref(%struct.num_regs_nested_struct) align 8 %{{.*}}) +// CHECK: define{{.*}} void @func_reg_state_num_regs_nested_struct(<4 x i32> noundef %arg0, i32 noundef %arg1, i32 %arg2.coerce0, %struct.nested %arg2.coerce1, i32 %arg3.coerce0, %struct.nested %arg3.coerce1, ptr addrspace(5) noundef readnone byref(%struct.num_regs_nested_struct) align 8 captures(none) %{{.*}}) void func_reg_state_num_regs_nested_struct(int4 arg0, int arg1, num_regs_nested_struct arg2, num_regs_nested_struct arg3, num_regs_nested_struct arg4) { } // CHECK: define{{.*}} void @func_double_nested_struct_arg(<4 x i32> noundef %arg0, i32 noundef %arg1, i32 %arg2.coerce0, %struct.double_nested %arg2.coerce1, i16 %arg2.coerce2) @@ -467,7 +467,7 @@ double_nested_struct func_double_nested_struct_ret(int4 arg0, int arg1) { // CHECK: define{{.*}} void @func_large_struct_padding_arg_direct(i8 %arg.coerce0, i32 %arg.coerce1, i8 %arg.coerce2, i32 %arg.coerce3, i8 %arg.coerce4, i8 %arg.coerce5, i16 %arg.coerce6, i16 %arg.coerce7, [3 x i8] %arg.coerce8, i64 %arg.coerce9, i32 %arg.coerce10, i8 %arg.coerce11, i32 %arg.coerce12, i16 %arg.coerce13, i8 %arg.coerce14) void func_large_struct_padding_arg_direct(large_struct_padding arg) { } -// CHECK: define{{.*}} void @func_large_struct_padding_arg_store(ptr addrspace(1) nocapture noundef writeonly initializes((0, 56)) %out, ptr addrspace(5) nocapture noundef readonly byref(%struct.large_struct_padding) align 8 %{{.*}}) +// CHECK: define{{.*}} void @func_large_struct_padding_arg_store(ptr addrspace(1) noundef writeonly captures(none) initializes((0, 56)) %out, ptr addrspace(5) noundef readonly byref(%struct.large_struct_padding) align 8 captures(none) %{{.*}}) void func_large_struct_padding_arg_store(global large_struct_padding* out, large_struct_padding arg) { *out = arg; } @@ -477,7 +477,7 @@ void v3i32_reg_count(int3 arg1, int3 arg2, int3 arg3, int3 arg4, struct_arg_t ar // Function signature from blender, nothing should be passed byval. The v3i32 // should not count as 4 passed registers. -// CHECK: define{{.*}} void @v3i32_pair_reg_count(ptr addrspace(5) nocapture noundef readnone %arg0, <3 x i32> %arg1.coerce0, <3 x i32> %arg1.coerce1, <3 x i32> noundef %arg2, <3 x i32> %arg3.coerce0, <3 x i32> %arg3.coerce1, <3 x i32> noundef %arg4, float noundef %arg5) +// CHECK: define{{.*}} void @v3i32_pair_reg_count(ptr addrspace(5) noundef readnone captures(none) %arg0, <3 x i32> %arg1.coerce0, <3 x i32> %arg1.coerce1, <3 x i32> noundef %arg2, <3 x i32> %arg3.coerce0, <3 x i32> %arg3.coerce1, <3 x i32> noundef %arg4, float noundef %arg5) void v3i32_pair_reg_count(int3_pair *arg0, int3_pair arg1, int3 arg2, int3_pair arg3, int3 arg4, float arg5) { } // Each short4 should fit pack into 2 registers. @@ -485,7 +485,7 @@ void v3i32_pair_reg_count(int3_pair *arg0, int3_pair arg1, int3 arg2, int3_pair void v4i16_reg_count(short4 arg0, short4 arg1, short4 arg2, short4 arg3, short4 arg4, short4 arg5, struct_4regs arg6) { } -// CHECK: define{{.*}} void @v4i16_pair_reg_count_over(<4 x i16> noundef %arg0, <4 x i16> noundef %arg1, <4 x i16> noundef %arg2, <4 x i16> noundef %arg3, <4 x i16> noundef %arg4, <4 x i16> noundef %arg5, <4 x i16> noundef %arg6, ptr addrspace(5) nocapture noundef readnone byref(%struct.struct_4regs) align 4 %{{.*}}) +// CHECK: define{{.*}} void @v4i16_pair_reg_count_over(<4 x i16> noundef %arg0, <4 x i16> noundef %arg1, <4 x i16> noundef %arg2, <4 x i16> noundef %arg3, <4 x i16> noundef %arg4, <4 x i16> noundef %arg5, <4 x i16> noundef %arg6, ptr addrspace(5) noundef readnone byref(%struct.struct_4regs) align 4 captures(none) %{{.*}}) void v4i16_pair_reg_count_over(short4 arg0, short4 arg1, short4 arg2, short4 arg3, short4 arg4, short4 arg5, short4 arg6, struct_4regs arg7) { } @@ -493,7 +493,7 @@ void v4i16_pair_reg_count_over(short4 arg0, short4 arg1, short4 arg2, short4 arg void v3i16_reg_count(short3 arg0, short3 arg1, short3 arg2, short3 arg3, short3 arg4, short3 arg5, struct_4regs arg6) { } -// CHECK: define{{.*}} void @v3i16_reg_count_over(<3 x i16> noundef %arg0, <3 x i16> noundef %arg1, <3 x i16> noundef %arg2, <3 x i16> noundef %arg3, <3 x i16> noundef %arg4, <3 x i16> noundef %arg5, <3 x i16> noundef %arg6, ptr addrspace(5) nocapture noundef readnone byref(%struct.struct_4regs) align 4 %{{.*}}) +// CHECK: define{{.*}} void @v3i16_reg_count_over(<3 x i16> noundef %arg0, <3 x i16> noundef %arg1, <3 x i16> noundef %arg2, <3 x i16> noundef %arg3, <3 x i16> noundef %arg4, <3 x i16> noundef %arg5, <3 x i16> noundef %arg6, ptr addrspace(5) noundef readnone byref(%struct.struct_4regs) align 4 captures(none) %{{.*}}) void v3i16_reg_count_over(short3 arg0, short3 arg1, short3 arg2, short3 arg3, short3 arg4, short3 arg5, short3 arg6, struct_4regs arg7) { } @@ -503,7 +503,7 @@ void v2i16_reg_count(short2 arg0, short2 arg1, short2 arg2, short2 arg3, short2 arg8, short2 arg9, short2 arg10, short2 arg11, struct_4regs arg13) { } -// CHECK: define{{.*}} void @v2i16_reg_count_over(<2 x i16> noundef %arg0, <2 x i16> noundef %arg1, <2 x i16> noundef %arg2, <2 x i16> noundef %arg3, <2 x i16> noundef %arg4, <2 x i16> noundef %arg5, <2 x i16> noundef %arg6, <2 x i16> noundef %arg7, <2 x i16> noundef %arg8, <2 x i16> noundef %arg9, <2 x i16> noundef %arg10, <2 x i16> noundef %arg11, <2 x i16> noundef %arg12, ptr addrspace(5) nocapture noundef readnone byref(%struct.struct_4regs) align 4 %{{.*}}) +// CHECK: define{{.*}} void @v2i16_reg_count_over(<2 x i16> noundef %arg0, <2 x i16> noundef %arg1, <2 x i16> noundef %arg2, <2 x i16> noundef %arg3, <2 x i16> noundef %arg4, <2 x i16> noundef %arg5, <2 x i16> noundef %arg6, <2 x i16> noundef %arg7, <2 x i16> noundef %arg8, <2 x i16> noundef %arg9, <2 x i16> noundef %arg10, <2 x i16> noundef %arg11, <2 x i16> noundef %arg12, ptr addrspace(5) noundef readnone byref(%struct.struct_4regs) align 4 captures(none) %{{.*}}) void v2i16_reg_count_over(short2 arg0, short2 arg1, short2 arg2, short2 arg3, short2 arg4, short2 arg5, short2 arg6, short2 arg7, short2 arg8, short2 arg9, short2 arg10, short2 arg11, @@ -513,7 +513,7 @@ void v2i16_reg_count_over(short2 arg0, short2 arg1, short2 arg2, short2 arg3, void v2i8_reg_count(char2 arg0, char2 arg1, char2 arg2, char2 arg3, char2 arg4, char2 arg5, struct_4regs arg6) { } -// CHECK: define{{.*}} void @v2i8_reg_count_over(<2 x i8> noundef %arg0, <2 x i8> noundef %arg1, <2 x i8> noundef %arg2, <2 x i8> noundef %arg3, <2 x i8> noundef %arg4, <2 x i8> noundef %arg5, i32 noundef %arg6, ptr addrspace(5) nocapture noundef readnone byref(%struct.struct_4regs) align 4 %{{.*}}) +// CHECK: define{{.*}} void @v2i8_reg_count_over(<2 x i8> noundef %arg0, <2 x i8> noundef %arg1, <2 x i8> noundef %arg2, <2 x i8> noundef %arg3, <2 x i8> noundef %arg4, <2 x i8> noundef %arg5, i32 noundef %arg6, ptr addrspace(5) noundef readnone byref(%struct.struct_4regs) align 4 captures(none) %{{.*}}) void v2i8_reg_count_over(char2 arg0, char2 arg1, char2 arg2, char2 arg3, char2 arg4, char2 arg5, int arg6, struct_4regs arg7) { } diff --git a/clang/test/CodeGenOpenCL/amdgpu-call-kernel.cl b/clang/test/CodeGenOpenCL/amdgpu-call-kernel.cl index dfca09d034cdb..70a2185320538 100755 --- a/clang/test/CodeGenOpenCL/amdgpu-call-kernel.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-call-kernel.cl @@ -1,6 +1,6 @@ // REQUIRES: amdgpu-registered-target // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -emit-llvm -o - %s | FileCheck %s -// CHECK: define{{.*}} amdgpu_kernel void @test_call_kernel(ptr addrspace(1) nocapture noundef writeonly align 4 initializes((0, 4)) %out) +// CHECK: define{{.*}} amdgpu_kernel void @test_call_kernel(ptr addrspace(1) noundef writeonly align 4 captures(none) initializes((0, 4)) %out) // CHECK: store i32 4, ptr addrspace(1) %out, align 4 kernel void test_kernel(global int *out) diff --git a/clang/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl b/clang/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl index 5599f4dd50f04..ace34dd0ca6dc 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-enqueue-kernel.cl @@ -651,7 +651,7 @@ kernel void test_target_features_kernel(global int *i) { // // GFX900: Function Attrs: convergent nounwind // GFX900-LABEL: define {{[^@]+}}@__test_block_invoke_3_kernel -// GFX900-SAME: (<{ i32, i32, ptr, ptr addrspace(1), ptr addrspace(1), i64, i8 }> [[TMP0:%.*]], ptr addrspace(3) [[TMP1:%.*]]) #[[ATTR6]] !kernel_arg_addr_space [[META28:![0-9]+]] !kernel_arg_access_qual [[META29:![0-9]+]] !kernel_arg_type [[META30:![0-9]+]] !kernel_arg_base_type [[META30]] !kernel_arg_type_qual [[META31:![0-9]+]] { +// GFX900-SAME: (<{ i32, i32, ptr, ptr addrspace(1), ptr addrspace(1), i64, i8 }> [[TMP0:%.*]], ptr addrspace(3) [[TMP1:%.*]]) #[[ATTR6]] !kernel_arg_addr_space [[META27:![0-9]+]] !kernel_arg_access_qual [[META28:![0-9]+]] !kernel_arg_type [[META29:![0-9]+]] !kernel_arg_base_type [[META29]] !kernel_arg_type_qual [[META30:![0-9]+]] { // GFX900-NEXT: entry: // GFX900-NEXT: [[TMP2:%.*]] = alloca <{ i32, i32, ptr, ptr addrspace(1), ptr addrspace(1), i64, i8 }>, align 8, addrspace(5) // GFX900-NEXT: store <{ i32, i32, ptr, ptr addrspace(1), ptr addrspace(1), i64, i8 }> [[TMP0]], ptr addrspace(5) [[TMP2]], align 8 @@ -688,7 +688,7 @@ kernel void test_target_features_kernel(global int *i) { // // GFX900: Function Attrs: convergent norecurse nounwind // GFX900-LABEL: define {{[^@]+}}@test_target_features_kernel -// GFX900-SAME: (ptr addrspace(1) noundef align 4 [[I:%.*]]) #[[ATTR2]] !kernel_arg_addr_space [[META32:![0-9]+]] !kernel_arg_access_qual [[META23]] !kernel_arg_type [[META33:![0-9]+]] !kernel_arg_base_type [[META33]] !kernel_arg_type_qual [[META25]] { +// GFX900-SAME: (ptr addrspace(1) noundef align 4 [[I:%.*]]) #[[ATTR2]] !kernel_arg_addr_space [[META31:![0-9]+]] !kernel_arg_access_qual [[META23]] !kernel_arg_type [[META32:![0-9]+]] !kernel_arg_base_type [[META32]] !kernel_arg_type_qual [[META25]] { // GFX900-NEXT: entry: // GFX900-NEXT: [[I_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) // GFX900-NEXT: [[DEFAULT_QUEUE:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) @@ -700,7 +700,7 @@ kernel void test_target_features_kernel(global int *i) { // GFX900-NEXT: [[FLAGS_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[FLAGS]] to ptr // GFX900-NEXT: [[NDRANGE_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[NDRANGE]] to ptr // GFX900-NEXT: [[TMP_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[TMP]] to ptr -// GFX900-NEXT: store ptr addrspace(1) [[I]], ptr [[I_ADDR_ASCAST]], align 8, !tbaa [[TBAA34:![0-9]+]] +// GFX900-NEXT: store ptr addrspace(1) [[I]], ptr [[I_ADDR_ASCAST]], align 8, !tbaa [[TBAA33:![0-9]+]] // GFX900-NEXT: call void @llvm.lifetime.start.p5(i64 8, ptr addrspace(5) [[DEFAULT_QUEUE]]) #[[ATTR8]] // GFX900-NEXT: call void @llvm.lifetime.start.p5(i64 4, ptr addrspace(5) [[FLAGS]]) #[[ATTR8]] // GFX900-NEXT: store i32 0, ptr [[FLAGS_ASCAST]], align 4, !tbaa [[TBAA17]] @@ -803,16 +803,15 @@ kernel void test_target_features_kernel(global int *i) { // GFX900: [[META23]] = !{!"none"} // GFX900: [[META24]] = !{!"__block_literal"} // GFX900: [[META25]] = !{!""} -// GFX900: [[TBAA26]] = !{[[META27:![0-9]+]], [[META27]], i64 0} -// GFX900: [[META27]] = !{!"p1 void", [[META9]], i64 0} -// GFX900: [[META28]] = !{i32 0, i32 3} -// GFX900: [[META29]] = !{!"none", !"none"} -// GFX900: [[META30]] = !{!"__block_literal", !"void*"} -// GFX900: [[META31]] = !{!"", !""} -// GFX900: [[META32]] = !{i32 1} -// GFX900: [[META33]] = !{!"int*"} -// GFX900: [[TBAA34]] = !{[[META35:![0-9]+]], [[META35]], i64 0} -// GFX900: [[META35]] = !{!"p1 int", [[META9]], i64 0} +// GFX900: [[TBAA26]] = !{[[META9]], [[META9]], i64 0} +// GFX900: [[META27]] = !{i32 0, i32 3} +// GFX900: [[META28]] = !{!"none", !"none"} +// GFX900: [[META29]] = !{!"__block_literal", !"void*"} +// GFX900: [[META30]] = !{!"", !""} +// GFX900: [[META31]] = !{i32 1} +// GFX900: [[META32]] = !{!"int*"} +// GFX900: [[TBAA33]] = !{[[META34:![0-9]+]], [[META34]], i64 0} +// GFX900: [[META34]] = !{!"p1 int", [[META9]], i64 0} //. //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: // CHECK: {{.*}} diff --git a/clang/test/CodeGenOpenCL/atomic-builtins-default-to-device-scope.cl b/clang/test/CodeGenOpenCL/atomic-builtins-default-to-device-scope.cl index 5af2d807b4189..0cf961fc572b9 100644 --- a/clang/test/CodeGenOpenCL/atomic-builtins-default-to-device-scope.cl +++ b/clang/test/CodeGenOpenCL/atomic-builtins-default-to-device-scope.cl @@ -5,202 +5,202 @@ // RUN: | FileCheck %s --check-prefix=SPIRV // AMDGCN-LABEL: define dso_local i32 @load( -// AMDGCN-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// AMDGCN-SAME: ptr noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = load atomic i32, ptr [[P]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @load( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// SPIRV-SAME: ptr addrspace(4) noundef readonly captures(none) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = load atomic i32, ptr addrspace(4) [[P]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int load(int *p) { return __atomic_load_n(p, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local void @store( -// AMDGCN-SAME: ptr nocapture noundef writeonly [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef writeonly captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: store atomic i32 [[X]], ptr [[P]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret void // // SPIRV-LABEL: define spir_func void @store( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef writeonly [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef writeonly captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: store atomic i32 [[X]], ptr addrspace(4) [[P]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret void // void store(int *p, int x) { return __atomic_store_n(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @add( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw add ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @add( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw add ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int add(int *p, int x) { return __atomic_fetch_add(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local float @fadd( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret float [[TMP0]] // // SPIRV-LABEL: define spir_func float @fadd( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fadd ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret float [[TMP0]] // float fadd(float *p, float x) { return __atomic_fetch_add(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @sub( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw sub ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @sub( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw sub ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int sub(int *p, int x) { return __atomic_fetch_sub(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local float @fsub( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret float [[TMP0]] // // SPIRV-LABEL: define spir_func float @fsub( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fsub ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret float [[TMP0]] // float fsub(float *p, float x) { return __atomic_fetch_sub(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @and( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw and ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @and( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw and ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int and(int *p, int x) { return __atomic_fetch_and(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @nand( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw nand ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @nand( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw nand ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int nand(int *p, int x) { return __atomic_fetch_nand(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @or( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw or ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @or( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw or ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int or(int *p, int x) { return __atomic_fetch_or(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @xor( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw xor ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @xor( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw xor ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int xor(int *p, int x) { return __atomic_fetch_xor(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @min( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw min ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @min( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw min ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int min(int *p, int x) { return __atomic_fetch_min(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local float @fmin( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fmin ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret float [[TMP0]] // // SPIRV-LABEL: define spir_func float @fmin( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fmin ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret float [[TMP0]] // float fmin(float *p, float x) { return __atomic_fetch_min(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @max( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw max ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @max( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw max ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int max(int *p, int x) { return __atomic_fetch_max(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local float @fmax( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw fmax ptr [[P]], float [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret float [[TMP0]] // // SPIRV-LABEL: define spir_func float @fmax( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], float noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw fmax ptr addrspace(4) [[P]], float [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret float [[TMP0]] // float fmax(float *p, float x) { return __atomic_fetch_max(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local i32 @xchg( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = atomicrmw xchg ptr [[P]], i32 [[X]] syncscope("agent") seq_cst, align 4 // AMDGCN-NEXT: ret i32 [[TMP0]] // // SPIRV-LABEL: define spir_func i32 @xchg( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = atomicrmw xchg ptr addrspace(4) [[P]], i32 [[X]] syncscope("device") seq_cst, align 4 // SPIRV-NEXT: ret i32 [[TMP0]] // int xchg(int *p, int x) { return __atomic_exchange_n(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local range(i32 0, 2) i32 @cmpxchg( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = cmpxchg ptr [[P]], i32 [[X]], i32 [[Y]] syncscope("agent") seq_cst seq_cst, align 4 // AMDGCN-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1 @@ -208,7 +208,7 @@ int xchg(int *p, int x) { return __atomic_exchange_n(p, x, __ATOMIC_SEQ_CST); } // AMDGCN-NEXT: ret i32 [[CONV]] // // SPIRV-LABEL: define spir_func range(i32 0, 2) i32 @cmpxchg( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = cmpxchg ptr addrspace(4) [[P]], i32 [[X]], i32 [[Y]] syncscope("device") seq_cst seq_cst, align 4 // SPIRV-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1 @@ -217,7 +217,7 @@ int xchg(int *p, int x) { return __atomic_exchange_n(p, x, __ATOMIC_SEQ_CST); } // int cmpxchg(int *p, int x, int y) { return __atomic_compare_exchange(p, &x, &y, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } // AMDGCN-LABEL: define dso_local range(i32 0, 2) i32 @cmpxchg_weak( -// AMDGCN-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// AMDGCN-SAME: ptr noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // AMDGCN-NEXT: [[ENTRY:.*:]] // AMDGCN-NEXT: [[TMP0:%.*]] = cmpxchg weak ptr [[P]], i32 [[X]], i32 [[Y]] syncscope("agent") seq_cst seq_cst, align 4 // AMDGCN-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1 @@ -225,7 +225,7 @@ int cmpxchg(int *p, int x, int y) { return __atomic_compare_exchange(p, &x, &y, // AMDGCN-NEXT: ret i32 [[CONV]] // // SPIRV-LABEL: define spir_func range(i32 0, 2) i32 @cmpxchg_weak( -// SPIRV-SAME: ptr addrspace(4) nocapture noundef [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// SPIRV-SAME: ptr addrspace(4) noundef captures(none) [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[TMP0:%.*]] = cmpxchg weak ptr addrspace(4) [[P]], i32 [[X]], i32 [[Y]] syncscope("device") seq_cst seq_cst, align 4 // SPIRV-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1 diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11-err.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11-err.cl index 08f70a25276f1..d518fe3a11a81 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11-err.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11-err.cl @@ -2,7 +2,7 @@ // RUN: %clang_cc1 -triple amdgcn-unknown-unknown -target-cpu gfx1100 -verify -emit-llvm -o - %s -void test_s_sleep_var(int d) -{ - __builtin_amdgcn_s_sleep_var(d); // expected-error {{'__builtin_amdgcn_s_sleep_var' needs target feature gfx12-insts}} +void builtin_test_unsupported(int a, int b) { + __builtin_amdgcn_s_sleep_var(a); // expected-error {{'__builtin_amdgcn_s_sleep_var' needs target feature gfx12-insts}} + b = __builtin_amdgcn_ds_bpermute_fi_b32(a, b); // expected-error {{'__builtin_amdgcn_ds_bpermute_fi_b32' needs target feature gfx12-insts}} } diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl index 5b5ae419f0a4a..234ad4fd8cde6 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx12.cl @@ -296,3 +296,26 @@ void test_s_buffer_prefetch_data(__amdgpu_buffer_rsrc_t rsrc, unsigned int len) __builtin_amdgcn_s_buffer_prefetch_data(rsrc, 128, len); __builtin_amdgcn_s_buffer_prefetch_data(rsrc, 0, 31); } + +// CHECK-LABEL: @test_ds_bpermute_fi_b32( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[OUT_ADDR:%.*]] = alloca ptr addrspace(1), align 8, addrspace(5) +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// CHECK-NEXT: [[OUT_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[OUT_ADDR]] to ptr +// CHECK-NEXT: [[A_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[A_ADDR]] to ptr +// CHECK-NEXT: [[B_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[B_ADDR]] to ptr +// CHECK-NEXT: store ptr addrspace(1) [[OUT:%.*]], ptr [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[A:%.*]], ptr [[A_ADDR_ASCAST]], align 4 +// CHECK-NEXT: store i32 [[B:%.*]], ptr [[B_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR_ASCAST]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.amdgcn.ds.bpermute.fi.b32(i32 [[TMP0]], i32 [[TMP1]]) +// CHECK-NEXT: [[TMP3:%.*]] = load ptr addrspace(1), ptr [[OUT_ADDR_ASCAST]], align 8 +// CHECK-NEXT: store i32 [[TMP2]], ptr addrspace(1) [[TMP3]], align 4 +// CHECK-NEXT: ret void +// +void test_ds_bpermute_fi_b32(global int* out, int a, int b) +{ + *out = __builtin_amdgcn_ds_bpermute_fi_b32(a, b); +} diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx950-read-tr.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx950-read-tr.cl index 91e04430d4973..af1f434403767 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx950-read-tr.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn-gfx950-read-tr.cl @@ -8,7 +8,7 @@ typedef half v4h __attribute__((ext_vector_type(4))); typedef __bf16 v4y __attribute__((ext_vector_type(4))); // GFX950-LABEL: define dso_local <2 x i32> @test_amdgcn_ds_read_b64_tr_b4_v2i32( -// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// GFX950-SAME: ptr addrspace(3) noundef readonly captures(none) [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // GFX950-NEXT: entry: // GFX950-NEXT: [[TMP0:%.*]] = tail call <2 x i32> @llvm.amdgcn.ds.read.tr4.b64.v2i32(ptr addrspace(3) [[INPTR]]) // GFX950-NEXT: ret <2 x i32> [[TMP0]] @@ -19,7 +19,7 @@ v2i test_amdgcn_ds_read_b64_tr_b4_v2i32(local v2i* inptr) } // GFX950-LABEL: define dso_local <3 x i32> @test_amdgcn_ds_read_b96_tr_b6_v3i32( -// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// GFX950-SAME: ptr addrspace(3) noundef readonly captures(none) [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0]] { // GFX950-NEXT: entry: // GFX950-NEXT: [[TMP0:%.*]] = tail call <3 x i32> @llvm.amdgcn.ds.read.tr6.b96.v3i32(ptr addrspace(3) [[INPTR]]) // GFX950-NEXT: ret <3 x i32> [[TMP0]] @@ -30,7 +30,7 @@ v3i test_amdgcn_ds_read_b96_tr_b6_v3i32(local v3i* inptr) } // GFX950-LABEL: define dso_local <2 x i32> @test_amdgcn_ds_read_b64_tr_b8_v2i32( -// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// GFX950-SAME: ptr addrspace(3) noundef readonly captures(none) [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0]] { // GFX950-NEXT: entry: // GFX950-NEXT: [[TMP0:%.*]] = tail call <2 x i32> @llvm.amdgcn.ds.read.tr8.b64.v2i32(ptr addrspace(3) [[INPTR]]) // GFX950-NEXT: ret <2 x i32> [[TMP0]] @@ -41,7 +41,7 @@ v2i test_amdgcn_ds_read_b64_tr_b8_v2i32(local v2i* inptr) } // GFX950-LABEL: define dso_local <4 x i16> @test_amdgcn_ds_read_b64_tr_b16_v2i16( -// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// GFX950-SAME: ptr addrspace(3) noundef readonly captures(none) [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0]] { // GFX950-NEXT: entry: // GFX950-NEXT: [[TMP0:%.*]] = tail call <4 x i16> @llvm.amdgcn.ds.read.tr16.b64.v4i16(ptr addrspace(3) [[INPTR]]) // GFX950-NEXT: ret <4 x i16> [[TMP0]] @@ -52,7 +52,7 @@ v4s test_amdgcn_ds_read_b64_tr_b16_v2i16(local v4s* inptr) } // GFX950-LABEL: define dso_local <4 x half> @test_amdgcn_ds_read_b64_tr_b16_v2f16( -// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// GFX950-SAME: ptr addrspace(3) noundef readonly captures(none) [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0]] { // GFX950-NEXT: entry: // GFX950-NEXT: [[TMP0:%.*]] = tail call <4 x half> @llvm.amdgcn.ds.read.tr16.b64.v4f16(ptr addrspace(3) [[INPTR]]) // GFX950-NEXT: ret <4 x half> [[TMP0]] @@ -63,10 +63,11 @@ v4h test_amdgcn_ds_read_b64_tr_b16_v2f16(local v4h* inptr) } // GFX950-LABEL: define dso_local <4 x bfloat> @test_amdgcn_ds_read_b64_tr_b16_v2bf16( -// GFX950-SAME: ptr addrspace(3) nocapture noundef readonly [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// GFX950-SAME: ptr addrspace(3) noundef readonly captures(none) [[INPTR:%.*]]) local_unnamed_addr #[[ATTR0]] { // GFX950-NEXT: entry: // GFX950-NEXT: [[TMP0:%.*]] = tail call <4 x bfloat> @llvm.amdgcn.ds.read.tr16.b64.v4bf16(ptr addrspace(3) [[INPTR]]) // GFX950-NEXT: ret <4 x bfloat> [[TMP0]] +// v4y test_amdgcn_ds_read_b64_tr_b16_v2bf16(local v4y* inptr) { return __builtin_amdgcn_ds_read_tr16_b64_v4bf16(inptr); diff --git a/clang/test/CodeGenOpenCL/kernel-param-alignment.cl b/clang/test/CodeGenOpenCL/kernel-param-alignment.cl index 1bce77043981e..38922dba1ca37 100644 --- a/clang/test/CodeGenOpenCL/kernel-param-alignment.cl +++ b/clang/test/CodeGenOpenCL/kernel-param-alignment.cl @@ -17,10 +17,10 @@ kernel void test( global void *v, global struct packed *p) { // CHECK-LABEL: spir_kernel void @test( -// CHECK-SAME: ptr nocapture noundef readnone align 4 %i32, -// CHECK-SAME: ptr nocapture noundef readnone align 8 %i64, -// CHECK-SAME: ptr nocapture noundef readnone align 16 %v4i32, -// CHECK-SAME: ptr nocapture noundef readnone align 8 %v2f32, -// CHECK-SAME: ptr nocapture noundef readnone %v, -// CHECK-SAME: ptr nocapture noundef readnone align 1 %p) +// CHECK-SAME: ptr noundef readnone align 4 captures(none) %i32, +// CHECK-SAME: ptr noundef readnone align 8 captures(none) %i64, +// CHECK-SAME: ptr noundef readnone align 16 captures(none) %v4i32, +// CHECK-SAME: ptr noundef readnone align 8 captures(none) %v2f32, +// CHECK-SAME: ptr noundef readnone captures(none) %v, +// CHECK-SAME: ptr noundef readnone align 1 captures(none) %p) } diff --git a/clang/test/CodeGenOpenCL/kernels-have-spir-cc-by-default.cl b/clang/test/CodeGenOpenCL/kernels-have-spir-cc-by-default.cl index 2aeeb637795a9..d8b6e13633141 100644 --- a/clang/test/CodeGenOpenCL/kernels-have-spir-cc-by-default.cl +++ b/clang/test/CodeGenOpenCL/kernels-have-spir-cc-by-default.cl @@ -27,16 +27,16 @@ typedef struct test_struct { kernel void test_single(int_single input, global int* output) { // CHECK: spir_kernel // AMDGCN: define{{.*}} amdgpu_kernel void @test_single -// CHECK: ptr nocapture {{.*}} byval(%struct.int_single) -// CHECK: ptr nocapture noundef writeonly align 4 initializes((0, 4)) %output +// CHECK: ptr {{.*}} byval(%struct.int_single) align 4 captures(none) +// CHECK: ptr noundef writeonly align 4 captures(none) initializes((0, 4)) %output output[0] = input.a; } kernel void test_pair(int_pair input, global int* output) { // CHECK: spir_kernel // AMDGCN: define{{.*}} amdgpu_kernel void @test_pair -// CHECK: ptr nocapture {{.*}} byval(%struct.int_pair) -// CHECK: ptr nocapture noundef writeonly align 4 initializes((0, 8)) %output +// CHECK: ptr {{.*}} byval(%struct.int_pair) align 8 captures(none) +// CHECK: ptr noundef writeonly align 4 captures(none) initializes((0, 8)) %output output[0] = (int)input.a; output[1] = (int)input.b; } @@ -44,8 +44,8 @@ kernel void test_pair(int_pair input, global int* output) { kernel void test_kernel(test_struct input, global int* output) { // CHECK: spir_kernel // AMDGCN: define{{.*}} amdgpu_kernel void @test_kernel -// CHECK: ptr nocapture {{.*}} byval(%struct.test_struct) -// CHECK: ptr nocapture noundef writeonly align 4 initializes((0, 32)) %output +// CHECK: ptr {{.*}} byval(%struct.test_struct) align 8 captures(none) +// CHECK: ptr noundef writeonly align 4 captures(none) initializes((0, 32)) %output output[0] = input.elementA; output[1] = input.elementB; output[2] = (int)input.elementC; @@ -59,7 +59,7 @@ kernel void test_kernel(test_struct input, global int* output) { void test_function(int_pair input, global int* output) { // CHECK-NOT: spir_kernel // AMDGCN-NOT: define{{.*}} amdgpu_kernel void @test_function -// CHECK: i64 %input.coerce0, i64 %input.coerce1, ptr nocapture noundef writeonly initializes((0, 8)) %output +// CHECK: i64 %input.coerce0, i64 %input.coerce1, ptr noundef writeonly captures(none) initializes((0, 8)) %output output[0] = (int)input.a; output[1] = (int)input.b; } diff --git a/clang/test/CodeGenOpenCL/preserve_vec3.cl b/clang/test/CodeGenOpenCL/preserve_vec3.cl index 747cc301feff6..49ebae6fc7013 100644 --- a/clang/test/CodeGenOpenCL/preserve_vec3.cl +++ b/clang/test/CodeGenOpenCL/preserve_vec3.cl @@ -9,7 +9,7 @@ typedef float float3 __attribute__((ext_vector_type(3))); typedef float float4 __attribute__((ext_vector_type(4))); // CHECK-LABEL: define dso_local spir_kernel void @foo( -// CHECK-SAME: ptr addrspace(1) nocapture noundef readonly align 16 [[A:%.*]], ptr addrspace(1) nocapture noundef writeonly align 16 initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META3:![0-9]+]] !kernel_arg_access_qual [[META4:![0-9]+]] !kernel_arg_type [[META5:![0-9]+]] !kernel_arg_base_type [[META6:![0-9]+]] !kernel_arg_type_qual [[META7:![0-9]+]] { +// CHECK-SAME: ptr addrspace(1) noundef readonly align 16 captures(none) [[A:%.*]], ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META3:![0-9]+]] !kernel_arg_access_qual [[META4:![0-9]+]] !kernel_arg_type [[META5:![0-9]+]] !kernel_arg_base_type [[META6:![0-9]+]] !kernel_arg_type_qual [[META7:![0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x float>, ptr addrspace(1) [[A]], align 16 // CHECK-NEXT: [[EXTRACTVEC1:%.*]] = shufflevector <4 x float> [[LOADVECN]], <4 x float> poison, <4 x i32> @@ -21,7 +21,7 @@ void kernel foo(global float3 *a, global float3 *b) { } // CHECK-LABEL: define dso_local spir_kernel void @float4_to_float3( -// CHECK-SAME: ptr addrspace(1) nocapture noundef writeonly align 16 initializes((0, 16)) [[A:%.*]], ptr addrspace(1) nocapture noundef readonly align 16 [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META11:![0-9]+]] !kernel_arg_base_type [[META12:![0-9]+]] !kernel_arg_type_qual [[META7]] { +// CHECK-SAME: ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[A:%.*]], ptr addrspace(1) noundef readonly align 16 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META11:![0-9]+]] !kernel_arg_base_type [[META12:![0-9]+]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr addrspace(1) [[B]], align 16, !tbaa [[TBAA8]] // CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x float> [[TMP0]], <4 x float> poison, <4 x i32> @@ -33,7 +33,7 @@ void kernel float4_to_float3(global float3 *a, global float4 *b) { } // CHECK-LABEL: define dso_local spir_kernel void @float3_to_float4( -// CHECK-SAME: ptr addrspace(1) nocapture noundef readonly align 16 [[A:%.*]], ptr addrspace(1) nocapture noundef writeonly align 16 initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META11]] !kernel_arg_base_type [[META12]] !kernel_arg_type_qual [[META7]] { +// CHECK-SAME: ptr addrspace(1) noundef readonly align 16 captures(none) [[A:%.*]], ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META11]] !kernel_arg_base_type [[META12]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x float>, ptr addrspace(1) [[A]], align 16 // CHECK-NEXT: [[ASTYPE:%.*]] = shufflevector <4 x float> [[LOADVECN]], <4 x float> poison, <4 x i32> @@ -45,7 +45,7 @@ void kernel float3_to_float4(global float3 *a, global float4 *b) { } // CHECK-LABEL: define dso_local spir_kernel void @float3_to_double2( -// CHECK-SAME: ptr addrspace(1) nocapture noundef readonly align 16 [[A:%.*]], ptr addrspace(1) nocapture noundef writeonly align 16 initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META13:![0-9]+]] !kernel_arg_base_type [[META14:![0-9]+]] !kernel_arg_type_qual [[META7]] { +// CHECK-SAME: ptr addrspace(1) noundef readonly align 16 captures(none) [[A:%.*]], ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META13:![0-9]+]] !kernel_arg_base_type [[META14:![0-9]+]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x float>, ptr addrspace(1) [[A]], align 16 // CHECK-NEXT: [[TMP0:%.*]] = shufflevector <4 x float> [[LOADVECN]], <4 x float> poison, <4 x i32> @@ -57,7 +57,7 @@ void kernel float3_to_double2(global float3 *a, global double2 *b) { } // CHECK-LABEL: define dso_local spir_kernel void @char8_to_short3( -// CHECK-SAME: ptr addrspace(1) nocapture noundef writeonly align 8 initializes((0, 8)) [[A:%.*]], ptr addrspace(1) nocapture noundef readonly align 8 [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META15:![0-9]+]] !kernel_arg_base_type [[META16:![0-9]+]] !kernel_arg_type_qual [[META7]] { +// CHECK-SAME: ptr addrspace(1) noundef writeonly align 8 captures(none) initializes((0, 8)) [[A:%.*]], ptr addrspace(1) noundef readonly align 8 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META3]] !kernel_arg_access_qual [[META4]] !kernel_arg_type [[META15:![0-9]+]] !kernel_arg_base_type [[META16:![0-9]+]] !kernel_arg_type_qual [[META7]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = load <4 x i16>, ptr addrspace(1) [[B]], align 8, !tbaa [[TBAA8]] // CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> @@ -69,7 +69,7 @@ void kernel char8_to_short3(global short3 *a, global char8 *b) { } // CHECK-LABEL: define dso_local spir_func void @from_char3( -// CHECK-SAME: <3 x i8> noundef [[A:%.*]], ptr addrspace(1) nocapture noundef writeonly initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { +// CHECK-SAME: <3 x i8> noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i8> [[A]], <3 x i8> poison, <4 x i32> // CHECK-NEXT: store <4 x i8> [[EXTRACTVEC]], ptr addrspace(1) [[OUT]], align 4, !tbaa [[TBAA17:![0-9]+]] @@ -80,7 +80,7 @@ void from_char3(char3 a, global int *out) { } // CHECK-LABEL: define dso_local spir_func void @from_short3( -// CHECK-SAME: <3 x i16> noundef [[A:%.*]], ptr addrspace(1) nocapture noundef writeonly initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-SAME: <3 x i16> noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i16> [[A]], <3 x i16> poison, <4 x i32> // CHECK-NEXT: store <4 x i16> [[EXTRACTVEC]], ptr addrspace(1) [[OUT]], align 8, !tbaa [[TBAA19:![0-9]+]] @@ -91,7 +91,7 @@ void from_short3(short3 a, global long *out) { } // CHECK-LABEL: define dso_local spir_func void @scalar_to_char3( -// CHECK-SAME: i32 noundef [[A:%.*]], ptr addrspace(1) nocapture noundef writeonly initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-SAME: i32 noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[A]] to <4 x i8> // CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> poison, <4 x i32> @@ -103,7 +103,7 @@ void scalar_to_char3(int a, global char3 *out) { } // CHECK-LABEL: define dso_local spir_func void @scalar_to_short3( -// CHECK-SAME: i64 noundef [[A:%.*]], ptr addrspace(1) nocapture noundef writeonly initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] { +// CHECK-SAME: i64 noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR1]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[A]] to <4 x i16> // CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> diff --git a/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp b/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp index 697e50e199a04..8d8f0b0b5d699 100644 --- a/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp +++ b/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp @@ -2,7 +2,7 @@ //RUN: %clang_cc1 %s -triple spir -emit-llvm -O1 -o - | FileCheck %s // CHECK-LABEL: define dso_local spir_kernel void @test( -// CHECK-SAME: ptr addrspace(1) nocapture noundef readonly align 8 [[IN:%.*]], ptr addrspace(1) nocapture noundef writeonly align 8 initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META4:![0-9]+]] !kernel_arg_access_qual [[META5:![0-9]+]] !kernel_arg_type [[META6:![0-9]+]] !kernel_arg_base_type [[META6]] !kernel_arg_type_qual [[META7:![0-9]+]] { +// CHECK-SAME: ptr addrspace(1) noundef readonly align 8 captures(none) [[IN:%.*]], ptr addrspace(1) noundef writeonly align 8 captures(none) initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META4:![0-9]+]] !kernel_arg_access_qual [[META5:![0-9]+]] !kernel_arg_type [[META6:![0-9]+]] !kernel_arg_base_type [[META6]] !kernel_arg_type_qual [[META7:![0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[IN]], i32 8 // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr addrspace(1) [[ARRAYIDX1]], align 8, !tbaa [[TBAA8:![0-9]+]] diff --git a/clang/test/Driver/Xarch.c b/clang/test/Driver/Xarch.c index f7693fb689d58..95bd0c502ddb3 100644 --- a/clang/test/Driver/Xarch.c +++ b/clang/test/Driver/Xarch.c @@ -1,8 +1,13 @@ // RUN: %clang -target i386-apple-darwin11 -m32 -Xarch_i386 -O3 %s -S -### 2>&1 | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -target x86_64-unknown-linux-gnu -Xarch_x86_64 -O3 %s -S -### 2>&1 | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -target x86_64-unknown-windows-msvc -Xarch_x86_64 -O3 %s -S -### 2>&1 | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -target aarch64-unknown-linux-gnu -Xarch_aarch64 -O3 %s -S -### 2>&1 | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -target powerpc64le-unknown-linux-gnu -Xarch_powerpc64le -O3 %s -S -### 2>&1 | FileCheck -check-prefix=O3ONCE %s // O3ONCE: "-O3" // O3ONCE-NOT: "-O3" // RUN: %clang -target i386-apple-darwin11 -m64 -Xarch_i386 -O3 %s -S -### 2>&1 | FileCheck -check-prefix=O3NONE %s +// RUN: %clang -target x86_64-unknown-linux-gnu -m64 -Xarch_i386 -O3 %s -S -### 2>&1 | FileCheck -check-prefix=O3NONE %s // O3NONE-NOT: "-O3" // O3NONE: argument unused during compilation: '-Xarch_i386 -O3' @@ -10,3 +15,10 @@ // INVALID: error: invalid Xarch argument: '-Xarch_i386 -o' // INVALID: error: invalid Xarch argument: '-Xarch_i386 -S' // INVALID: error: invalid Xarch argument: '-Xarch_i386 -o' + +// RUN: %clang -target x86_64-unknown-linux-gnu -Xarch_x86_64 -Wl,foo %s -### 2>&1 | FileCheck -check-prefix=LINKER %s +// LINKER: "foo" + +// RUN: %clang -target x86_64-unknown-linux-gnu -Xarch_x86_64 -O1 %s -S -### 2>&1 | FileCheck -check-prefix=O1ONCE %s +// O1ONCE: "-O1" +// O1ONCE-NOT: "-O1" diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index d036189e61498..1d2993f4c60c4 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -64,22 +64,31 @@ //// The only branch protection option compatible with PAuthABI is BTI. // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR4 +// RUN: FileCheck %s --check-prefix=ERR4_1 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR4 -// ERR4: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest' +// RUN: FileCheck %s --check-prefix=ERR4_1 +// RUN: not %clang -### -c --target=aarch64 -fptrauth-returns -mbranch-protection=pac-ret %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR4_2 +// ERR4_1: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest' +// ERR4_2: error: the combination of '-mbranch-protection=pac-ret' and '-fptrauth-returns' is incompatible // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=gcs %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR5 +// RUN: FileCheck %s --check-prefix=ERR5_1 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=gcs %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR5 -// ERR5: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest' +// RUN: FileCheck %s --check-prefix=ERR5_1 +// RUN: not %clang -### -c --target=aarch64 -fptrauth-returns -mbranch-protection=gcs %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR5_2 +// ERR5_1: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest' +// ERR5_2: error: the combination of '-mbranch-protection=gcs' and '-fptrauth-returns' is incompatible // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=standard %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR6 +// RUN: FileCheck %s --check-prefix=ERR6_1 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=standard %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR6 -// ERR6: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest' +// RUN: FileCheck %s --check-prefix=ERR6_1 +// RUN: not %clang -### -c --target=aarch64 -fptrauth-returns -mbranch-protection=standard %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR6_2 +// ERR6_1: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest' +// ERR6_2: error: the combination of '-mbranch-protection=standard' and '-fptrauth-returns' is incompatible // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=all %s 2>&1 | \ // RUN: FileCheck %s --check-prefix=ERR7 diff --git a/clang/test/Driver/amdgpu-openmp-sanitize-options.c b/clang/test/Driver/amdgpu-openmp-sanitize-options.c new file mode 100644 index 0000000000000..c28a758bfc0c5 --- /dev/null +++ b/clang/test/Driver/amdgpu-openmp-sanitize-options.c @@ -0,0 +1,65 @@ +// REQUIRES: x86-registered-target, amdgpu-registered-target + +// Fail on invalid ROCm Path. +// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fgpu-sanitize -nogpuinc --rocm-path=%S/Inputs/rocm-invalid %s 2>&1 \ +// RUN: | FileCheck --check-prefix=FAIL %s + +// Enable multiple sanitizer's apart from ASan with invalid rocm-path. +// RUN: not %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fsanitize=leak -fgpu-sanitize --rocm-path=%S/Inputs/rocm-invalid -nogpuinc %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=NOTSUPPORTED,FAIL %s + +// Memory, Leak, UndefinedBehaviour and Thread Sanitizer are not supported on AMDGPU. +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fsanitize=leak -fgpu-sanitize --rocm-path=%S/Inputs/rocm -nogpuinc %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NOTSUPPORTED %s + +// GPU ASan Enabled Test Cases +// ASan enabled for amdgpu-arch [gfx908] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908 -fsanitize=address -fgpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOXNACK,GPUSAN %s + +// GPU ASan enabled for amdgpu-arch [gfx908:xnack-] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack- -fsanitize=address -fgpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=XNACKNEG,GPUSAN %s + +// GPU ASan enabled for amdgpu-arch [gfx908:xnack+] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fgpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=GPUSAN %s + +// ASan enabled for multiple amdgpu-arch [gfx908:xnack+,gfx900:xnack+] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ --offload-arch=gfx900:xnack+ -fsanitize=address -fgpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=GPUSAN %s + +// GPU ASan Disabled Test Cases +// ASan disabled for amdgpu-arch [gfx908] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908 -fsanitize=address -fno-gpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOGPUSAN %s + +// GPU ASan disabled for amdgpu-arch [gfx908:xnack-] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack- -fsanitize=address -fno-gpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOGPUSAN %s + +// GPU ASan disabled for amdgpu-arch [gfx908:xnack+] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ -fsanitize=address -fno-gpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOGPUSAN %s + +// ASan disabled for amdgpu-arch [gfx908:xnack+,gfx900:xnack+] +// RUN: %clang -no-canonical-prefixes -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp --offload-arch=gfx908:xnack+ --offload-arch=gfx900:xnack+ -fsanitize=address -fno-gpu-sanitize --rocm-path=%S/Inputs/rocm %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=NOGPUSAN %s + +// FAIL-DAG: error: cannot find ROCm device library for ABI version 5; provide its path via '--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build without ROCm device library +// NOTSUPPORTED-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa' + +// NOXNACK: warning: ignoring '-fsanitize=address' option for offload arch 'gfx908' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead +// XNACKNEG: warning: ignoring '-fsanitize=address' option for offload arch 'gfx908:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead + +// GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "-fopenmp-targets=amdgcn-amd-amdhsa".* "-x" "c".*}} +// GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-fsanitize=address".* "-x" "c".*}} +// GPUSAN: {{"[^"]*clang-offload-packager[^"]*" "-o".* "--image=file=.*.bc,triple=amdgcn-amd-amdhsa,arch=gfx908(:xnack\-|:xnack\+)?,kind=openmp(,feature=(\-xnack|\+xnack))?"}} +// GPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "-fopenmp-targets=amdgcn-amd-amdhsa".* "-x" "ir".*}} +// GPUSAN: {{"[^"]*clang-linker-wrapper[^"]*".* "--host-triple=x86_64-unknown-linux-gnu".* "--linker-path=[^"]*".* "--whole-archive" "[^"]*(libclang_rt.asan_static.a|libclang_rt.asan_static-x86_64.a)".* "--whole-archive" "[^"]*(libclang_rt.asan.a|libclang_rt.asan-x86_64.a)".*}} + +// NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "-fopenmp-targets=amdgcn-amd-amdhsa".* "-x" "c".*}} +// NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "amdgcn-amd-amdhsa" "-aux-triple" "x86_64-unknown-linux-gnu".* "-emit-llvm-bc".* "-target-cpu" "(gfx908|gfx900)".* "-fopenmp".* "-x" "c".*}} +// NOGPUSAN: {{"[^"]*clang-offload-packager[^"]*" "-o".* "--image=file=.*.bc,triple=amdgcn-amd-amdhsa,arch=gfx908(:xnack\-|:xnack\+)?,kind=openmp(,feature=(\-xnack|\+xnack))?"}} +// NOGPUSAN: {{"[^"]*clang[^"]*" "-cc1" "-triple" "x86_64-unknown-linux-gnu".* "-fopenmp".* "-fsanitize=address".* "-fopenmp-targets=amdgcn-amd-amdhsa".* "-x" "ir".*}} +// NOGPUSAN: {{"[^"]*clang-linker-wrapper[^"]*".* "--host-triple=x86_64-unknown-linux-gnu".* "--linker-path=[^"]*".* "--whole-archive" "[^"]*(libclang_rt.asan_static.a|libclang_rt.asan_static-x86_64.a)".* "--whole-archive" "[^"]*(libclang_rt.asan.a|libclang_rt.asan-x86_64.a)".*}} diff --git a/clang/test/Driver/amdgpu-openmp-system-arch-fail.c b/clang/test/Driver/amdgpu-openmp-system-arch-fail.c index b7e1d0b2c5665..eb037183b4c3c 100644 --- a/clang/test/Driver/amdgpu-openmp-system-arch-fail.c +++ b/clang/test/Driver/amdgpu-openmp-system-arch-fail.c @@ -12,9 +12,9 @@ // case when amdgpu_arch returns nothing or fails // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp -fopenmp-targets=amdgcn-amd-amdhsa -nogpulib --amdgpu-arch-tool=%t/amdgpu_arch_fail %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=NO-OUTPUT-ERROR -// NO-OUTPUT-ERROR: error: cannot determine amdgcn architecture{{.*}}; consider passing it via '-march' +// NO-OUTPUT-ERROR: error: cannot determine amdgcn architecture{{.*}}; consider passing it via '--offload-arch' // case when amdgpu_arch does not return anything with successful execution // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp -fopenmp-targets=amdgcn-amd-amdhsa -nogpulib --amdgpu-arch-tool=%t/amdgpu_arch_empty %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=EMPTY-OUTPUT -// EMPTY-OUTPUT: error: cannot determine amdgcn architecture: No AMD GPU detected in the system; consider passing it via '-march' +// EMPTY-OUTPUT: error: cannot determine amdgcn architecture: No AMD GPU detected in the system; consider passing it via '--offload-arch' diff --git a/clang/test/Driver/amdgpu-openmp-toolchain.c b/clang/test/Driver/amdgpu-openmp-toolchain.c index 1c2ee26173139..b3784537cb836 100644 --- a/clang/test/Driver/amdgpu-openmp-toolchain.c +++ b/clang/test/Driver/amdgpu-openmp-toolchain.c @@ -16,12 +16,12 @@ // CHECK-PHASES: 0: input, "[[INPUT:.+]]", c, (host-openmp) // CHECK-PHASES: 1: preprocessor, {0}, cpp-output, (host-openmp) // CHECK-PHASES: 2: compiler, {1}, ir, (host-openmp) -// CHECK-PHASES: 3: input, "[[INPUT]]", c, (device-openmp) -// CHECK-PHASES: 4: preprocessor, {3}, cpp-output, (device-openmp) -// CHECK-PHASES: 5: compiler, {4}, ir, (device-openmp) -// CHECK-PHASES: 6: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (amdgcn-amd-amdhsa)" {5}, ir -// CHECK-PHASES: 7: backend, {6}, ir, (device-openmp) -// CHECK-PHASES: 8: offload, "device-openmp (amdgcn-amd-amdhsa)" {7}, ir +// CHECK-PHASES: 3: input, "[[INPUT]]", c, (device-openmp, gfx906) +// CHECK-PHASES: 4: preprocessor, {3}, cpp-output, (device-openmp, gfx906) +// CHECK-PHASES: 5: compiler, {4}, ir, (device-openmp, gfx906) +// CHECK-PHASES: 6: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (amdgcn-amd-amdhsa:gfx906)" {5}, ir +// CHECK-PHASES: 7: backend, {6}, ir, (device-openmp, gfx906) +// CHECK-PHASES: 8: offload, "device-openmp (amdgcn-amd-amdhsa:gfx906)" {7}, ir // CHECK-PHASES: 9: clang-offload-packager, {8}, image, (device-openmp) // CHECK-PHASES: 10: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (x86_64-unknown-linux-gnu)" {9}, ir // CHECK-PHASES: 11: backend, {10}, assembler, (host-openmp) @@ -72,7 +72,7 @@ // RUN: %clang -### -target x86_64-pc-linux-gnu -fopenmp --offload-arch=gfx90a \ // RUN: -O3 -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-OPT -// CHECK-OPT: clang-linker-wrapper{{.*}}"--opt-level=O3" +// CHECK-OPT: clang-linker-wrapper{{.*}}"--device-compiler=amdgcn-amd-amdhsa=-O3" // RUN: %clang -### --target=x86_64-unknown-linux-gnu -emit-llvm -S -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-WARN-ATOMIC // CHECK-WARN-ATOMIC-NOT: "-cc1" "-triple" "x86_64-unknown-linux-gnu"{{.*}}"-Werror=atomic-alignment" @@ -84,4 +84,4 @@ // RUN: %clang -### -target x86_64-pc-linux-gnu -nogpulib -fopenmp --offload-arch=gfx90a \ // RUN: -ftime-report %s 2>&1 | FileCheck %s --check-prefix=CHECK-TIME-REPORT -// CHECK-TIME-REPORT: clang-linker-wrapper{{.*}}"--device-compiler=-ftime-report" +// CHECK-TIME-REPORT: clang-linker-wrapper{{.*}}"--device-compiler=amdgcn-amd-amdhsa=-ftime-report" diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 29a0fcbc17ac6..9f9ca1bf1a8fd 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -738,9 +738,13 @@ // RUN: -fno-modules-search-all \ // RUN: -fimplicit-modules \ // RUN: -fno-implicit-modules \ +// RUN: -fstrict-overflow \ +// RUN: -fno-strict-overflow \ // RUN: -ftrivial-auto-var-init=zero \ // RUN: -fwrapv \ // RUN: -fno-wrapv \ +// RUN: -fwrapv-pointer \ +// RUN: -fno-wrapv-pointer \ // RUN: --version \ // RUN: -Werror /Zs -- %s 2>&1 diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index 38f25898c9556..7454ce3d30f5f 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -45,6 +45,13 @@ // CHECK-UNROLL-LOOPS: "-funroll-loops" // CHECK-NO-UNROLL-LOOPS: "-fno-unroll-loops" +// RUN: %clang -### -S -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-INTERCHANGE-LOOPS %s +// RUN: %clang -### -S -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-INTERCHANGE-LOOPS %s +// RUN: %clang -### -S -fno-loop-interchange -floop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-INTERCHANGE-LOOPS %s +// RUN: %clang -### -S -floop-interchange -fno-loop-interchange %s 2>&1 | FileCheck -check-prefix=CHECK-NO-INTERCHANGE-LOOPS %s +// CHECK-INTERCHANGE-LOOPS: "-floop-interchange" +// CHECK-NO-INTERCHANGE-LOOPS: "-fno-loop-interchange" + // RUN: %clang -### -S -fprofile-sample-accurate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-SAMPLE-ACCURATE %s // CHECK-PROFILE-SAMPLE-ACCURATE: "-fprofile-sample-accurate" diff --git a/clang/test/Driver/clang_wrapv_opts.c b/clang/test/Driver/clang_wrapv_opts.c index 826468e0678d0..295d8deb0d99d 100644 --- a/clang/test/Driver/clang_wrapv_opts.c +++ b/clang/test/Driver/clang_wrapv_opts.c @@ -1,11 +1,20 @@ -// RUN: %clang -### -S -fwrapv -fno-wrapv -fwrapv %s 2>&1 | FileCheck -check-prefix=CHECK1 %s -// CHECK1: -fwrapv -// -// RUN: %clang -### -S -fstrict-overflow -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK2 %s -// CHECK2: -fwrapv -// -// RUN: %clang -### -S -fwrapv -fstrict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK3 %s -// CHECK3: -fwrapv -// -// RUN: %clang -### -S -fno-wrapv -fno-strict-overflow %s 2>&1 | FileCheck -check-prefix=CHECK4 %s -// CHECK4-NOT: -fwrapv +// RUN: %clang -### -S -fwrapv -fno-wrapv -fwrapv -Werror %s 2>&1 | FileCheck -check-prefix=CHECK1 %s +// CHECK1: "-fwrapv" + +// RUN: %clang -### -S -fwrapv-pointer -fno-wrapv-pointer -fwrapv-pointer -Werror %s 2>&1 | FileCheck -check-prefix=CHECK1-POINTER %s +// CHECK1-POINTER: "-fwrapv-pointer" + +// RUN: %clang -### -S -fstrict-overflow -fno-strict-overflow -Werror %s 2>&1 | FileCheck -check-prefix=CHECK2 %s +// CHECK2: "-fwrapv"{{.*}}"-fwrapv-pointer" + +// RUN: %clang -### -S -fwrapv -fstrict-overflow -Werror -Werror %s 2>&1 | FileCheck -check-prefix=CHECK3 %s --implicit-check-not="-fwrapv-pointer" +// CHECK3-NOT: "-fwrapv" + +// RUN: %clang -### -S -fwrapv-pointer -fstrict-overflow -Werror %s 2>&1 | FileCheck -check-prefix=CHECK3-POINTER %s --implicit-check-not="-fwrapv" +// CHECK3-POINTER-NOT: "-fwrapv-pointer" + +// RUN: %clang -### -S -fno-wrapv -fno-strict-overflow -fno-wrapv-pointer -Werror %s 2>&1 | FileCheck -check-prefix=CHECK4 %s --implicit-check-not="-fwrapv-pointer" +// CHECK4: "-fwrapv" + +// RUN: %clang -### -S -fno-wrapv-pointer -fno-strict-overflow -fno-wrapv -Werror %s 2>&1 | FileCheck -check-prefix=CHECK4-POINTER %s --implicit-check-not="-fwrapv" +// CHECK4-POINTER: "-fwrapv-pointer" diff --git a/clang/test/Driver/csky-toolchain.c b/clang/test/Driver/csky-toolchain.c index 66485464652ac..638ce64ec98cd 100644 --- a/clang/test/Driver/csky-toolchain.c +++ b/clang/test/Driver/csky-toolchain.c @@ -3,6 +3,7 @@ // RUN: %clang -### %s --target=csky 2>&1 | FileCheck -check-prefix=CC1 %s // CC1: "-cc1" "-triple" "csky" +// CC1: "-fno-signed-char" // In the below tests, --rtlib=platform is used so that the driver ignores // the configure-time CLANG_DEFAULT_RTLIB option when choosing the runtime lib diff --git a/clang/test/Driver/cuda-cross-compiling.c b/clang/test/Driver/cuda-cross-compiling.c index 7817e462c47be..1df231ecb4479 100644 --- a/clang/test/Driver/cuda-cross-compiling.c +++ b/clang/test/Driver/cuda-cross-compiling.c @@ -57,19 +57,6 @@ // LINK: clang-nvlink-wrapper{{.*}}"-o" "a.out" "-arch" "sm_61"{{.*}}[[CUBIN:.+]].o -// -// Test to ensure that we enable handling global constructors in a freestanding -// Nvidia compilation. -// -// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_70 %s -### 2>&1 \ -// RUN: | FileCheck -check-prefix=LOWERING %s -// RUN: %clang -target nvptx64-nvidia-cuda -march=sm_70 -flto -c %s -### 2>&1 \ -// RUN: | FileCheck -check-prefix=LOWERING-LTO %s - -// LOWERING: -cc1" "-triple" "nvptx64-nvidia-cuda" {{.*}} "-mllvm" "--nvptx-lower-global-ctor-dtor" -// LOWERING: clang-nvlink-wrapper{{.*}} "-mllvm" "--nvptx-lower-global-ctor-dtor" -// LOWERING-LTO-NOT: "--nvptx-lower-global-ctor-dtor" - // // Test passing arguments directly to nvlink. // diff --git a/clang/test/Driver/dep-file-flag-with-multiple-offload-archs.hip b/clang/test/Driver/dep-file-flag-with-multiple-offload-archs.hip new file mode 100644 index 0000000000000..f17e56acfb7f7 --- /dev/null +++ b/clang/test/Driver/dep-file-flag-with-multiple-offload-archs.hip @@ -0,0 +1,12 @@ +// RUN: %clang -### -nogpuinc -nogpulib --offload-arch=gfx1030 --offload-arch=gfx1100 --offload-arch=gfx1101 --target=x86_64-linux-gnu -MD -MF tmp.d %s 2>&1 | FileCheck %s + +// CHECK-NOT: {{.*}}clang{{.*}}"-target-cpu" "gfx1030"{{.*}}"-dependency-file" "tmp.d" +// CHECK: {{.*}}lld{{.*}}"-plugin-opt=mcpu=gfx1030" +// CHECK-NOT: {{.*}}clang{{.*}}"-target-cpu" "gfx1100"{{.*}}"-dependency-file" "tmp.d" +// CHECK: {{.*}}lld{{.*}}"-plugin-opt=mcpu=gfx1100" +// CHECK-NOT: {{.*}}clang{{.*}}"-target-cpu" "gfx1101"{{.*}}"-dependency-file" "tmp.d" +// CHECK: {{.*}}lld{{.*}}"-plugin-opt=mcpu=gfx1101" +// CHECK: {{.*}}clang-offload-bundler +// CHECK: {{.*}}clang{{.*}}"-target-cpu"{{.*}}"-dependency-file" "tmp.d" + +void main(){} diff --git a/clang/test/Driver/extend-variable-liveness.c b/clang/test/Driver/extend-variable-liveness.c new file mode 100644 index 0000000000000..bbfb2ece6f297 --- /dev/null +++ b/clang/test/Driver/extend-variable-liveness.c @@ -0,0 +1,14 @@ +// Tests that -fextend-variable-liveness and its aliases are correctly passed +// by the driver. + +// RUN: %clang -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,DEFAULT +// RUN: %clang -fextend-variable-liveness=none -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,NONE +// RUN: %clang -fextend-variable-liveness=this -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,THIS +// RUN: %clang -fextend-variable-liveness=all -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,ALL +// RUN: %clang -fextend-variable-liveness -### -c %s 2>&1 | FileCheck %s --check-prefixes=CHECK,ALL + +// CHECK: "-cc1" +// DEFAULT-NOT: -fextend-variable-liveness +// NONE-SAME: "-fextend-variable-liveness=none" +// THIS-SAME: "-fextend-variable-liveness=this" +// ALL-SAME: "-fextend-variable-liveness=all" diff --git a/clang/test/Driver/fprofile-continuous.c b/clang/test/Driver/fprofile-continuous.c new file mode 100644 index 0000000000000..81719fb70cb1e --- /dev/null +++ b/clang/test/Driver/fprofile-continuous.c @@ -0,0 +1,21 @@ +// 1) test on platforms that (do or do not) require runtime relocation + +// RUN: %clang --target=x86_64-darwin -fprofile-generate -fprofile-continuous -### -c %s 2>&1 | FileCheck %s --check-prefix=NO_RELOC +// NO_RELOC: "-cc1" {{.*}} "-fprofile-continuous" +// NO_RELOC-NOT: "-mllvm" "-runtime-counter-relocation" + +// RUN: %clang --target=powerpc64-ibm-aix -fprofile-generate -fprofile-continuous -### -c %s 2>&1 | FileCheck %s --check-prefix=RELOC +// RUN: %clang --target=x86_64-unknown-fuchsia -fprofile-generate -fprofile-continuous -### -c %s 2>&1 | FileCheck %s --check-prefix=RELOC +// RELOC: "-cc1" {{.*}} "-fprofile-continuous" "-mllvm" "-runtime-counter-relocation" + +// 2) test -fprofile-continuous with cs-profile-generate and -fprofile-instr-generate + +// RUN: %clang --target=powerpc-ibm-aix -fprofile-instr-generate -fprofile-continuous -### -c %s 2>&1 | FileCheck %s --check-prefix=CLANG_PGO +// RUN: %clang --target=powerpc64le-unknown-linux -fprofile-instr-generate= -fprofile-continuous -### -c %s 2>&1 | FileCheck %s --check-prefix=CLANG_PGO +// CLANG_PGO: "-cc1" {{.*}} "-fprofile-continuous" "-mllvm" "-runtime-counter-relocation" "-fprofile-instrument-path=default.profraw" + +// RUN: %clang --target=x86_64-unknown-fuchsia -fcs-profile-generate -fprofile-continuous -### -c %s 2>&1 | FileCheck %s --check-prefix=RELOC + +// RUN: not %clang -fprofile-continuous -### -c %s 2>&1 | FileCheck %s --check-prefix=ERROR +// ERROR: error: invalid argument '-fprofile-continuous' only allowed with '-fprofile-generate, -fprofile-instr-generate, or -fcs-profile-generate' +void foo(){} diff --git a/clang/test/Driver/frelaxed-template-template-args.cpp b/clang/test/Driver/frelaxed-template-template-args.cpp deleted file mode 100644 index 7a7fd6f0bbc8f..0000000000000 --- a/clang/test/Driver/frelaxed-template-template-args.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang -fsyntax-only -### %s 2>&1 | FileCheck --check-prefix=CHECK-DEF %s -// RUN: %clang -fsyntax-only -frelaxed-template-template-args %s 2>&1 | FileCheck --check-prefix=CHECK-ON %s -// RUN: %clang -fsyntax-only -fno-relaxed-template-template-args %s 2>&1 | FileCheck --check-prefix=CHECK-OFF %s -// RUN: %clang -fsyntax-only -fno-relaxed-template-template-args -Wno-deprecated-no-relaxed-template-template-args %s 2>&1 | FileCheck --check-prefix=CHECK-DIS --allow-empty %s - -// CHECK-DEF-NOT: "-cc1"{{.*}} "-fno-relaxed-template-template-args" -// CHECK-ON: warning: argument '-frelaxed-template-template-args' is deprecated [-Wdeprecated] -// CHECK-OFF: warning: argument '-fno-relaxed-template-template-args' is deprecated [-Wdeprecated-no-relaxed-template-template-args] -// CHECK-DIS-NOT: warning: argument '-fno-relaxed-template-template-args' is deprecated diff --git a/clang/test/Driver/hexagon-cpu-default.c b/clang/test/Driver/hexagon-cpu-default.c new file mode 100644 index 0000000000000..31fb839f21656 --- /dev/null +++ b/clang/test/Driver/hexagon-cpu-default.c @@ -0,0 +1,4 @@ +// CHECK: "-target-cpu" "hexagonv68" + +// RUN: %clang -c %s -### --target=hexagon-unknown-elf \ +// RUN: 2>&1 | FileCheck %s diff --git a/clang/test/Driver/hip-sanitize-options.hip b/clang/test/Driver/hip-sanitize-options.hip index d94cbdacdaeb3..8a852867f5b3b 100644 --- a/clang/test/Driver/hip-sanitize-options.hip +++ b/clang/test/Driver/hip-sanitize-options.hip @@ -1,5 +1,5 @@ // RUN: %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \ -// RUN: -fsanitize=address \ +// RUN: -fsanitize=address -fgpu-sanitize \ // RUN: -nogpuinc --rocm-path=%S/Inputs/rocm \ // RUN: %s 2>&1 | FileCheck -check-prefixes=NORDC %s @@ -18,7 +18,7 @@ // RUN: -nogpuinc --rocm-path=%S/Inputs/rocm \ // RUN: %s 2>&1 | FileCheck -check-prefixes=RDC %s -// RUN: not %clang -### --target=x86_64-unknown-linux-gnu --offload-arch=gfx900:xnack+ \ +// RUN: not %clang -### --target=x86_64-unknown-linux-gnu -mcode-object-version=5 --offload-arch=gfx900:xnack+ \ // RUN: -fsanitize=address -fgpu-sanitize \ // RUN: -nogpuinc --rocm-path=%S/Inputs/rocm-invalid \ // RUN: %s 2>&1 | FileCheck -check-prefixes=FAIL %s @@ -52,15 +52,15 @@ // CHECK-NOT: {{"[^"]*lld(\.exe){0,1}".* ".*hip.bc"}} // CHECK: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}} -// NORDC: {{"[^"]*clang[^"]*".* "-emit-obj".* "-fcuda-is-device".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-mlink-builtin-bitcode" ".*hip.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.o]]" +// NORDC: {{"[^"]*clang[^"]*".* "-emit-obj".* "-fcuda-is-device".* "-mlink-builtin-bitcode" ".*hip.bc".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.o]]" // NORDC-NOT: {{"[^"]*lld(\.exe){0,1}".*}} "[[OUT]]" {{".*asanrtl.bc" ".*hip.bc"}} // NORDC: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}} // RDC: {{"[^"]*clang[^"]*".* "-triple" "x86_64-unknown-linux-gnu".* "-fsanitize=address"}} -// RDC: {{"[^"]*clang[^"]*".* "-emit-llvm-bc".* "-fcuda-is-device".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-mlink-builtin-bitcode" ".*hip.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.bc]]" +// RDC: {{"[^"]*clang[^"]*".* "-emit-llvm-bc".* "-fcuda-is-device".* "-mlink-builtin-bitcode" ".*hip.bc".* "-mlink-bitcode-file" ".*asanrtl.bc".* "-fsanitize=address".*}} "-o" "[[OUT:[^"]*.bc]]" // RDC-NOT: {{"[^"]*lld(\.exe){0,1}".*}} "[[OUT]]" {{".*asanrtl.bc" ".*hip.bc"}} -// FAIL: AMDGPU address sanitizer runtime library (asanrtl) is not found. Please install ROCm device library which supports address sanitizer +// FAIL: error: cannot find ROCm device library for ABI version 5; provide its path via '--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build without ROCm device library // XNACK-DAG: warning: ignoring '-fsanitize=leak' option as it is not currently supported for target 'amdgcn-amd-amdhsa' // XNACK-DAG: warning: ignoring '-fsanitize=address' option for offload arch 'gfx900:xnack-' as it is not currently supported there. Use it with an offload arch containing 'xnack+' instead diff --git a/clang/test/Driver/linker-wrapper-image.c b/clang/test/Driver/linker-wrapper-image.c index 7f96f629e9127..775385137c75f 100644 --- a/clang/test/Driver/linker-wrapper-image.c +++ b/clang/test/Driver/linker-wrapper-image.c @@ -14,18 +14,18 @@ // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-windows-gnu \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefixes=OPENMP,OPENMP-COFF -// OPENMP-ELF: @__start_omp_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry] -// OPENMP-ELF-NEXT: @__stop_omp_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry] -// OPENMP-ELF-NEXT: @__dummy.omp_offloading_entries = internal constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries" +// OPENMP-ELF: @__start_llvm_offload_entries = external hidden constant [0 x %struct.__tgt_offload_entry] +// OPENMP-ELF-NEXT: @__stop_llvm_offload_entries = external hidden constant [0 x %struct.__tgt_offload_entry] +// OPENMP-ELF-NEXT: @__dummy.llvm_offload_entries = internal constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries" -// OPENMP-COFF: @__start_omp_offloading_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OA" -// OPENMP-COFF-NEXT: @__stop_omp_offloading_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OZ" +// OPENMP-COFF: @__start_llvm_offload_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries$OA" +// OPENMP-COFF-NEXT: @__stop_llvm_offload_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries$OZ" // OPENMP-REL: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading.relocatable", align 8 // OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading", align 8 -// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr getelementptr ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }] -// OPENMP-NEXT: @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries } +// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr getelementptr ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 0, i64 144), ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries }] +// OPENMP-NEXT: @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_llvm_offload_entries, ptr @__stop_llvm_offload_entries } // OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 101, ptr @.omp_offloading.descriptor_reg, ptr null }] // OPENMP: define internal void @.omp_offloading.descriptor_reg() section ".text.startup" { @@ -51,12 +51,12 @@ // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-windows-gnu \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefixes=CUDA,CUDA-COFF -// CUDA-ELF: @__start_cuda_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry] -// CUDA-ELF-NEXT: @__stop_cuda_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry] -// CUDA-ELF-NEXT: @__dummy.cuda_offloading_entries = internal constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "cuda_offloading_entries" +// CUDA-ELF: @__start_llvm_offload_entries = external hidden constant [0 x %struct.__tgt_offload_entry] +// CUDA-ELF-NEXT: @__stop_llvm_offload_entries = external hidden constant [0 x %struct.__tgt_offload_entry] +// CUDA-ELF-NEXT: @__dummy.llvm_offload_entries = internal constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries" -// CUDA-COFF: @__start_cuda_offloading_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "cuda_offloading_entries$OA" -// CUDA-COFF-NEXT: @__stop_cuda_offloading_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "cuda_offloading_entries$OZ" +// CUDA-COFF: @__start_llvm_offload_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries$OA" +// CUDA-COFF-NEXT: @__stop_llvm_offload_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries$OZ" // CUDA: @.fatbin_image = internal constant [0 x i8] zeroinitializer, section ".nv_fatbin" // CUDA-NEXT: @.fatbin_wrapper = internal constant %fatbin_wrapper { i32 1180844977, i32 1, ptr @.fatbin_image, ptr null }, section ".nvFatBinSegment", align 8 @@ -73,45 +73,54 @@ // CUDA-NEXT: %1 = call i32 @atexit(ptr @.cuda.fatbin_unreg) // CUDA-NEXT: ret void // CUDA-NEXT: } - +// // CUDA: define internal void @.cuda.fatbin_unreg() section ".text.startup" { // CUDA-NEXT: entry: // CUDA-NEXT: %0 = load ptr, ptr @.cuda.binary_handle, align 8 // CUDA-NEXT: call void @__cudaUnregisterFatBinary(ptr %0) // CUDA-NEXT: ret void // CUDA-NEXT: } - +// // CUDA: define internal void @.cuda.globals_reg(ptr %0) section ".text.startup" { // CUDA-NEXT: entry: -// CUDA-NEXT: %1 = icmp ne ptr @__start_cuda_offloading_entries, @__stop_cuda_offloading_entries +// CUDA-NEXT: %1 = icmp ne ptr @__start_llvm_offload_entries, @__stop_llvm_offload_entries // CUDA-NEXT: br i1 %1, label %while.entry, label %while.end - +// // CUDA: while.entry: -// CUDA-NEXT: %entry1 = phi ptr [ @__start_cuda_offloading_entries, %entry ], [ %13, %if.end ] -// CUDA-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 0 +// CUDA-NEXT: %entry1 = phi ptr [ @__start_llvm_offload_entries, %entry ], [ %16, %if.end ] +// CUDA-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 4 // CUDA-NEXT: %addr = load ptr, ptr %2, align 8 -// CUDA-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 1 -// CUDA-NEXT: %name = load ptr, ptr %3, align 8 -// CUDA-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 2 -// CUDA-NEXT: %size = load i64, ptr %4, align 4 -// CUDA-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 3 -// CUDA-NEXT: %flags = load i32, ptr %5, align 4 -// CUDA-NEXT: %6 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 4 -// CUDA-NEXT: %textype = load i32, ptr %6, align 4 +// CUDA-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 8 +// CUDA-NEXT: %aux_addr = load ptr, ptr %3, align 8 +// CUDA-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 2 +// CUDA-NEXT: %kind = load i16, ptr %4, align 2 +// CUDA-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 5 +// CUDA-NEXT: %name = load ptr, ptr %5, align 8 +// CUDA-NEXT: %6 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 6 +// CUDA-NEXT: %size = load i64, ptr %6, align 4 +// CUDA-NEXT: %7 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 3 +// CUDA-NEXT: %flags = load i32, ptr %7, align 4 +// CUDA-NEXT: %8 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 7 +// CUDA-NEXT: %data = load i64, ptr %8, align 4 +// CUDA-NEXT: %9 = trunc i64 %data to i32 // CUDA-NEXT: %type = and i32 %flags, 7 -// CUDA-NEXT: %7 = and i32 %flags, 8 -// CUDA-NEXT: %extern = lshr i32 %7, 3 -// CUDA-NEXT: %8 = and i32 %flags, 16 -// CUDA-NEXT: %constant = lshr i32 %8, 4 -// CUDA-NEXT: %9 = and i32 %flags, 32 -// CUDA-NEXT: %normalized = lshr i32 %9, 5 -// CUDA-NEXT: %10 = icmp eq i64 %size, 0 -// CUDA-NEXT: br i1 %10, label %if.then, label %if.else - +// CUDA-NEXT: %10 = and i32 %flags, 8 +// CUDA-NEXT: %extern = lshr i32 %10, 3 +// CUDA-NEXT: %11 = and i32 %flags, 16 +// CUDA-NEXT: %constant = lshr i32 %11, 4 +// CUDA-NEXT: %12 = and i32 %flags, 32 +// CUDA-NEXT: %normalized = lshr i32 %12, 5 +// CUDA-NEXT: %13 = icmp eq i16 %kind, 2 +// CUDA-NEXT: br i1 %13, label %if.kind, label %if.end +// +// CUDA: if.kind: +// CUDA-NEXT: %14 = icmp eq i64 %size, 0 +// CUDA-NEXT: br i1 %14, label %if.then, label %if.else +// // CUDA: if.then: -// CUDA-NEXT: %11 = call i32 @__cudaRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null) +// CUDA-NEXT: %15 = call i32 @__cudaRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null) // CUDA-NEXT: br label %if.end - +// // CUDA: if.else: // CUDA-NEXT: switch i32 %type, label %if.end [ // CUDA-NEXT: i32 0, label %sw.global @@ -119,29 +128,26 @@ // CUDA-NEXT: i32 2, label %sw.surface // CUDA-NEXT: i32 3, label %sw.texture // CUDA-NEXT: ] - +// // CUDA: sw.global: // CUDA-NEXT: call void @__cudaRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %extern, i64 %size, i32 %constant, i32 0) // CUDA-NEXT: br label %if.end - +// // CUDA: sw.managed: -// CUDA-NEXT: %managed.addr = load ptr, ptr %addr, align 8 -// CUDA-NEXT: %12 = getelementptr inbounds ptr, ptr %addr, i64 1 -// CUDA-NEXT: %managed.addr2 = load ptr, ptr %12, align 8 -// CUDA-NEXT: call void @__cudaRegisterManagedVar(ptr %0, ptr %managed.addr, ptr %managed.addr2, ptr %name, i64 %size, i32 %textype) -// CUDA-NEXT: br label %if.end - +// CUDA-NEXT: call void @__cudaRegisterManagedVar(ptr %0, ptr %aux_addr, ptr %addr, ptr %name, i64 %size, i32 %9) +// CUDA-NEXT: br label %if.end +// // CUDA: sw.surface: // CUDA-NEXT: br label %if.end - +// // CUDA: sw.texture: // CUDA-NEXT: br label %if.end - +// // CUDA: if.end: -// CUDA-NEXT: %13 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1 -// CUDA-NEXT: %14 = icmp eq ptr %13, @__stop_cuda_offloading_entries -// CUDA-NEXT: br i1 %14, label %while.end, label %while.entry - +// CUDA-NEXT: %16 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1 +// CUDA-NEXT: %17 = icmp eq ptr %16, @__stop_llvm_offload_entries +// CUDA-NEXT: br i1 %17, label %while.end, label %while.entry +// // CUDA: while.end: // CUDA-NEXT: ret void // CUDA-NEXT: } @@ -156,12 +162,12 @@ // RUN: clang-linker-wrapper --print-wrapped-module --dry-run --host-triple=x86_64-unknown-windows-gnu \ // RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefixes=HIP,HIP-COFF -// HIP-ELF: @__start_hip_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry] -// HIP-ELF-NEXT: @__stop_hip_offloading_entries = external hidden constant [0 x %struct.__tgt_offload_entry] -// HIP-ELF-NEXT: @__dummy.hip_offloading_entries = internal constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "hip_offloading_entries" +// HIP-ELF: @__start_llvm_offload_entries = external hidden constant [0 x %struct.__tgt_offload_entry] +// HIP-ELF-NEXT: @__stop_llvm_offload_entries = external hidden constant [0 x %struct.__tgt_offload_entry] +// HIP-ELF-NEXT: @__dummy.llvm_offload_entries = internal constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries" -// HIP-COFF: @__start_hip_offloading_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "hip_offloading_entries$OA" -// HIP-COFF-NEXT: @__stop_hip_offloading_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "hip_offloading_entries$OZ" +// HIP-COFF: @__start_llvm_offload_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries$OA" +// HIP-COFF-NEXT: @__stop_llvm_offload_entries = weak_odr hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "llvm_offload_entries$OZ" // HIP: @.fatbin_image = internal constant [0 x i8] zeroinitializer, section ".hip_fatbin" // HIP-NEXT: @.fatbin_wrapper = internal constant %fatbin_wrapper { i32 1212764230, i32 1, ptr @.fatbin_image, ptr null }, section ".hipFatBinSegment", align 8 @@ -177,45 +183,54 @@ // HIP-NEXT: %1 = call i32 @atexit(ptr @.hip.fatbin_unreg) // HIP-NEXT: ret void // HIP-NEXT: } - +// // HIP: define internal void @.hip.fatbin_unreg() section ".text.startup" { // HIP-NEXT: entry: // HIP-NEXT: %0 = load ptr, ptr @.hip.binary_handle, align 8 // HIP-NEXT: call void @__hipUnregisterFatBinary(ptr %0) // HIP-NEXT: ret void // HIP-NEXT: } - +// // HIP: define internal void @.hip.globals_reg(ptr %0) section ".text.startup" { // HIP-NEXT: entry: -// HIP-NEXT: %1 = icmp ne ptr @__start_hip_offloading_entries, @__stop_hip_offloading_entries +// HIP-NEXT: %1 = icmp ne ptr @__start_llvm_offload_entries, @__stop_llvm_offload_entries // HIP-NEXT: br i1 %1, label %while.entry, label %while.end - +// // HIP: while.entry: -// HIP-NEXT: %entry1 = phi ptr [ @__start_hip_offloading_entries, %entry ], [ %13, %if.end ] -// HIP-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 0 +// HIP-NEXT: %entry1 = phi ptr [ @__start_llvm_offload_entries, %entry ], [ %16, %if.end ] +// HIP-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 4 // HIP-NEXT: %addr = load ptr, ptr %2, align 8 -// HIP-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 1 -// HIP-NEXT: %name = load ptr, ptr %3, align 8 -// HIP-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 2 -// HIP-NEXT: %size = load i64, ptr %4, align 4 -// HIP-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 3 -// HIP-NEXT: %flags = load i32, ptr %5, align 4 -// HIP-NEXT: %6 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 4 -// HIP-NEXT: %textype = load i32, ptr %6, align 4 +// HIP-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 8 +// HIP-NEXT: %aux_addr = load ptr, ptr %3, align 8 +// HIP-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 2 +// HIP-NEXT: %kind = load i16, ptr %4, align 2 +// HIP-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 5 +// HIP-NEXT: %name = load ptr, ptr %5, align 8 +// HIP-NEXT: %6 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 6 +// HIP-NEXT: %size = load i64, ptr %6, align 4 +// HIP-NEXT: %7 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 3 +// HIP-NEXT: %flags = load i32, ptr %7, align 4 +// HIP-NEXT: %8 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i32 0, i32 7 +// HIP-NEXT: %data = load i64, ptr %8, align 4 +// HIP-NEXT: %9 = trunc i64 %data to i32 // HIP-NEXT: %type = and i32 %flags, 7 -// HIP-NEXT: %7 = and i32 %flags, 8 -// HIP-NEXT: %extern = lshr i32 %7, 3 -// HIP-NEXT: %8 = and i32 %flags, 16 -// HIP-NEXT: %constant = lshr i32 %8, 4 -// HIP-NEXT: %9 = and i32 %flags, 32 -// HIP-NEXT: %normalized = lshr i32 %9, 5 -// HIP-NEXT: %10 = icmp eq i64 %size, 0 -// HIP-NEXT: br i1 %10, label %if.then, label %if.else - +// HIP-NEXT: %10 = and i32 %flags, 8 +// HIP-NEXT: %extern = lshr i32 %10, 3 +// HIP-NEXT: %11 = and i32 %flags, 16 +// HIP-NEXT: %constant = lshr i32 %11, 4 +// HIP-NEXT: %12 = and i32 %flags, 32 +// HIP-NEXT: %normalized = lshr i32 %12, 5 +// HIP-NEXT: %13 = icmp eq i16 %kind, 3 +// HIP-NEXT: br i1 %13, label %if.kind, label %if.end +// +// HIP: if.kind: +// HIP-NEXT: %14 = icmp eq i64 %size, 0 +// HIP-NEXT: br i1 %14, label %if.then, label %if.else +// // HIP: if.then: -// HIP-NEXT: %11 = call i32 @__hipRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null) +// HIP-NEXT: %15 = call i32 @__hipRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null) // HIP-NEXT: br label %if.end - +// // HIP: if.else: // HIP-NEXT: switch i32 %type, label %if.end [ // HIP-NEXT: i32 0, label %sw.global @@ -223,31 +238,28 @@ // HIP-NEXT: i32 2, label %sw.surface // HIP-NEXT: i32 3, label %sw.texture // HIP-NEXT: ] - +// // HIP: sw.global: // HIP-NEXT: call void @__hipRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %extern, i64 %size, i32 %constant, i32 0) // HIP-NEXT: br label %if.end - +// // HIP: sw.managed: -// HIP-NEXT: %managed.addr = load ptr, ptr %addr, align 8 -// HIP-NEXT: %12 = getelementptr inbounds ptr, ptr %addr, i64 1 -// HIP-NEXT: %managed.addr2 = load ptr, ptr %12, align 8 -// HIP-NEXT: call void @__hipRegisterManagedVar(ptr %0, ptr %managed.addr, ptr %managed.addr2, ptr %name, i64 %size, i32 %textype) -// HIP-NEXT: br label %if.end - +// HIP-NEXT: call void @__hipRegisterManagedVar(ptr %0, ptr %aux_addr, ptr %addr, ptr %name, i64 %size, i32 %9) +// HIP-NEXT: br label %if.end +// // HIP: sw.surface: -// HIP-NEXT: call void @__hipRegisterSurface(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %textype, i32 %extern) +// HIP-NEXT: call void @__hipRegisterSurface(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %9, i32 %extern) // HIP-NEXT: br label %if.end - +// // HIP: sw.texture: -// HIP-NEXT: call void @__hipRegisterTexture(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %textype, i32 %normalized, i32 %extern) +// HIP-NEXT: call void @__hipRegisterTexture(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %9, i32 %normalized, i32 %extern) // HIP-NEXT: br label %if.end - +// // HIP: if.end: -// HIP-NEXT: %13 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1 -// HIP-NEXT: %14 = icmp eq ptr %13, @__stop_hip_offloading_entries -// HIP-NEXT: br i1 %14, label %while.end, label %while.entry - +// HIP-NEXT: %16 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1 +// HIP-NEXT: %17 = icmp eq ptr %16, @__stop_llvm_offload_entries +// HIP-NEXT: br i1 %17, label %while.end, label %while.entry +// // HIP: while.end: // HIP-NEXT: ret void // HIP-NEXT: } diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c index f416ee5f4463b..df0a1d1e9a84d 100644 --- a/clang/test/Driver/linker-wrapper.c +++ b/clang/test/Driver/linker-wrapper.c @@ -59,7 +59,7 @@ __attribute__((visibility("protected"), used)) int x; // RUN: --linker-path=/usr/bin/ld.lld --whole-archive %t.a --no-whole-archive \ // RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=CPU-LINK -// CPU-LINK: clang{{.*}} -o {{.*}}.img --target=x86_64-unknown-linux-gnu -march=native -O2 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared -Wl,--whole-archive {{.*}}.a -Wl,--no-whole-archive +// CPU-LINK: clang{{.*}} -o {{.*}}.img --target=x86_64-unknown-linux-gnu -O2 -flto -Wl,--no-undefined {{.*}}.o {{.*}}.o -Wl,-Bsymbolic -shared -Wl,--whole-archive {{.*}}.a -Wl,--no-whole-archive // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o // RUN: clang-linker-wrapper --dry-run --host-triple=x86_64-unknown-linux-gnu -mllvm -openmp-opt-disable \ diff --git a/clang/test/Driver/objc-sdk-migration-options.m b/clang/test/Driver/objc-sdk-migration-options.m deleted file mode 100644 index 8f7e5c72a3cff..0000000000000 --- a/clang/test/Driver/objc-sdk-migration-options.m +++ /dev/null @@ -1,8 +0,0 @@ -// Check miscellaneous Objective-C sdk migration options. - -// RUN: %clang -objcmt-migrate-property-dot-syntax -target x86_64-apple-darwin10 -S -### %s \ -// RUN: -arch x86_64 2> %t -// RUN: FileCheck < %t %s - -// CHECK: "-cc1" -// CHECK: -objcmt-migrate-property-dot-syntax diff --git a/clang/test/Driver/offload-Xarch.c b/clang/test/Driver/offload-Xarch.c new file mode 100644 index 0000000000000..0f8f40a5cbd74 --- /dev/null +++ b/clang/test/Driver/offload-Xarch.c @@ -0,0 +1,45 @@ +// UNSUPPORTED: target={{.*darwin.*}} + +// RUN: %clang --target=x86_64-unknown-linux-gnu -x cuda %s -Xarch_nvptx64 -O3 -S -nogpulib -nogpuinc -### 2>&1 | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -x cuda %s -Xarch_device -O3 -S -nogpulib -nogpuinc -### 2>&1 | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -x hip %s -Xarch_amdgcn -O3 -S -nogpulib -nogpuinc -### 2>&1 | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -fopenmp=libomp -fopenmp-targets=amdgcn-amd-amdhsa -nogpulib -nogpuinc \ +// RUN: -Xarch_amdgcn -march=gfx90a -Xarch_amdgcn -O3 -S -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=O3ONCE %s +// RUN: %clang -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda -nogpulib -nogpuinc \ +// RUN: -Xarch_nvptx64 -march=sm_52 -Xarch_nvptx64 -O3 -S -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=O3ONCE %s +// O3ONCE: "-O3" +// O3ONCE-NOT: "-O3" + +// RUN: %clang -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda,amdgcn-amd-amdhsa -nogpulib \ +// RUN: --target=x86_64-unknown-linux-gnu -Xopenmp-target=nvptx64-nvidia-cuda --offload-arch=sm_52,sm_60 -nogpuinc \ +// RUN: -Xopenmp-target=amdgcn-amd-amdhsa --offload-arch=gfx90a,gfx1030 -ccc-print-bindings -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=OPENMP %s + +// OPENMP: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[INPUT:.+]]"], output: "[[HOST_BC:.+]]" +// OPENMP: # "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[GFX1030_BC:.+]]" +// OPENMP: # "amdgcn-amd-amdhsa" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[GFX90A_BC:.+]]" +// OPENMP: # "nvptx64-nvidia-cuda" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[SM52_PTX:.+]]" +// OPENMP: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler", inputs: ["[[SM52_PTX]]"], output: "[[SM52_CUBIN:.+]]" +// OPENMP: # "nvptx64-nvidia-cuda" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[SM60_PTX:.+]]" +// OPENMP: # "nvptx64-nvidia-cuda" - "NVPTX::Assembler", inputs: ["[[SM60_PTX]]"], output: "[[SM60_CUBIN:.+]]" +// OPENMP: # "x86_64-unknown-linux-gnu" - "Offload::Packager", inputs: ["[[GFX1030_BC]]", "[[GFX90A_BC]]", "[[SM52_CUBIN]]", "[[SM60_CUBIN]]"], output: "[[BINARY:.+]]" +// OPENMP: # "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[HOST_BC]]", "[[BINARY]]"], output: "[[HOST_OBJ:.+]]" +// OPENMP: # "x86_64-unknown-linux-gnu" - "Offload::Linker", inputs: ["[[HOST_OBJ]]"], output: "a.out" + +// RUN: %clang -x cuda %s --offload-arch=sm_52,sm_60 -Xarch_sm_52 -O3 -Xarch_sm_60 -O0 \ +// RUN: --target=x86_64-unknown-linux-gnu -Xarch_host -O3 -S -nogpulib -nogpuinc -### 2>&1 \ +// RUN: | FileCheck -check-prefix=CUDA %s +// CUDA: "-cc1" "-triple" "nvptx64-nvidia-cuda" {{.*}}"-target-cpu" "sm_52" {{.*}}"-O3" +// CUDA: "-cc1" "-triple" "nvptx64-nvidia-cuda" {{.*}}"-target-cpu" "sm_60" {{.*}}"-O0" +// CUDA: "-cc1" "-triple" "x86_64-unknown-linux-gnu" {{.*}}"-O3" + +// Make sure that `-Xarch_amdgcn` forwards libraries to the device linker. +// RUN: %clang -fopenmp=libomp --offload-arch=gfx90a -nogpulib -nogpuinc \ +// RUN: --target=x86_64-unknown-linux-gnu -Xarch_amdgcn -Wl,-lfoo -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=LIBS %s +// RUN: %clang -fopenmp=libomp --offload-arch=gfx90a -nogpulib -nogpuinc \ +// RUN: -Xoffload-linker-amdgcn-amd-amdhsa -lfoo -### %s 2>&1 \ +// RUN: | FileCheck -check-prefix=LIBS %s +// LIBS: "--device-linker=amdgcn-amd-amdhsa=-lfoo" diff --git a/clang/test/Driver/openbsd.c b/clang/test/Driver/openbsd.c index 672cd3adf44a6..6639e9d2d9d67 100644 --- a/clang/test/Driver/openbsd.c +++ b/clang/test/Driver/openbsd.c @@ -136,3 +136,13 @@ // RUN: %clang --target=amd64-unknown-openbsd -flto -### %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-LTO-FLAGS %s // CHECK-LTO-FLAGS: "-plugin-opt=mcpu=x86-64" + +// Check 64-bit ARM for BTI and PAC flags +// RUN: %clang --target=aarch64-unknown-openbsd -### -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-AARCH64-BTI-PAC %s +// CHECK-AARCH64-BTI-PAC: "-msign-return-address=non-leaf" "-msign-return-address-key=a_key" "-mbranch-target-enforce" + +// Check 64-bit X86 for IBT flags +// RUN: %clang --target=amd64-unknown-openbsd -### -c %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-AMD64-IBT %s +// CHECK-AMD64-IBT: "-fcf-protection=branch" "-fno-jump-tables" diff --git a/clang/test/Driver/openmp-offload-gpu.c b/clang/test/Driver/openmp-offload-gpu.c index 74bd2a6aeee46..1f7e2996068c4 100644 --- a/clang/test/Driver/openmp-offload-gpu.c +++ b/clang/test/Driver/openmp-offload-gpu.c @@ -235,13 +235,13 @@ // CHECK-PHASES: 0: input, "[[INPUT:.+]]", c, (host-openmp) // CHECK-PHASES: 1: preprocessor, {0}, cpp-output, (host-openmp) // CHECK-PHASES: 2: compiler, {1}, ir, (host-openmp) -// CHECK-PHASES: 3: input, "[[INPUT]]", c, (device-openmp) -// CHECK-PHASES: 4: preprocessor, {3}, cpp-output, (device-openmp) -// CHECK-PHASES: 5: compiler, {4}, ir, (device-openmp) -// CHECK-PHASES: 6: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (nvptx64-nvidia-cuda)" {5}, ir -// CHECK-PHASES: 7: backend, {6}, assembler, (device-openmp) -// CHECK-PHASES: 8: assembler, {7}, object, (device-openmp) -// CHECK-PHASES: 9: offload, "device-openmp (nvptx64-nvidia-cuda)" {8}, object +// CHECK-PHASES: 3: input, "[[INPUT]]", c, (device-openmp, sm_52) +// CHECK-PHASES: 4: preprocessor, {3}, cpp-output, (device-openmp, sm_52) +// CHECK-PHASES: 5: compiler, {4}, ir, (device-openmp, sm_52) +// CHECK-PHASES: 6: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (nvptx64-nvidia-cuda:sm_52)" {5}, ir +// CHECK-PHASES: 7: backend, {6}, assembler, (device-openmp, sm_52) +// CHECK-PHASES: 8: assembler, {7}, object, (device-openmp, sm_52) +// CHECK-PHASES: 9: offload, "device-openmp (nvptx64-nvidia-cuda:sm_52)" {8}, object // CHECK-PHASES: 10: clang-offload-packager, {9}, image // CHECK-PHASES: 11: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (x86_64-unknown-linux-gnu)" {10}, ir // CHECK-PHASES: 12: backend, {11}, assembler, (host-openmp) @@ -315,7 +315,7 @@ // RUN: -Xopenmp-target=nvptx64-nvidia-cuda -march=sm_52 --offload-device-only -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-DEVICE-ONLY // CHECK-DEVICE-ONLY: "x86_64-unknown-linux-gnu" - "clang", inputs: ["[[INPUT:.*]]"], output: "[[HOST_BC:.*]]" // CHECK-DEVICE-ONLY: "nvptx64-nvidia-cuda" - "clang", inputs: ["[[INPUT]]", "[[HOST_BC]]"], output: "[[DEVICE_ASM:.*]]" -// CHECK-DEVICE-ONLY: "nvptx64-nvidia-cuda" - "NVPTX::Assembler", inputs: ["[[DEVICE_ASM]]"], output: "{{.*}}-openmp-nvptx64-nvidia-cuda.o" +// CHECK-DEVICE-ONLY: "nvptx64-nvidia-cuda" - "NVPTX::Assembler", inputs: ["[[DEVICE_ASM]]"], output: "{{.*}}-openmp-nvptx64-nvidia-cuda-sm_52.o" // RUN: %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-bindings -fopenmp=libomp -fopenmp-targets=nvptx64-nvidia-cuda \ // RUN: -Xopenmp-target=nvptx64-nvidia-cuda -march=sm_52 --offload-device-only -E -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-DEVICE-ONLY-PP diff --git a/clang/test/Driver/openmp-offload-jit.c b/clang/test/Driver/openmp-offload-jit.c index 57f265ac37eac..b3566f06bbee1 100644 --- a/clang/test/Driver/openmp-offload-jit.c +++ b/clang/test/Driver/openmp-offload-jit.c @@ -1,29 +1,29 @@ // Check that we enable LTO-mode properly with '-fopenmp-target-jit' and that it // still enabled LTO-mode if `-fno-offload-lto` is on. // RUN: %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-phases -fopenmp=libomp \ -// RUN: -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-target-jit %s 2>&1 \ +// RUN: --offload-arch=sm_52 -fopenmp-target-jit %s 2>&1 \ // RUN: | FileCheck -check-prefix=PHASES-JIT %s // RUN: %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-phases -fopenmp=libomp \ -// RUN: -fopenmp-targets=nvptx64-nvidia-cuda -foffload-lto -fopenmp-target-jit %s 2>&1 \ +// RUN: --offload-arch=sm_52 -foffload-lto -fopenmp-target-jit %s 2>&1 \ // RUN: | FileCheck -check-prefix=PHASES-JIT %s // RUN: %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-phases -fopenmp=libomp \ -// RUN: -fopenmp-targets=amdgcn-amd-amdhsa -fopenmp-target-jit %s 2>&1 \ +// RUN: --offload-arch=gfx90a -fopenmp-target-jit %s 2>&1 \ // RUN: | FileCheck -check-prefix=PHASES-JIT %s // RUN: %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-phases -fopenmp=libomp \ -// RUN: -fopenmp-targets=amdgcn-amd-amdhsa -foffload-lto -fopenmp-target-jit %s 2>&1 \ +// RUN: --offload-arch=gfx90a -foffload-lto -fopenmp-target-jit %s 2>&1 \ // RUN: | FileCheck -check-prefix=PHASES-JIT %s // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -ccc-print-phases -fopenmp=libomp \ -// RUN: -fopenmp-targets=amdgcn-amd-amdhsa -fno-offload-lto -fopenmp-target-jit %s 2>&1 \ +// RUN: --offload-arch=gfx90a -fno-offload-lto -fopenmp-target-jit %s 2>&1 \ // RUN: | FileCheck -check-prefix=PHASES-JIT %s // // PHASES-JIT: 0: input, "[[INPUT:.+]]", c, (host-openmp) // PHASES-JIT-NEXT: 1: preprocessor, {0}, cpp-output, (host-openmp) // PHASES-JIT-NEXT: 2: compiler, {1}, ir, (host-openmp) -// PHASES-JIT-NEXT: 3: input, "[[INPUT]]", c, (device-openmp) -// PHASES-JIT-NEXT: 4: preprocessor, {3}, cpp-output, (device-openmp) -// PHASES-JIT-NEXT: 5: compiler, {4}, ir, (device-openmp) +// PHASES-JIT-NEXT: 3: input, "[[INPUT]]", c, (device-openmp, {{.*}}) +// PHASES-JIT-NEXT: 4: preprocessor, {3}, cpp-output, (device-openmp, {{.*}}) +// PHASES-JIT-NEXT: 5: compiler, {4}, ir, (device-openmp, {{.*}}) // PHASES-JIT-NEXT: 6: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp ([[TARGET:.+]])" {5}, ir -// PHASES-JIT-NEXT: 7: backend, {6}, lto-bc, (device-openmp) +// PHASES-JIT-NEXT: 7: backend, {6}, lto-bc, (device-openmp, {{.*}}) // PHASES-JIT-NEXT: 8: offload, "device-openmp ([[TARGET]])" {7}, lto-bc // PHASES-JIT-NEXT: 9: clang-offload-packager, {8}, image, (device-openmp) // PHASES-JIT-NEXT: 10: offload, "host-openmp (x86_64-unknown-linux-gnu)" {2}, "device-openmp (x86_64-unknown-linux-gnu)" {9}, ir @@ -41,11 +41,11 @@ // Check for incompatible combinations // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp -fno-offload-lto \ -// RUN: -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-target-jit %s 2>&1 \ +// RUN: --offload-arch=sm_52 -fopenmp-target-jit %s 2>&1 \ // RUN: | FileCheck -check-prefix=NO-LTO %s // NO-LTO: error: the combination of '-fno-offload-lto' and '-fopenmp-target-jit' is incompatible // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -fopenmp=libomp -foffload-lto=thin \ -// RUN: -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-target-jit %s 2>&1 \ +// RUN: --offload-arch=sm_52 -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-target-jit %s 2>&1 \ // RUN: | FileCheck -check-prefix=THIN-LTO %s // THIN-LTO: error: the combination of '-foffload-lto=' and '-fopenmp-target-jit' is incompatible diff --git a/clang/test/Driver/openmp-offload.c b/clang/test/Driver/openmp-offload.c index caedc223a5c76..6f56ae00ba065 100644 --- a/clang/test/Driver/openmp-offload.c +++ b/clang/test/Driver/openmp-offload.c @@ -184,13 +184,13 @@ // RUN: %clang -### --target=powerpc64le-linux -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu -g %s 2>&1 \ // RUN: | FileCheck -check-prefix=CHK-NEW-DRIVER-DEBUG %s -// CHK-NEW-DRIVER-DEBUG: clang-linker-wrapper{{.*}} "--device-debug" +// CHK-NEW-DRIVER-DEBUG: clang-linker-wrapper{{.*}} "--device-compiler=powerpc64le-ibm-linux-gnu=-g" /// Check arguments to the linker wrapper // RUN: %clang -### --target=powerpc64le-linux -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu \ // RUN: -mllvm -abc %s 2>&1 | FileCheck -check-prefix=CHK-NEW-DRIVER-MLLVM %s -// CHK-NEW-DRIVER-MLLVM: clang-linker-wrapper{{.*}} "-abc" +// CHK-NEW-DRIVER-MLLVM: clang-linker-wrapper{{.*}} "--device-linker=powerpc64le-ibm-linux-gnu=-mllvm" "--device-linker=powerpc64le-ibm-linux-gnu=-abc" // // Ensure that we generate the correct bindings for '-fsyntax-only' for OpenMP. diff --git a/clang/test/Driver/openmp-system-arch.c b/clang/test/Driver/openmp-system-arch.c index d097c6bc06548..51021e352f4d3 100644 --- a/clang/test/Driver/openmp-system-arch.c +++ b/clang/test/Driver/openmp-system-arch.c @@ -68,13 +68,13 @@ // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -nogpulib -fopenmp=libomp \ // RUN: -fopenmp-targets=nvptx64-nvidia-cuda --nvptx-arch-tool=%t/nvptx_arch_empty %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=NVPTX -// NVPTX: error: cannot determine nvptx64 architecture: No NVIDIA GPU detected in the system; consider passing it via '-march' +// NVPTX: error: cannot determine nvptx64 architecture: No NVIDIA GPU detected in the system; consider passing it via '--offload-arch' // case when 'amdgpu-arch' returns nothing using `-fopenmp-targets=`. // RUN: not %clang -### --target=x86_64-unknown-linux-gnu -nogpulib -fopenmp=libomp \ // RUN: -fopenmp-targets=amdgcn-amd-amdhsa --amdgpu-arch-tool=%t/amdgpu_arch_empty %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=AMDGPU -// AMDGPU: error: cannot determine amdgcn architecture: No AMD GPU detected in the system; consider passing it via '-march' +// AMDGPU: error: cannot determine amdgcn architecture: No AMD GPU detected in the system; consider passing it via '--offload-arch' // case when CLANG_TOOLCHAIN_PROGRAM_TIMEOUT is malformed for nvptx-arch. // RUN: env CLANG_TOOLCHAIN_PROGRAM_TIMEOUT=foo \ @@ -82,7 +82,7 @@ // RUN: -fopenmp-targets=nvptx64-nvidia-cuda -nogpulib \ // RUN: --nvptx-arch-tool=%t/nvptx_arch_sm_70 %s 2>&1 | \ // RUN: FileCheck %s --check-prefix=BAD-TIMEOUT-NVPTX -// BAD-TIMEOUT-NVPTX: clang: error: cannot determine nvptx64 architecture: CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected an integer, got 'foo'; consider passing it via '-march'; environment variable CLANG_TOOLCHAIN_PROGRAM_TIMEOUT specifies the tool timeout (integer secs, <=0 is infinite) +// BAD-TIMEOUT-NVPTX: clang: error: cannot determine nvptx64 architecture: CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected an integer, got 'foo'; consider passing it via '--offload-arch'; environment variable CLANG_TOOLCHAIN_PROGRAM_TIMEOUT specifies the tool timeout (integer secs, <=0 is infinite) // case when CLANG_TOOLCHAIN_PROGRAM_TIMEOUT is malformed for amdgpu-arch. // RUN: env CLANG_TOOLCHAIN_PROGRAM_TIMEOUT= \ @@ -90,4 +90,4 @@ // RUN: -fopenmp-targets=amdgcn-amd-amdhsa -nogpulib \ // RUN: --amdgpu-arch-tool=%t/amdgpu_arch_gfx906 %s 2>&1 | \ // RUN: FileCheck %s --check-prefix=BAD-TIMEOUT-AMDGPU -// BAD-TIMEOUT-AMDGPU: clang: error: cannot determine amdgcn architecture: CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected an integer, got ''; consider passing it via '-march'; environment variable CLANG_TOOLCHAIN_PROGRAM_TIMEOUT specifies the tool timeout (integer secs, <=0 is infinite) +// BAD-TIMEOUT-AMDGPU: clang: error: cannot determine amdgcn architecture: CLANG_TOOLCHAIN_PROGRAM_TIMEOUT expected an integer, got ''; consider passing it via '--offload-arch'; environment variable CLANG_TOOLCHAIN_PROGRAM_TIMEOUT specifies the tool timeout (integer secs, <=0 is infinite) diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index ae3a1c29df397..3443ff0b69de9 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -157,6 +157,8 @@ // CHECK-NEXT: xcvmac 1.0 'XCVmac' (CORE-V Multiply-Accumulate) // CHECK-NEXT: xcvmem 1.0 'XCVmem' (CORE-V Post-incrementing Load & Store) // CHECK-NEXT: xcvsimd 1.0 'XCVsimd' (CORE-V SIMD ALU) +// CHECK-NEXT: xmipscmove 1.0 'XMIPSCMove' (MIPS conditional move instruction(s) (ccmov)) +// CHECK-NEXT: xmipslsp 1.0 'XMIPSLSP' (MIPS optimization for hardware load-store bonding) // CHECK-NEXT: xsfcease 1.0 'XSfcease' (SiFive sf.cease Instruction) // CHECK-NEXT: xsfvcp 1.0 'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions) // CHECK-NEXT: xsfvfnrclipxfqf 1.0 'XSfvfnrclipxfqf' (SiFive FP32-to-int8 Ranged Clip Instructions) @@ -191,7 +193,7 @@ // CHECK-NEXT: ssctr 1.0 'Ssctr' (Control Transfer Records Supervisor Level) // CHECK-NEXT: svukte 0.3 'Svukte' (Address-Independent Latency of User-Mode Faults to Supervisor Addresses) // CHECK-NEXT: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) -// CHECK-NEXT: xqciac 0.2 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) +// CHECK-NEXT: xqciac 0.3 'Xqciac' (Qualcomm uC Load-Store Address Calculation Extension) // CHECK-NEXT: xqcicli 0.2 'Xqcicli' (Qualcomm uC Conditional Load Immediate Extension) // CHECK-NEXT: xqcicm 0.2 'Xqcicm' (Qualcomm uC Conditional Move Extension) // CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension) diff --git a/clang/test/Driver/rocm-device-libs.cl b/clang/test/Driver/rocm-device-libs.cl index 6837e219dc35d..f9766e6fa4d99 100644 --- a/clang/test/Driver/rocm-device-libs.cl +++ b/clang/test/Driver/rocm-device-libs.cl @@ -145,8 +145,8 @@ // RUN: 2>&1 | FileCheck --check-prefixes=NOASAN %s // COMMON: "-triple" "amdgcn-amd-amdhsa" -// ASAN-SAME: "-mlink-bitcode-file" "{{.*}}/amdgcn/bitcode/asanrtl.bc" // COMMON-SAME: "-mlink-builtin-bitcode" "{{.*}}/amdgcn/bitcode/opencl.bc" +// ASAN-SAME: "-mlink-bitcode-file" "{{.*}}/amdgcn/bitcode/asanrtl.bc" // COMMON-SAME: "-mlink-builtin-bitcode" "{{.*}}/amdgcn/bitcode/ocml.bc" // COMMON-SAME: "-mlink-builtin-bitcode" "{{.*}}/amdgcn/bitcode/ockl.bc" diff --git a/clang/test/Driver/sycl-offload-jit.cpp b/clang/test/Driver/sycl-offload-jit.cpp index eb192e08a3bc0..e040f4ded18e9 100644 --- a/clang/test/Driver/sycl-offload-jit.cpp +++ b/clang/test/Driver/sycl-offload-jit.cpp @@ -27,7 +27,7 @@ // CHK-DEVICE-TRIPLE-SAME: "-aux-triple" "x86_64-unknown-linux-gnu" // CHK-DEVICE-TRIPLE-SAME: "-fsycl-is-device" // CHK-DEVICE-TRIPLE-SAME: "-O2" -// CHK-DEVICE-TRIPLE: clang-offload-packager{{.*}} "--image=file={{.*}}.bc,triple=spirv64-unknown-unknown,arch=,kind=sycl" +// CHK-DEVICE-TRIPLE: clang-offload-packager{{.*}} "--image=file={{.*}}.bc,triple=spirv64-unknown-unknown,arch=generic,kind=sycl" /// Check -fsycl-is-device is passed when compiling for the device. /// Check -fsycl-is-host is passed when compiling for host. diff --git a/clang/test/Driver/tls-dialect.c b/clang/test/Driver/tls-dialect.c index 3471b55b0ebae..9ab79e87353d8 100644 --- a/clang/test/Driver/tls-dialect.c +++ b/clang/test/Driver/tls-dialect.c @@ -10,6 +10,11 @@ /// TLSDESC is not on by default in Linux, even on RISC-V, and is covered above // RUN: %clang -### --target=riscv64-android %s 2>&1 | FileCheck --check-prefix=DESC %s +/// Fuchsia supports TLSDESC by default for all architectures. +// RUN: %clang -### --target=riscv64-unknown-fuchsia %s 2>&1 | FileCheck --check-prefix=DESC %s +// RUN: %clang -### --target=aarch64-unknown-fuchsia %s 2>&1 | FileCheck --check-prefix=DESC %s +// RUN: %clang -### --target=x86_64-unknown-fuchsia %s 2>&1 | FileCheck --check-prefix=DESC %s + /// LTO // RUN: %clang -### --target=loongarch64-linux -flto -mtls-dialect=desc %s 2>&1 | FileCheck --check-prefix=LTO-DESC %s // RUN: %clang -### --target=loongarch64-linux -flto %s 2>&1 | FileCheck --check-prefix=LTO-NODESC %s diff --git a/clang/test/Driver/uefi-constructed-args.c b/clang/test/Driver/uefi-constructed-args.c index 3cc5abe697453..44d2271e0c8ba 100644 --- a/clang/test/Driver/uefi-constructed-args.c +++ b/clang/test/Driver/uefi-constructed-args.c @@ -1,3 +1,5 @@ +// RUN: %clang -### --target=x86_64-unknown-uefi -g -- %s 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK %s // RUN: %clang_cl -### --target=x86_64-unknown-uefi -g -- %s 2>&1 \ // RUN: | FileCheck -check-prefixes=CHECK %s // CHECK: "-cc1" diff --git a/clang/test/Driver/unsupported-target-arch.c b/clang/test/Driver/unsupported-target-arch.c index 8df0ee9fe7d06..c0ec235439bca 100644 --- a/clang/test/Driver/unsupported-target-arch.c +++ b/clang/test/Driver/unsupported-target-arch.c @@ -63,3 +63,21 @@ // RUN: not %clang --target=powerpc-apple-darwin -o /dev/null %s 2> %t.err // RUN: FileCheck --input-file=%t.err --check-prefix=CHECK-PPCMAC %s // CHECK-PPCMAC: error: unknown target triple 'unknown-apple-macosx{{.*}}' + +// RUN: not %clang --target=aarch64-unknown-uefi -o %t.o %s 2> %t.err +// RUN: FileCheck --input-file=%t.err --check-prefix=CHECK-AARCH64 %s +// RUN: not %clang_cl --target=aarch64-unknown-uefi -o %t.o %s 2> %t.err +// RUN: FileCheck --input-file=%t.err --check-prefix=CHECK-AARCH64 %s +// CHECK-AARCH64: error: unknown target triple 'aarch64-unknown-uefi'{{$}} + +// RUN: not %clang --target=arm-unknown-uefi -o %t.o %s 2> %t.err +// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-ARM %s +// RUN: not %clang_cl --target=arm-unknown-uefi -o %t.o %s 2> %t.err +// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-ARM %s +// CHECK-ARM: error: unknown target triple 'arm-unknown-uefi'{{$}} + +// RUN: not %clang --target=x86-unknown-uefi -o %t.o %s 2> %t.err +// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-x86 %s +// RUN: not %clang_cl --target=x86-unknown-uefi -o %t.o %s 2> %t.err +// RUN: FileCheck --input-file=%t.err -check-prefixes=CHECK-x86 %s +// CHECK-x86: error: unknown target triple 'x86-unknown-uefi'{{$}} diff --git a/clang/test/Driver/warning-suppression-mappings-not-parsed.cpp b/clang/test/Driver/warning-suppression-mappings-not-parsed.cpp new file mode 100644 index 0000000000000..8f52fb1c6cc7d --- /dev/null +++ b/clang/test/Driver/warning-suppression-mappings-not-parsed.cpp @@ -0,0 +1,5 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: echo '[unknown-warning]' > %t/foo.txt +// RUN: %clang -fdriver-only --warning-suppression-mappings=%t/foo.txt %s | FileCheck -allow-empty %s +// CHECK-NOT: unknown warning option 'unknown-warning' diff --git a/clang/test/Driver/wasm-toolchain.c b/clang/test/Driver/wasm-toolchain.c index 2d14052082776..f516a4e457da7 100644 --- a/clang/test/Driver/wasm-toolchain.c +++ b/clang/test/Driver/wasm-toolchain.c @@ -224,6 +224,14 @@ // RUN: | FileCheck -check-prefix=WASM_LEGACY_EH_NO_EH %s // WASM_LEGACY_EH_NO_EH: invalid argument '-wasm-use-legacy-eh' not allowed with '-mno-exception-handling' +// When invoking clang with multiple files in a single command line, target +// feature flags should be equally added to the multiple clang-cc1 command lines +// RUN: %clang -### --target=wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s %s -mllvm -wasm-enable-sjlj 2>&1 \ +// RUN: | FileCheck -check-prefix=WASM_SJLJ_MULTI_FILES %s +// WASM_SJLJ_MULTI_FILES: "-cc1" {{.*}} "-target-feature" "+exception-handling" "-target-feature" "+multivalue" "-target-feature" "+reference-types" "-exception-model=wasm" +// WASM_SJLJ_MULTI_FILES: "-cc1" {{.*}} "-target-feature" "+exception-handling" "-target-feature" "+multivalue" "-target-feature" "+reference-types" "-exception-model=wasm" + // RUN: %clang -### %s -fsanitize=address --target=wasm32-unknown-emscripten 2>&1 | FileCheck -check-prefix=CHECK-ASAN-EMSCRIPTEN %s // CHECK-ASAN-EMSCRIPTEN: "-fsanitize=address" // CHECK-ASAN-EMSCRIPTEN: "-fsanitize-address-globals-dead-stripping" diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index 339f593dc760a..18361251dcebc 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -395,7 +395,8 @@ // EVEX512: "-target-feature" "+evex512" // NO-EVEX512: "-target-feature" "-evex512" -// RUN: %clang --target=i386 -mavx10.1 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_256 %s +// RUN: not %clang --target=i386 -march=i386 -mavx10.1 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=UNSUPPORT-AVX10 %s +// RUN: not %clang --target=i386 -march=i386 -mno-avx10.1 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=UNSUPPORT-AVX10 %s // RUN: %clang --target=i386 -mavx10.1-256 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_256 %s // RUN: %clang --target=i386 -mavx10.1-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_512 %s // RUN: %clang --target=i386 -mavx10.1-256 -mavx10.1-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_1_512 %s @@ -403,15 +404,18 @@ // RUN: not %clang --target=i386 -march=i386 -mavx10.1-128 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=BAD-AVX10 %s // RUN: not %clang --target=i386 -march=i386 -mavx10.a-256 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=BAD-AVX10 %s // RUN: not %clang --target=i386 -march=i386 -mavx10.1024-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=BAD-AVX10 %s -// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mavx512f %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-AVX512 %s -// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mno-avx512f %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-AVX512 %s -// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mevex512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-EVEX512 %s -// RUN: %clang --target=i386 -march=i386 -mavx10.1 -mno-evex512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-EVEX512 %s -// RUN: %clang --target=i386 -mavx10.2 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_2_256 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1-256 -mavx512f %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-AVX512 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1-256 -mno-avx512f %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-AVX512 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1-256 -mevex512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-EVEX512 %s +// RUN: %clang --target=i386 -march=i386 -mavx10.1-256 -mno-evex512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10-EVEX512 %s +// RUN: %clang --target=i386 -mavx10.2 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_2_512 %s +// RUN: %clang --target=i386 -mno-avx10.2 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-AVX10_2 %s // RUN: %clang --target=i386 -mavx10.2-256 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_2_256 %s // RUN: %clang --target=i386 -mavx10.2-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=AVX10_2_512 %s // RUN: %clang --target=i386 -mavx10.2-256 -mavx10.1-512 %s -### -o %t.o 2>&1 | FileCheck -check-prefixes=AVX10_2_256,AVX10_1_512 %s // RUN: %clang --target=i386 -mavx10.2-512 -mavx10.1-256 %s -### -o %t.o 2>&1 | FileCheck -check-prefixes=AVX10_2_512,AVX10_1_256 %s +// UNSUPPORT-AVX10: error: unsupported option '-m{{.*}}avx10.1' for target 'i386' +// NO-AVX10_2: "-target-feature" "-avx10.2-256" // AVX10_2_256: "-target-feature" "+avx10.2-256" // AVX10_2_512: "-target-feature" "+avx10.2-512" // AVX10_1_256: "-target-feature" "+avx10.1-256" diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c index c0c76ef1f06b5..d278cbb8ec348 100644 --- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c +++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c @@ -191,4 +191,44 @@ union Vector { // VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@Sa@FI@X $ c:@U@Vector" // VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@Sa@FI@Y $ c:@U@Vector" +// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix MYSTRUCT +// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix MYSTRUCT +// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix COUNTS +// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix COUNTS +struct MyStruct { + struct { + int count; + } counts[1]; +}; +// MYSTRUCT-NOT: "spelling": "" +// MYSTRUCT-NOT: "title": "" + +// COUNTS-LABEL: "!testLabel": "c:@S@MyStruct@FI@counts" +// COUNTS: "declarationFragments": [ +// COUNTS-NEXT: { +// COUNTS-NEXT: "kind": "keyword", +// COUNTS-NEXT: "spelling": "struct" +// COUNTS-NEXT: }, +// COUNTS-NEXT: { +// COUNTS-NEXT: "kind": "text", +// COUNTS-NEXT: "spelling": " { ... } " +// COUNTS-NEXT: }, +// COUNTS-NEXT: { +// COUNTS-NEXT: "kind": "identifier", +// COUNTS-NEXT: "spelling": "counts" +// COUNTS-NEXT: }, +// COUNTS-NEXT: { +// COUNTS-NEXT: "kind": "text", +// COUNTS-NEXT: "spelling": "[" +// COUNTS-NEXT: }, +// COUNTS-NEXT: { +// COUNTS-NEXT: "kind": "number", +// COUNTS-NEXT: "spelling": "1" +// COUNTS-NEXT: }, +// COUNTS-NEXT: { +// COUNTS-NEXT: "kind": "text", +// COUNTS-NEXT: "spelling": "];" +// COUNTS-NEXT: } +// COUNTS-NEXT: ], + // expected-no-diagnostics diff --git a/clang/test/ExtractAPI/typedef_underscore.c b/clang/test/ExtractAPI/typedef_underscore.c new file mode 100644 index 0000000000000..a42046907b46d --- /dev/null +++ b/clang/test/ExtractAPI/typedef_underscore.c @@ -0,0 +1,69 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \ +// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c-header %s -o %t/typedefchain-c.symbols.json -verify +// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \ +// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c++-header %s -o %t/typedefchain-cxx.symbols.json -verify + +// RUN: FileCheck %s --input-file %t/typedefchain-c.symbols.json --check-prefix MYSTRUCT +// RUN: FileCheck %s --input-file %t/typedefchain-cxx.symbols.json --check-prefix MYSTRUCT +typedef struct _MyStruct { } MyStruct; + +// MYSTRUCT-LABEL: "!testLabel": "c:@S@_MyStruct" +// MYSTRUCT: "accessLevel": "public", +// MYSTRUCT: "declarationFragments": [ +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "keyword", +// MYSTRUCT-NEXT: "spelling": "typedef" +// MYSTRUCT-NEXT: }, +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "text", +// MYSTRUCT-NEXT: "spelling": " " +// MYSTRUCT-NEXT: }, +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "keyword", +// MYSTRUCT-NEXT: "spelling": "struct" +// MYSTRUCT-NEXT: }, +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "text", +// MYSTRUCT-NEXT: "spelling": " " +// MYSTRUCT-NEXT: }, +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "identifier", +// MYSTRUCT-NEXT: "spelling": "_MyStruct" +// MYSTRUCT-NEXT: }, +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "text", +// MYSTRUCT-NEXT: "spelling": " { ... } " +// MYSTRUCT-NEXT: }, +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "identifier", +// MYSTRUCT-NEXT: "spelling": "MyStruct" +// MYSTRUCT-NEXT: }, +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "text", +// MYSTRUCT-NEXT: "spelling": ";" +// MYSTRUCT-NEXT: } +// MYSTRUCT-NEXT: ], +// MYSTRUCT: "kind": { +// MYSTRUCT-NEXT: "displayName": "Structure", +// MYSTRUCT-NEXT: "identifier": "c{{(\+\+)?}}.struct" +// MYSTRUCT: "names": { +// MYSTRUCT-NEXT: "navigator": [ +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "identifier", +// MYSTRUCT-NEXT: "spelling": "MyStruct" +// MYSTRUCT-NEXT: } +// MYSTRUCT-NEXT: ], +// MYSTRUCT-NEXT: "subHeading": [ +// MYSTRUCT-NEXT: { +// MYSTRUCT-NEXT: "kind": "identifier", +// MYSTRUCT-NEXT: "spelling": "MyStruct" +// MYSTRUCT-NEXT: } +// MYSTRUCT-NEXT: ], +// MYSTRUCT-NEXT: "title": "MyStruct" +// MYSTRUCT-NEXT: }, +// MYSTRUCT: "pathComponents": [ +// MYSTRUCT-NEXT: "MyStruct" +// MYSTRUCT-NEXT: ] + +// expected-no-diagnostics diff --git a/clang/test/Frontend/aarch64-ignore-branch-protection-attribute.c b/clang/test/Frontend/aarch64-ignore-branch-protection-attribute.c new file mode 100644 index 0000000000000..32cc98dd4e037 --- /dev/null +++ b/clang/test/Frontend/aarch64-ignore-branch-protection-attribute.c @@ -0,0 +1,31 @@ +// REQUIRES: aarch64-registered-target + +// RUN: %clang -target aarch64-linux-pauthtest %s -S -emit-llvm -o - 2>&1 | FileCheck --implicit-check-not=warning: %s +// RUN: %clang -target aarch64 -fptrauth-returns %s -S -emit-llvm -o - 2>&1 | FileCheck --implicit-check-not=warning: %s + +/// Unsupported with pauthtest, warning emitted +__attribute__((target("branch-protection=pac-ret"))) void f1() {} +// CHECK: warning: unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored [-Wignored-attributes] +// CHECK-NEXT: __attribute__((target("branch-protection=pac-ret"))) void f1() {} +__attribute__((target("branch-protection=gcs"))) void f2() {} +// CHECK: warning: unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored [-Wignored-attributes] +// CHECK-NEXT: __attribute__((target("branch-protection=gcs"))) void f2() {} +__attribute__((target("branch-protection=standard"))) void f3() {} +// CHECK: warning: unsupported 'branch-protection' in the 'target' attribute string; 'target' attribute ignored [-Wignored-attributes] +// CHECK-NEXT: __attribute__((target("branch-protection=standard"))) void f3() {} + +/// Supported with pauthtest, no warning emitted +__attribute__((target("branch-protection=bti"))) void f4() {} + +/// Supported with pauthtest, no warning emitted +__attribute__((target("branch-protection=none"))) void f5() {} + +/// Check there are no branch protection function attributes which are unsupported with pauthtest + +// CHECK-NOT: attributes {{.*}} "sign-return-address" +// CHECK-NOT: attributes {{.*}} "sign-return-address-key" +// CHECK-NOT: attributes {{.*}} "branch-protection-pauth-lr" +// CHECK-NOT: attributes {{.*}} "guarded-control-stack" + +/// Check function attributes which are supported with pauthtest +// CHECK: attributes {{.*}} "branch-target-enforcement" diff --git a/clang/test/Frontend/custom-diag-werror-interaction.c b/clang/test/Frontend/custom-diag-werror-interaction.c new file mode 100644 index 0000000000000..997c8c11ff0e0 --- /dev/null +++ b/clang/test/Frontend/custom-diag-werror-interaction.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm-only -fprofile-instrument=clang -fcoverage-mcdc -Werror -Wno-unused-value %s -verify + +int foo(int x); + +int main(void) { + int a, b, c; + a && foo( b && c ); // expected-warning{{unsupported MC/DC boolean expression; contains an operation with a nested boolean expression. Expression will not be covered}} + return 0; +} diff --git a/clang/test/Headers/__cpuidex_conflict.c b/clang/test/Headers/__cpuidex_conflict.c index 0f5e6e5e0a0ff..8687a6aa2f897 100644 --- a/clang/test/Headers/__cpuidex_conflict.c +++ b/clang/test/Headers/__cpuidex_conflict.c @@ -3,9 +3,7 @@ // RUN: %clang_cc1 %s -ffreestanding -fms-extensions -fms-compatibility \ // RUN: -fms-compatibility-version=19.00 -triple x86_64-pc-windows-msvc -emit-llvm -o - // %clang_cc1 %s -ffreestanding -triple x86_64-w64-windows-gnu -fms-extensions -emit-llvm -o - -// -// FIXME: See https://github.com/llvm/llvm-project/pull/121839 -// RUN: not %clang_cc1 %s -ffreestanding -fopenmp -fopenmp-is-target-device -aux-triple x86_64-unknown-linux-gnu +// RUN: %clang_cc1 %s -ffreestanding -fopenmp -fopenmp-is-target-device -aux-triple x86_64-unknown-linux-gnu typedef __SIZE_TYPE__ size_t; diff --git a/clang/test/Headers/gpuintrin.c b/clang/test/Headers/gpuintrin.c index 281339716c3ed..89efe12ee8def 100644 --- a/clang/test/Headers/gpuintrin.c +++ b/clang/test/Headers/gpuintrin.c @@ -38,7 +38,7 @@ // AMDGPU-NEXT: [[CALL20:%.*]] = call i64 @__gpu_ballot(i64 noundef -1, i1 noundef zeroext true) #[[ATTR7]] // AMDGPU-NEXT: call void @__gpu_sync_threads() #[[ATTR7]] // AMDGPU-NEXT: call void @__gpu_sync_lane(i64 noundef -1) #[[ATTR7]] -// AMDGPU-NEXT: [[CALL21:%.*]] = call i32 @__gpu_shuffle_idx_u32(i64 noundef -1, i32 noundef -1, i32 noundef -1) #[[ATTR7]] +// AMDGPU-NEXT: [[CALL21:%.*]] = call i32 @__gpu_shuffle_idx_u32(i64 noundef -1, i32 noundef -1, i32 noundef -1, i32 noundef 0) #[[ATTR7]] // AMDGPU-NEXT: [[CALL22:%.*]] = call i64 @__gpu_first_lane_id(i64 noundef -1) #[[ATTR7]] // AMDGPU-NEXT: [[CALL23:%.*]] = call zeroext i1 @__gpu_is_first_in_lane(i64 noundef -1) #[[ATTR7]] // AMDGPU-NEXT: call void @__gpu_exit() #[[ATTR8:[0-9]+]] @@ -70,7 +70,7 @@ // NVPTX-NEXT: [[CALL20:%.*]] = call i64 @__gpu_ballot(i64 noundef -1, i1 noundef zeroext true) #[[ATTR6]] // NVPTX-NEXT: call void @__gpu_sync_threads() #[[ATTR6]] // NVPTX-NEXT: call void @__gpu_sync_lane(i64 noundef -1) #[[ATTR6]] -// NVPTX-NEXT: [[CALL21:%.*]] = call i32 @__gpu_shuffle_idx_u32(i64 noundef -1, i32 noundef -1, i32 noundef -1) #[[ATTR6]] +// NVPTX-NEXT: [[CALL21:%.*]] = call i32 @__gpu_shuffle_idx_u32(i64 noundef -1, i32 noundef -1, i32 noundef -1, i32 noundef 0) #[[ATTR6]] // NVPTX-NEXT: [[CALL22:%.*]] = call i64 @__gpu_first_lane_id(i64 noundef -1) #[[ATTR6]] // NVPTX-NEXT: [[CALL23:%.*]] = call zeroext i1 @__gpu_is_first_in_lane(i64 noundef -1) #[[ATTR6]] // NVPTX-NEXT: call void @__gpu_exit() #[[ATTR7:[0-9]+]] @@ -90,6 +90,68 @@ __gpu_kernel void foo() { __gpu_num_threads_z(); __gpu_num_threads(0); __gpu_thread_id_x(); +// AMDGPU-LABEL: define internal i32 @__gpu_thread_id( +// AMDGPU-SAME: i32 noundef [[__DIM:%.*]]) #[[ATTR0]] { +// AMDGPU-NEXT: [[ENTRY:.*:]] +// AMDGPU-NEXT: [[RETVAL:%.*]] = alloca i32, align 4, addrspace(5) +// AMDGPU-NEXT: [[__DIM_ADDR:%.*]] = alloca i32, align 4, addrspace(5) +// AMDGPU-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr +// AMDGPU-NEXT: [[__DIM_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[__DIM_ADDR]] to ptr +// AMDGPU-NEXT: store i32 [[__DIM]], ptr [[__DIM_ADDR_ASCAST]], align 4 +// AMDGPU-NEXT: [[TMP0:%.*]] = load i32, ptr [[__DIM_ADDR_ASCAST]], align 4 +// AMDGPU-NEXT: switch i32 [[TMP0]], label %[[SW_DEFAULT:.*]] [ +// AMDGPU-NEXT: i32 0, label %[[SW_BB:.*]] +// AMDGPU-NEXT: i32 1, label %[[SW_BB1:.*]] +// AMDGPU-NEXT: i32 2, label %[[SW_BB3:.*]] +// AMDGPU-NEXT: ] +// AMDGPU: [[SW_BB]]: +// AMDGPU-NEXT: [[CALL:%.*]] = call i32 @__gpu_thread_id_x() #[[ATTR7]] +// AMDGPU-NEXT: store i32 [[CALL]], ptr [[RETVAL_ASCAST]], align 4 +// AMDGPU-NEXT: br label %[[RETURN:.*]] +// AMDGPU: [[SW_BB1]]: +// AMDGPU-NEXT: [[CALL2:%.*]] = call i32 @__gpu_thread_id_y() #[[ATTR7]] +// AMDGPU-NEXT: store i32 [[CALL2]], ptr [[RETVAL_ASCAST]], align 4 +// AMDGPU-NEXT: br label %[[RETURN]] +// AMDGPU: [[SW_BB3]]: +// AMDGPU-NEXT: [[CALL4:%.*]] = call i32 @__gpu_thread_id_z() #[[ATTR7]] +// AMDGPU-NEXT: store i32 [[CALL4]], ptr [[RETVAL_ASCAST]], align 4 +// AMDGPU-NEXT: br label %[[RETURN]] +// AMDGPU: [[SW_DEFAULT]]: +// AMDGPU-NEXT: unreachable +// AMDGPU: [[RETURN]]: +// AMDGPU-NEXT: [[TMP1:%.*]] = load i32, ptr [[RETVAL_ASCAST]], align 4 +// AMDGPU-NEXT: ret i32 [[TMP1]] +// +// NVPTX-LABEL: define internal i32 @__gpu_thread_id( +// NVPTX-SAME: i32 noundef [[__DIM:%.*]]) #[[ATTR0]] { +// NVPTX-NEXT: [[ENTRY:.*:]] +// NVPTX-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 +// NVPTX-NEXT: [[__DIM_ADDR:%.*]] = alloca i32, align 4 +// NVPTX-NEXT: store i32 [[__DIM]], ptr [[__DIM_ADDR]], align 4 +// NVPTX-NEXT: [[TMP0:%.*]] = load i32, ptr [[__DIM_ADDR]], align 4 +// NVPTX-NEXT: switch i32 [[TMP0]], label %[[SW_DEFAULT:.*]] [ +// NVPTX-NEXT: i32 0, label %[[SW_BB:.*]] +// NVPTX-NEXT: i32 1, label %[[SW_BB1:.*]] +// NVPTX-NEXT: i32 2, label %[[SW_BB3:.*]] +// NVPTX-NEXT: ] +// NVPTX: [[SW_BB]]: +// NVPTX-NEXT: [[CALL:%.*]] = call i32 @__gpu_thread_id_x() #[[ATTR6]] +// NVPTX-NEXT: store i32 [[CALL]], ptr [[RETVAL]], align 4 +// NVPTX-NEXT: br label %[[RETURN:.*]] +// NVPTX: [[SW_BB1]]: +// NVPTX-NEXT: [[CALL2:%.*]] = call i32 @__gpu_thread_id_y() #[[ATTR6]] +// NVPTX-NEXT: store i32 [[CALL2]], ptr [[RETVAL]], align 4 +// NVPTX-NEXT: br label %[[RETURN]] +// NVPTX: [[SW_BB3]]: +// NVPTX-NEXT: [[CALL4:%.*]] = call i32 @__gpu_thread_id_z() #[[ATTR6]] +// NVPTX-NEXT: store i32 [[CALL4]], ptr [[RETVAL]], align 4 +// NVPTX-NEXT: br label %[[RETURN]] +// NVPTX: [[SW_DEFAULT]]: +// NVPTX-NEXT: unreachable +// NVPTX: [[RETURN]]: +// NVPTX-NEXT: [[TMP1:%.*]] = load i32, ptr [[RETVAL]], align 4 +// NVPTX-NEXT: ret i32 [[TMP1]] +// __gpu_thread_id_y(); __gpu_thread_id_z(); __gpu_thread_id(0); @@ -100,7 +162,7 @@ __gpu_kernel void foo() { __gpu_ballot(-1, 1); __gpu_sync_threads(); __gpu_sync_lane(-1); - __gpu_shuffle_idx_u32(-1, -1, -1); + __gpu_shuffle_idx_u32(-1, -1, -1, 0); __gpu_first_lane_id(-1); __gpu_is_first_in_lane(-1); __gpu_exit(); diff --git a/clang/test/Import/cxx-anon-namespace/test.cpp b/clang/test/Import/cxx-anon-namespace/test.cpp index e7668cc36f0e8..9a2df03d35bbc 100644 --- a/clang/test/Import/cxx-anon-namespace/test.cpp +++ b/clang/test/Import/cxx-anon-namespace/test.cpp @@ -14,12 +14,12 @@ // CHECK-NEXT: CompoundStmt // This is for the nested anonymous namespace. // CHECK-NEXT: UsingDirectiveDecl -// CHECK-SAME: '' +// CHECK-SAME: // CHECK: FunctionDecl // CHECK-SAME: func1 // CHECK-NEXT: CompoundStmt // CHECK-NEXT: UsingDirectiveDecl -// CHECK-SAME: '' +// CHECK-SAME: // CHECK: NamespaceDecl // CHECK-SAME: test_namespace1 @@ -28,7 +28,7 @@ // CHECK-SAME: func2 // CHECK-NEXT: CompoundStmt // CHECK-NEXT: UsingDirectiveDecl -// CHECK-SAME: '' +// CHECK-SAME: // CHECK-NEXT: NamespaceDecl // CHECK-SAME: test_namespace2 @@ -39,7 +39,7 @@ // CHECK-SAME: func3 // CHECK-NEXT: CompoundStmt // CHECK-NEXT: UsingDirectiveDecl -// CHECK-SAME: '' +// CHECK-SAME: void expr() { func1(); diff --git a/clang/test/Index/index-deduction-guide.cpp b/clang/test/Index/index-deduction-guide.cpp new file mode 100644 index 0000000000000..a29162e8588e8 --- /dev/null +++ b/clang/test/Index/index-deduction-guide.cpp @@ -0,0 +1,10 @@ +// RUN: c-index-test core -print-source-symbols -- %s -std=gnu++17 | FileCheck %s + +template +typename T::type declval() {} +template struct Test; +template ().d())> Test(C &) -> Test; +// CHECK: [[@LINE-1]]:45 | function/C | declval +// CHECK-NOT: RelCall +// CHECK: [[@LINE-3]]:77 | struct(Gen)/C++ | Test +// CHECK: [[@LINE-4]]:64 | struct(Gen)/C++ | Test diff --git a/clang/test/Interpreter/simple-exception.cpp b/clang/test/Interpreter/simple-exception.cpp index 6749acd6e6bd2..651e8d9402f89 100644 --- a/clang/test/Interpreter/simple-exception.cpp +++ b/clang/test/Interpreter/simple-exception.cpp @@ -1,7 +1,7 @@ // clang-format off // UNSUPPORTED: system-aix -// XFAIL for arm and arm64, or running on Windows. -// XFAIL: target=arm{{.*}}, system-windows +// XFAIL for arm, or running on Windows. +// XFAIL: target=arm-{{.*}}, target=armv{{.*}}, system-windows // RUN: cat %s | clang-repl | FileCheck %s // Incompatible with msan. It passes with -O3 but fail -Oz. Interpreter diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp index 3a60318d3f231..b423e94b26aca 100644 --- a/clang/test/Lexer/cxx-features.cpp +++ b/clang/test/Lexer/cxx-features.cpp @@ -7,7 +7,6 @@ // RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -verify %s // -// RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -fno-relaxed-template-template-args -DNO_RELAXED_TEMPLATE_TEMPLATE_ARGS=1 -verify %s // RUN: %clang_cc1 -std=c++17 -fcxx-exceptions -DCONCEPTS_TS=1 -verify %s // RUN: %clang_cc1 -std=c++14 -fno-rtti -fno-threadsafe-statics -verify %s -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS // RUN: %clang_cc1 -std=c++14 -fchar8_t -DNO_EXCEPTIONS -DCHAR8_T -verify %s @@ -239,9 +238,7 @@ #error "wrong value for __cpp_nontype_template_args" #endif -#if !defined(NO_RELAXED_TEMPLATE_TEMPLATE_ARGS) \ - ? check(template_template_args, 201611, 201611, 201611, 201611, 201611, 201611, 201611) \ - : check(template_template_args, 0, 0, 0, 0, 0, 0, 0) +#if check(template_template_args, 201611, 201611, 201611, 201611, 201611, 201611, 201611) #error "wrong value for __cpp_template_template_args" #endif diff --git a/clang/test/Misc/warning-flags.c b/clang/test/Misc/warning-flags.c index 1fd0244083335..46b4e5a064c36 100644 --- a/clang/test/Misc/warning-flags.c +++ b/clang/test/Misc/warning-flags.c @@ -18,7 +18,7 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (61): +CHECK: Warnings without flags (59): CHECK-NEXT: ext_expected_semi_decl_list CHECK-NEXT: ext_missing_whitespace_after_macro_name @@ -32,7 +32,6 @@ CHECK-NEXT: pp_invalid_string_literal CHECK-NEXT: pp_out_of_date_dependency CHECK-NEXT: pp_poisoning_existing_macro CHECK-NEXT: warn_accessor_property_type_mismatch -CHECK-NEXT: warn_arcmt_nsalloc_realloc CHECK-NEXT: warn_asm_label_on_auto_decl CHECK-NEXT: warn_c_kext CHECK-NEXT: warn_call_wrong_number_of_arguments @@ -60,7 +59,6 @@ CHECK-NEXT: warn_method_param_redefinition CHECK-NEXT: warn_missing_case_for_condition CHECK-NEXT: warn_missing_dependent_template_keyword CHECK-NEXT: warn_missing_whitespace_after_macro_name -CHECK-NEXT: warn_mt_message CHECK-NEXT: warn_no_constructor_for_refconst CHECK-NEXT: warn_not_compound_assign CHECK-NEXT: warn_objc_property_copy_missing_on_block diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index b197f319e0d15..f587af4beb7ce 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -40,7 +40,10 @@ void g() { template_param_kinds_1<0>(); // ok, from cxx-templates-a.h template_param_kinds_1(); // ok, from cxx-templates-b.h - template_param_kinds_2(); // ok, from cxx-templates-b.h + + template_param_kinds_2(); // expected-error {{no matching function for call}} + // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}} template_param_kinds_2(); // expected-error {{ambiguous}} // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}} diff --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp index 4de0e50dbc0eb..b0f5b904f2b39 100644 --- a/clang/test/Modules/odr_hash.cpp +++ b/clang/test/Modules/odr_hash.cpp @@ -4020,7 +4020,7 @@ struct Valid { }; #else Invalid::L2<1>::L3<1> invalid; -// expected-error@second.h:* {{'Types::InjectedClassName::Invalid::L2::L3::x' from module 'SecondModule' is not present in definition of 'L3<>' in module 'FirstModule'}} +// expected-error@second.h:* {{'Types::InjectedClassName::Invalid::L2::L3::x' from module 'SecondModule' is not present in definition of 'L3' in module 'FirstModule'}} // expected-note@first.h:* {{declaration of 'x' does not match}} Valid::L2<1>::L3<1> valid; #endif diff --git a/clang/test/Modules/pr120277-2.cpp b/clang/test/Modules/pr120277-2.cpp new file mode 100644 index 0000000000000..f3a7e47431848 --- /dev/null +++ b/clang/test/Modules/pr120277-2.cpp @@ -0,0 +1,66 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-01.h \ +// RUN: -o %t/hu-01.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-02.h \ +// RUN: -Wno-experimental-header-units -fmodule-file=%t/hu-01.pcm -o %t/hu-02.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-03.h \ +// RUN: -Wno-experimental-header-units \ +// RUN: -fmodule-file=%t/hu-01.pcm -o %t/hu-03.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-04.h \ +// RUN: -Wno-experimental-header-units -fmodule-file=%t/hu-02.pcm \ +// RUN: -fmodule-file=%t/hu-03.pcm -o %t/hu-04.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-obj %t/main.cpp \ +// RUN: -Wno-experimental-header-units -fmodule-file=%t/hu-04.pcm +//--- hu-01.h +template +struct A { + ~A() { f(); } + auto f() const { return 0; } +}; + +template +struct B { + int g() const { return a.f(); } + A a; +}; + +//--- hu-02.h +import "hu-01.h"; + +template +struct C { + void h() { + B().g(); + } +}; + +template struct A; + +//--- hu-03.h +import "hu-01.h"; + +inline B b() { + return {}; +} + +//--- hu-04.h +import "hu-02.h"; +import "hu-03.h"; + +inline void f4() { + C{}.h(); +} + +//--- main.cpp +import "hu-04.h"; + +int main() { + f4(); +} diff --git a/clang/test/Modules/pr121245.cpp b/clang/test/Modules/pr121245.cpp new file mode 100644 index 0000000000000..0e276ad0e435d --- /dev/null +++ b/clang/test/Modules/pr121245.cpp @@ -0,0 +1,93 @@ +// If this test fails, it should be investigated under Debug builds. +// Before the PR, this test was encountering an `llvm_unreachable()`. + +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// RUN: cd %t + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-01.h \ +// RUN: -fcxx-exceptions -o %t/hu-01.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-02.h \ +// RUN: -Wno-experimental-header-units -fcxx-exceptions \ +// RUN: -fmodule-file=%t/hu-01.pcm -o %t/hu-02.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-03.h \ +// RUN: -Wno-experimental-header-units -fcxx-exceptions \ +// RUN: -fmodule-file=%t/hu-01.pcm -o %t/hu-03.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-04.h \ +// RUN: -Wno-experimental-header-units -fcxx-exceptions \ +// RUN: -fmodule-file=%t/hu-01.pcm -o %t/hu-04.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header %t/hu-05.h \ +// RUN: -Wno-experimental-header-units -fcxx-exceptions \ +// RUN: -fmodule-file=%t/hu-03.pcm -fmodule-file=%t/hu-04.pcm \ +// RUN: -fmodule-file=%t/hu-01.pcm -o %t/hu-05.pcm + +// RUN: %clang_cc1 -std=c++20 -emit-obj %t/main.cpp \ +// RUN: -Wno-experimental-header-units -fcxx-exceptions \ +// RUN: -fmodule-file=%t/hu-02.pcm -fmodule-file=%t/hu-05.pcm \ +// RUN: -fmodule-file=%t/hu-04.pcm -fmodule-file=%t/hu-03.pcm \ +// RUN: -fmodule-file=%t/hu-01.pcm + +//--- hu-01.h +template +struct A { + A() {} + ~A() {} +}; + +template +struct EBO : T { + EBO() = default; +}; + +template +struct HT : EBO> {}; + +//--- hu-02.h +import "hu-01.h"; + +inline void f() { + HT(); +} + +//--- hu-03.h +import "hu-01.h"; + +struct C { + C(); + + HT _; +}; + +//--- hu-04.h +import "hu-01.h"; + +void g(HT = {}); + +//--- hu-05.h +import "hu-03.h"; +import "hu-04.h"; +import "hu-01.h"; + +struct B { + virtual ~B() = default; + + virtual void f() { + HT(); + } +}; + +//--- main.cpp +import "hu-02.h"; +import "hu-05.h"; +import "hu-03.h"; + +int main() { + f(); + C(); + B(); +} diff --git a/clang/test/Modules/pr125521.cppm b/clang/test/Modules/pr125521.cppm new file mode 100644 index 0000000000000..d064cdfe3eb73 --- /dev/null +++ b/clang/test/Modules/pr125521.cppm @@ -0,0 +1,57 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/mod2.cppm -emit-module-interface -o %t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod1.cppm -emit-module-interface -o %t/mod1.pcm \ +// RUN: -fmodule-file=Mod2=%t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/test.cc -fmodule-file=Mod2=%t/mod2.pcm -fmodule-file=Mod=%t/mod1.pcm \ +// RUN: -fsyntax-only -verify + +// RUN: %clang_cc1 -std=c++20 %t/mod2.cppm -emit-module-interface -o %t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod1.cppm -emit-module-interface -o %t/mod1.pcm \ +// RUN: -fmodule-file=Mod2=%t/mod2.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod1.pcm -fmodule-file=Mod2=%t/mod2.pcm -emit-llvm -o - \ +// RUN: | FileCheck %t/mod1.cppm + +//--- hello.h +template int get() noexcept {return 0;}; + +template +class List +{ + template friend int get() noexcept; +}; + +//--- mod2.cppm +module; +#include "hello.h" +export module Mod2; +export const char *modFn2() { + List a; + return "hello"; +} + +//--- mod1.cppm +module; +#include "hello.h" +export module Mod; +import Mod2; +export extern "C" const char *modFn() { + List a; + List b; + return modFn2(); +} + +// Fine enough to check it won't crash. +// CHECK: define {{.*}}@modFn + +//--- test.cc +// expected-no-diagnostics +import Mod; +import Mod2; + +void test() { + modFn(); + modFn2(); +} diff --git a/clang/test/Modules/pr126373.cppm b/clang/test/Modules/pr126373.cppm new file mode 100644 index 0000000000000..f176a587b51ce --- /dev/null +++ b/clang/test/Modules/pr126373.cppm @@ -0,0 +1,34 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/module1.cppm -emit-module-interface -o %t/module1.pcm +// RUN: %clang_cc1 -std=c++20 -fmodule-file=module1=%t/module1.pcm %t/module2.cppm \ +// RUN: -emit-module-interface -o %t/module2.pcm +// RUN: %clang_cc1 -std=c++20 %t/module2.pcm -fmodule-file=module1=%t/module1.pcm \ +// RUN: -emit-llvm -o - | FileCheck %t/module2.cppm + +//--- test.h +template +struct Test { + template + friend class Test; +}; + +//--- module1.cppm +module; +#include "test.h" +export module module1; +export void f1(Test) {} + +//--- module2.cppm +module; +#include "test.h" +export module module2; +import module1; +export void f2(Test) {} + +extern "C" void func() {} + +// Fine enough to check the IR is emitted correctly. +// CHECK: define{{.*}}@func diff --git a/clang/test/OpenMP/assume_lambda.cpp b/clang/test/OpenMP/assume_lambda.cpp index 4000dc1600b23..fa0d9ac2c327c 100644 --- a/clang/test/OpenMP/assume_lambda.cpp +++ b/clang/test/OpenMP/assume_lambda.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -ast-print %s | FileCheck %s // expected-no-diagnostics extern int bar(int); @@ -11,6 +11,12 @@ int foo(int arg) // CHECK: auto fn = [](int x) { return fn(5); } + #pragma omp assume no_openmp_constructs + { + auto fn = [](int x) { return bar(x); }; +// CHECK: auto fn = [](int x) { + return fn(6); + } } class C { diff --git a/clang/test/OpenMP/assume_nesting_tmpl.cpp b/clang/test/OpenMP/assume_nesting_tmpl.cpp index 59ef603f5874d..b0f50b0ddddf7 100644 --- a/clang/test/OpenMP/assume_nesting_tmpl.cpp +++ b/clang/test/OpenMP/assume_nesting_tmpl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -ast-print %s | FileCheck %s // expected-no-diagnostics extern void bar(); @@ -14,6 +14,14 @@ void foo() {} } + #pragma omp assume no_openmp_constructs + // CHECK: omp assume no_openmp_constructs + { + #pragma omp assume no_parallelism + // CHECK: omp assume no_parallelism + {} + } + #pragma omp target // CHECK: omp target { diff --git a/clang/test/OpenMP/assume_template.cpp b/clang/test/OpenMP/assume_template.cpp index 20d1c5d437145..2bf7567f675e9 100644 --- a/clang/test/OpenMP/assume_template.cpp +++ b/clang/test/OpenMP/assume_template.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER @@ -17,6 +17,12 @@ int foo(T arg) // CHECK: auto fn = [](int x) { return fn(5); } + #pragma omp assume no_openmp_constructs + { + auto fn = [](int x) { return qux(x); }; +// CHECK: auto fn = [](int x) { + return fn(6); + } } template diff --git a/clang/test/OpenMP/assumes_codegen.cpp b/clang/test/OpenMP/assumes_codegen.cpp index 4206e5a9caab7..a52ea956af245 100644 --- a/clang/test/OpenMP/assumes_codegen.cpp +++ b/clang/test/OpenMP/assumes_codegen.cpp @@ -1,11 +1,11 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s --check-prefix=AST -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -verify -o %t %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify=pch %s -emit-llvm -o - | FileCheck %s -// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown -o - | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -verify -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify=pch %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s --check-prefix=AST +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -verify -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify=pch %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fopenmp-version=60 -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -triple x86_64-unknown-unknown -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -verify -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify=pch %s -emit-llvm -o - | FileCheck %s // pch-no-diagnostics @@ -15,7 +15,7 @@ void foo() { } -#pragma omp assumes no_openmp_routines warning ext_another_warning(1) ext_after_invalid_clauses // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{'ext_another_warning' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} +#pragma omp assumes no_openmp_routines warning ext_another_warning(1) ext_after_invalid_clauses // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{'ext_another_warning' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} #pragma omp assumes no_openmp diff --git a/clang/test/OpenMP/assumes_include_nvptx.cpp b/clang/test/OpenMP/assumes_include_nvptx.cpp index 4577ea4c9c2b5..c5040989a0e40 100644 --- a/clang/test/OpenMP/assumes_include_nvptx.cpp +++ b/clang/test/OpenMP/assumes_include_nvptx.cpp @@ -11,11 +11,11 @@ // TODO: Think about teaching the OMPIRBuilder about default attributes as well so the __kmpc* declarations are annotated. -// CHECK: define weak_odr protected void @__omp_offloading_{{.*}}__Z17complex_reductionIfEvv_{{.*}}({{.*}}) [[attr0:#[0-9]]] +// CHECK: define weak_odr protected ptx_kernel void @__omp_offloading_{{.*}}__Z17complex_reductionIfEvv_{{.*}}({{.*}}) [[attr0:#[0-9]]] // CHECK: call i32 @__kmpc_target_init( // CHECK: declare noundef float @_Z3sinf(float noundef) [[attr1:#[0-9]*]] // CHECK: declare void @__kmpc_target_deinit( -// CHECK: define weak_odr protected void @__omp_offloading_{{.*}}__Z17complex_reductionIdEvv_{{.*}}({{.*}}) [[attr0]] +// CHECK: define weak_odr protected ptx_kernel void @__omp_offloading_{{.*}}__Z17complex_reductionIdEvv_{{.*}}({{.*}}) [[attr0]] // CHECK: %call = call noundef double @_Z3sind(double noundef 0.000000e+00) [[attr2:#[0-9]]] // CHECK: declare noundef double @_Z3sind(double noundef) [[attr1]] diff --git a/clang/test/OpenMP/assumes_messages.c b/clang/test/OpenMP/assumes_messages.c index 99bbe93dc1fc2..9bbedf59b77fc 100644 --- a/clang/test/OpenMP/assumes_messages.c +++ b/clang/test/OpenMP/assumes_messages.c @@ -1,46 +1,46 @@ -// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c -std=c99 -fms-extensions -Wno-pragma-pack %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -fopenmp-version=60 -x c -std=c99 -fms-extensions -Wno-pragma-pack %s -// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -x c -std=c99 -fms-extensions -Wno-pragma-pack %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -fopenmp-version=60 -x c -std=c99 -fms-extensions -Wno-pragma-pack %s -#pragma omp assumes // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism' clause for '#pragma omp assumes'}} +#pragma omp assumes // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism' clause for '#pragma omp assumes'}} #pragma omp begin // expected-error {{expected an OpenMP directive}} -#pragma omp begin assumes // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism' clause for '#pragma omp begin assumes'}} +#pragma omp begin assumes // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism' clause for '#pragma omp begin assumes'}} #pragma omp end assumes -#pragma omp assumes foobar // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -#pragma omp begin assumes foobar // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +#pragma omp assumes foobar // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +#pragma omp begin assumes foobar // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} #pragma omp end assumes -#pragma omp begin assumes foobar(foo 2 no_openmp // expected-error {{expected ')'}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{to match this '('}} -#pragma omp assumes foobar(foo 2 no_openmp // expected-error {{expected ')'}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{to match this '('}} +#pragma omp begin assumes foobar(foo 2 no_openmp // expected-error {{expected ')'}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{to match this '('}} +#pragma omp assumes foobar(foo 2 no_openmp // expected-error {{expected ')'}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{to match this '('}} #pragma omp end assumes -#pragma omp begin assumes foobar(foo 2 baz) // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} -#pragma omp assumes foobar(foo 2 baz) // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} +#pragma omp begin assumes foobar(foo 2 baz) // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} +#pragma omp assumes foobar(foo 2 baz) // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} #pragma omp end assumes -#pragma omp begin assumes foobar foo 2 baz) bar // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -#pragma omp assumes foobar foo 2 baz) bar // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +#pragma omp begin assumes foobar foo 2 baz) bar // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +#pragma omp assumes foobar foo 2 baz) bar // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} #pragma omp end assumes #pragma omp assumes no_openmp(1) // expected-warning {{'no_openmp' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} #pragma omp begin assumes no_openmp(1 2 3) // expected-warning {{'no_openmp' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} #pragma omp end assumes no_openmp(1) -#pragma omp assumes foobar no_openmp bazbaz // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -#pragma omp begin assumes foobar no_openmp bazbaz // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +#pragma omp assumes foobar no_openmp bazbaz // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +#pragma omp begin assumes foobar no_openmp bazbaz // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} #pragma omp end assumes -#pragma omp begin assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz) // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} -#pragma omp assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz) // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} +#pragma omp begin assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz) // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} +#pragma omp assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz) // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} #pragma omp end assumes -#pragma omp begin assumes foobar(foo (2) baz) no_openmp bazbaz(foo (2)) baz) // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} -#pragma omp assumes foobar(foo () baz) no_openmp bazbaz(foo ((2) baz) // expected-error {{expected ')'}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{to match this '('}} +#pragma omp begin assumes foobar(foo (2) baz) no_openmp bazbaz(foo (2)) baz) // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} +#pragma omp assumes foobar(foo () baz) no_openmp bazbaz(foo ((2) baz) // expected-error {{expected ')'}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{to match this '('}} #pragma omp end assumes -#pragma omp assumes no_openmp foobar no_openmp // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -#pragma omp begin assumes no_openmp foobar no_openmp // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +#pragma omp assumes no_openmp foobar no_openmp // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +#pragma omp begin assumes no_openmp foobar no_openmp // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} #pragma omp end assumes #pragma omp assumes holds(1, 2 3) @@ -55,8 +55,8 @@ #pragma omp begin assumes contains(1, 2 3) #pragma omp end assumes -#pragma omp assumes ext // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -#pragma omp begin assumes ext // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +#pragma omp assumes ext // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +#pragma omp begin assumes ext // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} #pragma omp end assumes #pragma omp assumes ext_123(not allowed) // expected-warning {{'ext_123' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} diff --git a/clang/test/OpenMP/assumes_messages_attr.c b/clang/test/OpenMP/assumes_messages_attr.c index c9fc68ce65d35..d68767493a512 100644 --- a/clang/test/OpenMP/assumes_messages_attr.c +++ b/clang/test/OpenMP/assumes_messages_attr.c @@ -1,33 +1,33 @@ // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -std=c99 -fms-extensions -Wno-pragma-pack %s // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -std=c99 -fms-extensions -Wno-pragma-pack %s -[[omp::directive(assumes)]]; // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism' clause for '#pragma omp assumes'}} +[[omp::directive(assumes)]]; // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism' clause for '#pragma omp assumes'}} [[omp::directive(begin)]]; // expected-error {{expected an OpenMP directive}} -[[omp::directive(begin assumes)]]; // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism' clause for '#pragma omp begin assumes'}} +[[omp::directive(begin assumes)]]; // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism' clause for '#pragma omp begin assumes'}} [[omp::directive(end assumes)]]; -[[omp::directive(assumes foobar)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -[[omp::directive(begin assumes foobar)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +[[omp::directive(assumes foobar)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +[[omp::directive(begin assumes foobar)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} [[omp::directive(end assumes)]]; -[[omp::directive(begin assumes foobar(foo 2 baz))]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} -[[omp::directive(assumes foobar(foo 2 baz))]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} +[[omp::directive(begin assumes foobar(foo 2 baz))]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} +[[omp::directive(assumes foobar(foo 2 baz))]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} [[omp::directive(end assumes)]]; [[omp::directive(assumes no_openmp(1))]]; // expected-warning {{'no_openmp' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} [[omp::directive(begin assumes no_openmp(1 2 3))]]; // expected-warning {{'no_openmp' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} [[omp::directive(end assumes no_openmp(1))]]; -[[omp::directive(assumes foobar no_openmp bazbaz)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -[[omp::directive(begin assumes foobar no_openmp bazbaz)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +[[omp::directive(assumes foobar no_openmp bazbaz)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +[[omp::directive(begin assumes foobar no_openmp bazbaz)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} [[omp::directive(end assumes)]]; -[[omp::directive(begin assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz))]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} -[[omp::directive(assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz))]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} +[[omp::directive(begin assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz))]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} +[[omp::directive(assumes foobar(foo 2 baz) no_openmp bazbaz(foo 2 baz))]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} expected-note {{the ignored tokens spans until here}} [[omp::directive(end assumes)]]; -[[omp::directive(assumes no_openmp foobar no_openmp)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -[[omp::directive(begin assumes no_openmp foobar no_openmp)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +[[omp::directive(assumes no_openmp foobar no_openmp)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +[[omp::directive(begin assumes no_openmp foobar no_openmp)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} [[omp::directive(end assumes)]]; [[omp::directive(assumes holds(1, 2 3))]]; @@ -42,8 +42,8 @@ [[omp::directive(begin assumes contains(1, 2 3))]]; [[omp::directive(end assumes)]]; -[[omp::directive(assumes ext)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} -[[omp::directive(begin assumes ext)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism'; token will be ignored}} +[[omp::directive(assumes ext)]]; // expected-warning {{valid assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} +[[omp::directive(begin assumes ext)]]; // expected-warning {{valid begin assumes clauses start with 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_openmp_constructs', 'no_parallelism'; token will be ignored}} [[omp::directive(end assumes)]]; [[omp::directive(assumes ext_123(not allowed))]]; // expected-warning {{'ext_123' clause should not be followed by arguments; tokens will be ignored}} expected-note {{the ignored tokens spans until here}} diff --git a/clang/test/OpenMP/assumes_print.cpp b/clang/test/OpenMP/assumes_print.cpp index 9254c29ab8335..25796ae8afcf5 100644 --- a/clang/test/OpenMP/assumes_print.cpp +++ b/clang/test/OpenMP/assumes_print.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER @@ -14,6 +14,7 @@ void foo() { } #pragma omp assumes no_openmp_routines +#pragma omp assumes no_openmp_constructs namespace inner { #pragma omp assumes no_openmp @@ -37,8 +38,8 @@ void baz() { } #pragma omp end assumes -// CHECK{LITERAL}: void foo() [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp")]] -// CHECK{LITERAL}: [[omp::assume("ompx_range_bar_only")]] [[omp::assume("ompx_range_bar_only_2")]] [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp")]] void bar() -// CHECK{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp")]] void baz() +// CHECK{LITERAL}: void foo() [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp_constructs")]] [[omp::assume("omp_no_openmp")]] +// CHECK{LITERAL}: [[omp::assume("ompx_range_bar_only")]] [[omp::assume("ompx_range_bar_only_2")]] [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp_constructs")]] [[omp::assume("omp_no_openmp")]] void bar() +// CHECK{LITERAL}: [[omp::assume("ompx_1234")]] [[omp::assume("omp_no_openmp_routines")]] [[omp::assume("omp_no_openmp_constructs")]] [[omp::assume("omp_no_openmp")]] void baz() #endif diff --git a/clang/test/OpenMP/attr-assume.cpp b/clang/test/OpenMP/attr-assume.cpp index 09c22f98d1e29..2d807d9a00b0d 100644 --- a/clang/test/OpenMP/attr-assume.cpp +++ b/clang/test/OpenMP/attr-assume.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify %s +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=60 -verify %s [[omp::assume(3)]] void f1(); // expected-error {{expected string literal as argument of 'assume' attribute}} [[omp::assume(int)]] void f2(); // expected-error {{expected string literal as argument of 'assume' attribute}} [[omp::assume(for)]] void f3(); // expected-error {{expected string literal as argument of 'assume' attribute}} @@ -8,6 +8,7 @@ [[omp::assume("omp_no_openmp_routine")]] void f7(); // expected-warning {{unknown assumption string 'omp_no_openmp_routine' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp_routines'?}} [[omp::assume("omp_no_openmp1")]] void f8(); // expected-warning {{unknown assumption string 'omp_no_openmp1' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp'?}} [[omp::assume("omp_no_openmp", "omp_no_openmp")]] void f9(); // expected-error {{'assume' attribute takes one argument}} +[[omp::assume("omp_no_openmp_construct")]] void f10(); // expected-warning {{unknown assumption string 'omp_no_openmp_construct' may be misspelled; attribute is potentially ignored, did you mean 'omp_no_openmp_constructs'?}} [[omp::assume(3)]] int g1; // expected-error {{expected string literal as argument of 'assume' attribute}} [[omp::assume("omp_no_openmp")]] int g2; // expected-warning {{'assume' attribute only applies to functions and Objective-C methods}} diff --git a/clang/test/OpenMP/barrier_codegen.cpp b/clang/test/OpenMP/barrier_codegen.cpp index 79e4076846526..e1b50793169d0 100644 --- a/clang/test/OpenMP/barrier_codegen.cpp +++ b/clang/test/OpenMP/barrier_codegen.cpp @@ -46,7 +46,7 @@ int main(int argc, char **argv) { // IRBUILDER: ; Function Attrs: nounwind // IRBUILDER-NEXT: declare i32 @__kmpc_global_thread_num(ptr) # // IRBUILDER_OPT: ; Function Attrs: nofree nosync nounwind willreturn memory(argmem: read, inaccessiblemem: read) -// IRBUILDER_OPT-NEXT: declare i32 @__kmpc_global_thread_num(ptr nocapture nofree readonly) # +// IRBUILDER_OPT-NEXT: declare i32 @__kmpc_global_thread_num(ptr nofree readonly captures(none)) # // CHECK: define {{.+}} [[TMAIN_INT]]( // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(ptr [[LOC]]) diff --git a/clang/test/OpenMP/begin_declare_variant_messages.c b/clang/test/OpenMP/begin_declare_variant_messages.c index ffa56002f1953..f87714a47dce0 100644 --- a/clang/test/OpenMP/begin_declare_variant_messages.c +++ b/clang/test/OpenMP/begin_declare_variant_messages.c @@ -32,27 +32,27 @@ const int var; #pragma omp end declare variant #pragma omp begin declare variant match // expected-error {{expected '(' after 'match'}} #pragma omp end declare variant -#pragma omp begin declare variant match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} +#pragma omp begin declare variant match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} #pragma omp end declare variant -#pragma omp begin declare variant match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} +#pragma omp begin declare variant match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} +#pragma omp begin declare variant match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant -#pragma omp begin declare variant match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp begin declare variant match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{extra tokens at the end of '#pragma omp begin declare variant' are ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp end declare variant #pragma omp begin declare variant match(implementation={xxx}) // expected-warning {{'xxx' is not a valid context selector for the context set 'implementation'; selector ignored}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} #pragma omp end declare variant diff --git a/clang/test/OpenMP/bug54082.c b/clang/test/OpenMP/bug54082.c index 337c120983e0a..da32be2867411 100644 --- a/clang/test/OpenMP/bug54082.c +++ b/clang/test/OpenMP/bug54082.c @@ -80,28 +80,28 @@ void foo() { // // // CHECK-LABEL: define {{[^@]+}}@foo.omp_outlined -// CHECK-SAME: (ptr noalias nocapture noundef readonly [[DOTGLOBAL_TID_:%.*]], ptr noalias nocapture readnone [[DOTBOUND_TID_:%.*]], ptr nocapture noundef nonnull readonly align 8 dereferenceable(8) [[X_ALLOC:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK-SAME: (ptr noalias noundef readonly captures(none) [[DOTGLOBAL_TID_:%.*]], ptr noalias readnone captures(none) [[DOTBOUND_TID_:%.*]], ptr noundef nonnull readonly align 8 captures(none) dereferenceable(8) [[X_ALLOC:%.*]]) #[[ATTR4:[0-9]+]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4 // CHECK-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[DOTOMP_LB]]) #[[ATTR5]] -// CHECK-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA6:![0-9]+]] +// CHECK-NEXT: store i32 0, ptr [[DOTOMP_LB]], align 4, !tbaa [[TBAA7:![0-9]+]] // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[DOTOMP_UB]]) #[[ATTR5]] -// CHECK-NEXT: store i32 1023, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA6]] +// CHECK-NEXT: store i32 1023, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA7]] // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[DOTOMP_STRIDE]]) #[[ATTR5]] -// CHECK-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA6]] +// CHECK-NEXT: store i32 1, ptr [[DOTOMP_STRIDE]], align 4, !tbaa [[TBAA7]] // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[DOTOMP_IS_LAST]]) #[[ATTR5]] -// CHECK-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA6]] -// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA6]] +// CHECK-NEXT: store i32 0, ptr [[DOTOMP_IS_LAST]], align 4, !tbaa [[TBAA7]] +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[DOTGLOBAL_TID_]], align 4, !tbaa [[TBAA7]] // CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[X_ALLOC]], align 8, !tbaa [[TBAA3]] // CHECK-NEXT: [[CONV:%.*]] = inttoptr i64 [[TMP1]] to ptr // CHECK-NEXT: [[DOTX__VOID_ADDR:%.*]] = tail call ptr @__kmpc_alloc(i32 [[TMP0]], i64 8, ptr [[CONV]]) // CHECK-NEXT: call void @__kmpc_for_static_init_4(ptr nonnull @[[GLOB1:[0-9]+]], i32 [[TMP0]], i32 34, ptr nonnull [[DOTOMP_IS_LAST]], ptr nonnull [[DOTOMP_LB]], ptr nonnull [[DOTOMP_UB]], ptr nonnull [[DOTOMP_STRIDE]], i32 1, i32 1) -// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA7]] // CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP2]], i32 1023) -// CHECK-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA6]] +// CHECK-NEXT: store i32 [[COND]], ptr [[DOTOMP_UB]], align 4, !tbaa [[TBAA7]] // CHECK-NEXT: call void @__kmpc_for_static_fini(ptr nonnull @[[GLOB1]], i32 [[TMP0]]) // CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[X_ALLOC]], align 8, !tbaa [[TBAA3]] // CHECK-NEXT: [[CONV5:%.*]] = inttoptr i64 [[TMP3]] to ptr diff --git a/clang/test/OpenMP/declare_mapper_codegen.cpp b/clang/test/OpenMP/declare_mapper_codegen.cpp index f9da3d97766d9..81453223b2a27 100644 --- a/clang/test/OpenMP/declare_mapper_codegen.cpp +++ b/clang/test/OpenMP/declare_mapper_codegen.cpp @@ -23,7 +23,7 @@ // Mapper function code generation and runtime interface. // CK0: [[IDENT_T:%.+]] = type { i32, i32, i32, i32, ptr } -// CK0: [[ENTRY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CK0: [[ENTRY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CK0: [[ANON_T:%.+]] = type { ptr } // CK0: [[ANON_T_0:%.+]] = type { ptr } // CK0: [[KMP_TASK_T_WITH_PRIVATES:%.+]] = type { [[KMP_TASK_T:%[^,]+]], [[KMP_PRIVATES_T:%.+]] } @@ -235,7 +235,7 @@ void foo(int a){ // CK0-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0 // CK0-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0 // CK0-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[PS]], i32 0, i32 0 -// CK0-DAG: [[MPR1:%.+]] = getelementptr inbounds {{.+}}[[MPR]], i[[sz]] 0, i[[sz]] 0 +// CK0-DAG: [[MPR1:%.+]] = getelementptr inbounds {{.+}}[[MPR]], i[[sz:32|64]] 0, i[[sz]] 0 // CK0-DAG: store ptr [[VAL:%[^,]+]], ptr [[BP1]] // CK0-DAG: store ptr [[VAL]], ptr [[P1]] // CK0-DAG: store ptr [[MPRFUNC]], ptr [[MPR1]] @@ -250,7 +250,7 @@ void foo(int a){ // CK0: store ptr [[CADDR:%[^,]+]], ptr [[BP2GEP]], align // CK0: [[P2GEP:%.+]] = getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_P2:%[^,]+]], i32 0, i32 0 // CK0: store ptr [[CADDR]], ptr [[P2GEP]], align - // CK0: [[MAPPER2GEP:%.+]] = getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_MAPPER2:%[^,]+]], i[[SZ]] 0, i[[SZ]] 0 + // CK0: [[MAPPER2GEP:%.+]] = getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_MAPPER2:%[^,]+]], i[[SZ:32|64]] 0, i[[SZ]] 0 // CK0: store ptr [[MPRFUNC]], ptr [[MAPPER2GEP]], align // CK0: [[BP2:%.+]] = getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_BP2]], i32 0, i32 0 // CK0: [[P2:%.+]] = getelementptr inbounds [1 x ptr], ptr [[OFFLOAD_P2]], i32 0, i32 0 diff --git a/clang/test/OpenMP/declare_mapper_messages.c b/clang/test/OpenMP/declare_mapper_messages.c index 288caca097648..2238689227311 100644 --- a/clang/test/OpenMP/declare_mapper_messages.c +++ b/clang/test/OpenMP/declare_mapper_messages.c @@ -1,10 +1,12 @@ // RUN: %clang_cc1 -verify=omp50,expected -fopenmp -fopenmp-version=50 -ferror-limit 100 -DOMP50 %s // RUN: %clang_cc1 -verify=omp51,expected -fopenmp -ferror-limit 100 %s // RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -ferror-limit 100 -DOMP52 %s +// RUN: %clang_cc1 -verify=expected,omp60 -fopenmp -fopenmp-version=60 -ferror-limit 100 -DOMP60 %s // RUN: %clang_cc1 -verify=omp50,expected -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 -DOMP50 %s // RUN: %clang_cc1 -verify=omp51-simd,expected -fopenmp-simd -ferror-limit 100 %s // RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -ferror-limit 100 -DOMP52 %s +// RUN: %clang_cc1 -verify=expected,omp60-simd -fopenmp-simd -fopenmp-version=60 -ferror-limit 100 -DOMP60 %s int temp; // expected-note {{'temp' declared here}} @@ -32,11 +34,11 @@ struct vec { // expec #pragma omp declare mapper(struct vec v) map(v.len) // expected-error {{redefinition of user-defined mapper for type 'struct vec' with name 'default'}} #pragma omp declare mapper(int v) map(v) // expected-error {{mapper type must be of struct, union or class type}} -#ifndef OMP52 -// omp51-simd-error@+6 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}} -// omp50-error@+5 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'ompx_hold'}} -// omp51-error@+4 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}} -// expected-error@+3 {{only variable 'vvec' is allowed in map clauses of this 'omp declare mapper' directive}} +#if !defined(OMP52) && !defined(OMP60) +// omp51-simd-error@+6 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}} +// omp50-error@+5 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'ompx_hold'}} +// omp51-error@+4 {{incorrect map type modifier, expected one of: 'always', 'close', 'mapper', 'present', 'ompx_hold'}} +// expected-error@+3 {{only variable 'vvec' is allowed in map clauses of this 'omp declare mapper' directive}} // expected-error@+2 {{expected at least one clause on '#pragma omp declare mapper' directive}} // expected-note@+1 {{'it' declared here}} #pragma omp declare mapper(id2: struct vec vvec) map(iterator(it=0:vvec.len:2), tofrom:vvec.data[it]) @@ -68,15 +70,28 @@ int fun(int arg) { {} #pragma omp target map(mapper(aa :vv) // expected-error {{use of undeclared identifier 'aa'}} expected-error {{expected ')'}} expected-error {{call to undeclared function 'mapper'}} expected-note {{to match this '('}} {} +#ifndef OMP60 #pragma omp target map(mapper(ab) :vv) // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}} +#endif {} +#ifndef OMP60 #pragma omp target map(mapper(ab) :arr[0:2]) // expected-error {{missing map type}} expected-error {{cannot find a valid user-defined mapper for type 'struct vec' with name 'ab'}} +#endif {} -#pragma omp target map(mapper(aa) :vv) // expected-error {{missing map type}} +#ifndef OMP60 +#pragma omp target map(mapper(aa) :vv) // omp50-error {{missing map type}} omp51-error {{missing map type}} omp52-error {{missing map type}} omp51-simd-error {{missing map type}} {} -#pragma omp target map(mapper(aa) to:d) // expected-error {{mapper type must be of struct, union or class type}} omp52-error{{missing ',' after map type modifier}} +#endif +// expected-error@+4 {{mapper type must be of struct, union or class type}} +// omp52-error@+3 {{missing ',' after map type modifier}} +// omp60-error@+2 {{missing ',' after map type modifier}} +// omp60-simd-error@+1 {{missing ',' after map type modifier}} +#pragma omp target map(mapper(aa) to:d) {} -#pragma omp target map(mapper(aa) to:vv) map(close mapper(aa) from:v1) map(mapper(aa) to:arr[0]) // omp52-error 4 {{missing ',' after map type modifier}} +// omp52-error@+3 4 {{missing ',' after map type modifier}} +// omp60-error@+2 4 {{missing ',' after map type modifier}} +// omp60-simd-error@+1 4 {{missing ',' after map type modifier}} +#pragma omp target map(mapper(aa) to:vv) map(close mapper(aa) from:v1) map(mapper(aa) to:arr[0]) {} #pragma omp target update to(mapper) // expected-error {{expected '(' after 'mapper'}} expected-error {{expected expression}} expected-error {{expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'}} diff --git a/clang/test/OpenMP/declare_target_ast_print.cpp b/clang/test/OpenMP/declare_target_ast_print.cpp index 3334b7491fab8..27d7a9fe21e52 100644 --- a/clang/test/OpenMP/declare_target_ast_print.cpp +++ b/clang/test/OpenMP/declare_target_ast_print.cpp @@ -4,6 +4,8 @@ // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -I %S/Inputs -ast-print %s | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50 // RUN: %clang_cc1 -verify -fopenmp -I %S/Inputs -ast-print %s | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -I %S/Inputs -ast-print %s | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -I %S/Inputs -ast-print %s | FileCheck %s --check-prefix=CHECK + // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -I %S/Inputs -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -I %S/Inputs -verify %s -ast-print | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -I %S/Inputs -emit-pch -o %t %s @@ -229,7 +231,7 @@ void f1() { int b1, b2, b3; void f2() { } -#if _OPENMP == 202111 +#if _OPENMP >= 202111 #pragma omp declare target enter(b1) enter(b2), enter(b3, f2) #else #pragma omp declare target to(b1) to(b2), to(b3, f2) @@ -336,7 +338,7 @@ int baz() { return 1; } #pragma omp declare target int abc1() { return 1; } -#if _OPENMP == 202111 +#if _OPENMP >= 202111 #pragma omp declare target enter(abc1) device_type(nohost) #else #pragma omp declare target to(abc1) device_type(nohost) @@ -379,7 +381,7 @@ int main (int argc, char **argv) { baz(); baz(); -#if _OPENMP == 202111 +#if _OPENMP >= 202111 #pragma omp declare target enter(foo2) #else #pragma omp declare target to (foo2) diff --git a/clang/test/OpenMP/declare_target_codegen.cpp b/clang/test/OpenMP/declare_target_codegen.cpp index ba93772ede3e8..d2fd29dcfbc50 100644 --- a/clang/test/OpenMP/declare_target_codegen.cpp +++ b/clang/test/OpenMP/declare_target_codegen.cpp @@ -30,7 +30,7 @@ // CHECK-DAG: @dx = {{protected | }}global i32 0, // CHECK-DAG: @dy = {{protected | }}global i32 0, // CHECK-DAG: @bbb = {{protected | }}global i32 0, -// CHECK-DAG: weak constant %struct.__tgt_offload_entry { ptr @bbb, +// CHECK-DAG: weak constant %struct.__tgt_offload_entry { // CHECK-DAG: @ccc = external global i32, // CHECK-DAG: @ddd = {{protected | }}global i32 0, // CHECK-DAG: @hhh_decl_tgt_ref_ptr = weak global ptr null diff --git a/clang/test/OpenMP/declare_target_link_codegen.cpp b/clang/test/OpenMP/declare_target_link_codegen.cpp index 189c9ac59c153..61e7bd8274fed 100644 --- a/clang/test/OpenMP/declare_target_link_codegen.cpp +++ b/clang/test/OpenMP/declare_target_link_codegen.cpp @@ -27,11 +27,11 @@ // HOST: [[SIZES:@.+]] = private unnamed_addr constant [3 x i64] [i64 4, i64 4, i64 4] // HOST: [[MAPTYPES:@.+]] = private unnamed_addr constant [3 x i64] [i64 35, i64 531, i64 531] // HOST: @.offloading.entry_name{{.*}} = internal unnamed_addr constant [{{[0-9]+}} x i8] c"c_decl_tgt_ref_ptr\00" -// HOST: @.offloading.entry.c_decl_tgt_ref_ptr = weak constant %struct.__tgt_offload_entry { ptr @c_decl_tgt_ref_ptr, ptr @.offloading.entry_name, i64 8, i32 1, i32 0 }, section "omp_offloading_entries", align 1 -// HOST-COFF: @.offloading.entry.{{.*}} = weak constant %struct.__tgt_offload_entry { ptr @.{{.*}}, ptr @.{{.*}}, i64 0, i32 0, i32 0 }, section "omp_offloading_entries$OE", align 1 +// HOST: @.offloading.entry.c_decl_tgt_ref_ptr = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 1, ptr @c_decl_tgt_ref_ptr, ptr @.offloading.entry_name, i64 8, i64 0, ptr null }, section "llvm_offload_entries" +// HOST-COFF: @.offloading.entry.{{.*}} = weak constant %struct.__tgt_offload_entry { {{.*}} }, section "llvm_offload_entries$OE" // DEVICE-NOT: internal unnamed_addr constant [{{[0-9]+}} x i8] c"c_{{.*}}_decl_tgt_ref_ptr\00" // HOST: @.offloading.entry_name{{.*}} = internal unnamed_addr constant [{{[0-9]+}} x i8] c"_{{.*}}d_{{.*}}_decl_tgt_ref_ptr\00" -// HOST: @.offloading.entry.[[D_PTR]] = weak constant %struct.__tgt_offload_entry { ptr @[[D_PTR]], ptr @.offloading.entry_name{{.*}} +// HOST: @.offloading.entry.[[D_PTR]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 1, ptr @[[D_PTR]], ptr @.offloading.entry_name.3, i64 8, i64 0, ptr null }, section "llvm_offload_entries" extern int c; #pragma omp declare target link(c) diff --git a/clang/test/OpenMP/declare_target_messages.cpp b/clang/test/OpenMP/declare_target_messages.cpp index de831f8575ee5..3c0e766cf72ca 100644 --- a/clang/test/OpenMP/declare_target_messages.cpp +++ b/clang/test/OpenMP/declare_target_messages.cpp @@ -1,46 +1,97 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,host5 -fopenmp -fopenmp-version=50 -fopenmp-targets=x86_64-apple-macos10.7.0 -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,dev5 -fopenmp -fopenmp-version=50 -fopenmp-is-target-device -fopenmp-targets=x86_64-apple-macos10.7.0 -aux-triple x86_64-apple-macos10.7.0 -fnoopenmp-use-tls -ferror-limit 100 -o - %s +// DEFINE: %{common_opts_mac} = -triple x86_64-apple-macos10.7.0 +// DEFINE: %{limit} = -fnoopenmp-use-tls -ferror-limit 100 +// DEFINE: %{target_mac} = -fopenmp-targets=x86_64-apple-macos10.7.0 +// DEFINE: %{aux_triple} = -aux-triple x86_64-apple-macos10.7.0 +// DEFINE: %{openmp45} = -fopenmp -fopenmp-version=45 +// DEFINE: %{openmp50} = -fopenmp -fopenmp-version=50 +// DEFINE: %{openmp50_simd} = -fopenmp-simd -fopenmp-version=50 +// DEFINE: %{openmp52} = -fopenmp -fopenmp-version=52 +// DEFINE: %{openmp60} = -fopenmp -fopenmp-version=60 +// DEFINE: %{openmp60_simd} = -fopenmp-simd -fopenmp-version=60 + +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp45,omp45-to-51,omp45-to-51-var,omp45-to-51-clause,omp45-to-51-clause %{openmp45} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51 %{openmp50} %{target_mac} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60} %{target_mac} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51,dev5 %{openmp50} -fopenmp-is-target-device %{target_mac} %{aux_triple} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60} -fopenmp-is-target-device %{target_mac} %{aux_triple} %{limit} -o - %s + +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51 %{openmp50_simd} %{target_mac} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60_simd} %{target_mac} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host5,host-5-and-51,no-host5-and-51 %{openmp50_simd} -fopenmp-is-target-device %{target_mac} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60_simd} -fopenmp-is-target-device %{target_mac} %{limit} -o - %s + +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp45,omp45-to-51,omp45-to-51-var,omp45-to-51-clause -fopenmp-version=45 -fopenmp-simd %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -DTESTEND=1 -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -I%S/Inputs -DTESTENDINC=1 -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp-simd %{limit} -o - %s + +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp52} -DVERBOSE_MODE=1 %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60} -DVERBOSE_MODE=1 %{limit} -o - %s + +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp5,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 %{openmp50} %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp51,ompvar,omp45-to-51,omp5-and-51,omp5-or-later,omp5-or-later-var,omp45-to-51-var,omp45-to-51-clause,host-5-and-51,no-host5-and-51 -fopenmp %{limit} -o - %s +// RUN: %clang_cc1 %{common_opts_mac} -verify=expected,omp52,ompvar,omp5-or-later,omp5-or-later-var %{openmp60} %{limit} -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,host5 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=x86_64-apple-macos10.7.0 -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5,host5 -fopenmp-simd -fopenmp-version=50 -fopenmp-is-target-device -fopenmp-targets=x86_64-apple-macos10.7.0 -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp45 -fopenmp-version=45 -fopenmp-simd -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp51 -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp51 -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -DTESTEND=1 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp51 -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -I%S/Inputs -DTESTENDINC=1 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp51 -fopenmp-simd -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp51 -fopenmp-simd -fnoopenmp-use-tls -ferror-limit 100 -o - %s +#pragma omp begin declare target +static int gg; +// expected-warning@+1 {{variable 'recursive' is uninitialized when used within its own initialization}} +int recursive = recursive ^ 3 + gg; +#pragma omp end declare target -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DVERBOSE_MODE=1 -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp5 -fopenmp -fopenmp-version=50 -fnoopenmp-use-tls -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify=expected,omp51 -fopenmp -fnoopenmp-use-tls -ferror-limit 100 -o - %s -#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}} +#pragma omp end declare target -int a, b, z; // omp5-error {{variable captured in declare target region must appear in a to clause}} // omp51-error {{variable captured in declare target region must appear in a to clause}} omp52-error {{variable captured in declare target region must appear in a to clause}} -__thread int t; // expected-note {{defined as threadprivate or thread local}} +// ompvar-error@+1 {{variable captured in declare target region must appear in a to clause}} +int a, b, z; +// expected-note@+1 {{defined as threadprivate or thread local}} +__thread int t; -#pragma omp declare target . // expected-error {{expected '(' after 'declare target'}} +// expected-error@+1 {{expected '(' after 'declare target'}} +#pragma omp declare target . #pragma omp declare target void f(); -#pragma omp end declare target shared(a) // expected-warning {{extra tokens at the end of '#pragma omp end declare target' are ignored}} - -#pragma omp declare target map(a) // omp45-error {{expected at least one 'to' or 'link' clause}} omp5-error {{expected at least one 'to' or 'link' clause}} omp51-error {{expected at least one 'to', 'link' or 'indirect' clause}} omp45-error {{unexpected 'map' clause, only 'to' or 'link' clauses expected}} omp5-error {{unexpected 'map' clause, only 'to', 'link' or 'device_type' clauses expected}} omp51-error {{unexpected 'map' clause, only 'to', 'link', 'device_type' or 'indirect' clauses expected}} omp52-error {{unexpected 'map' clause, only 'enter', 'link', 'device_type' or 'indirect' clauses expected}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} - -#pragma omp declare target to(foo1) // omp45-error {{use of undeclared identifier 'foo1'}} omp5-error {{use of undeclared identifier 'foo1'}} omp51-error {{use of undeclared identifier 'foo1'}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} - -#pragma omp declare target link(foo2) // expected-error {{use of undeclared identifier 'foo2'}} - -#pragma omp declare target to(f) device_type(host) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} dev5-note {{marked as 'device_type(host)' here}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} +// expected-warning@+1 {{extra tokens at the end of '#pragma omp end declare target' are ignored}} +#pragma omp end declare target shared(a) + +// omp52-error@+8 {{unexpected 'map' clause, only 'enter', 'link', 'device_type' or 'indirect' clauses expected}} +// omp52-error@+7 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp51-error@+6 {{unexpected 'map' clause, only 'to', 'link', 'device_type' or 'indirect' clauses expected}} +// omp51-error@+5 {{expected at least one 'to', 'link' or 'indirect' clause}} +// omp5-error@+4 {{unexpected 'map' clause, only 'to', 'link' or 'device_type' clauses expected}} +// omp5-error@+3 {{expected at least one 'to' or 'link' clause}} +// omp45-error@+2 {{unexpected 'map' clause, only 'to' or 'link' clauses expected}} +// omp45-error@+1 {{expected at least one 'to' or 'link' clause}} +#pragma omp declare target map(a) + +// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp45-to-51-error@+1 {{use of undeclared identifier 'foo1'}} +#pragma omp declare target to(foo1) + +// expected-error@+1 {{use of undeclared identifier 'foo2'}} +#pragma omp declare target link(foo2) + +// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// dev5-note@+2 {{marked as 'device_type(host)' here}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(f) device_type(host) void q(); -#pragma omp declare target to(q) device_type(any) device_type(any) device_type(host) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} omp5-warning {{more than one 'device_type' clause is specified}} // omp51-warning {{more than one 'device_type' clause is specified}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp5-and-51-warning@+2 {{more than one 'device_type' clause is specified}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(q) device_type(any) device_type(any) device_type(host) #if _OPENMP == 202011 // omp51-error@+1 {{directive '#pragma omp declare target' cannot contain more than one 'indirect' clause}} #pragma omp declare target to(q) indirect(true) indirect(false) -int xxx; //expected-note {{declared here}} +// expected-note@+1 {{declared here}} +int xxx; // omp51-error@+2 {{expression is not an integral constant expression}} // omp51-note@+1 {{read of non-const variable 'xxx' is not allowed in a constant expression}} #pragma omp declare target to(q) indirect(xxx) @@ -67,13 +118,20 @@ void bar(); void c(); -void func() {} // expected-note {{'func' defined here}} +// expected-note@+1 {{'func' defined here}} +void func() {} -#pragma omp declare target link(func) allocate(a) // expected-error {{function name is not allowed in 'link' clause}} omp45-error {{unexpected 'allocate' clause, only 'to' or 'link' clauses expected}} omp5-error {{unexpected 'allocate' clause, only 'to', 'link' or 'device_type' clauses expected}} omp51-error {{unexpected 'allocate' clause, only 'to', 'link', 'device_type' or 'indirect' clauses expected}} omp52-error {{unexpected 'allocate' clause, only 'enter', 'link', 'device_type' or 'indirect' clauses expected}} +// omp52-error@+5 {{unexpected 'allocate' clause, only 'enter', 'link', 'device_type' or 'indirect' clauses expected}} +// omp51-error@+4 {{unexpected 'allocate' clause, only 'to', 'link', 'device_type' or 'indirect' clauses expected}} +// omp5-error@+3 {{unexpected 'allocate' clause, only 'to', 'link' or 'device_type' clauses expected}} +// expected-error@+2 {{function name is not allowed in 'link' clause}} +// omp45-error@+1 {{unexpected 'allocate' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target link(func) allocate(a) void bar(); void baz() {bar();} -#pragma omp declare target(bar) // omp5-warning {{declaration marked as declare target after first use, it may lead to incorrect results}} // omp51-warning {{declaration marked as declare target after first use, it may lead to incorrect results}} omp52-warning {{declaration marked as declare target after first use, it may lead to incorrect results}} +// omp5-or-later-warning@+1 {{declaration marked as declare target after first use, it may lead to incorrect results}} +#pragma omp declare target(bar) extern int b; @@ -113,7 +171,8 @@ void t2() { void abc(); #pragma omp end declare target void cba(); -#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}} +#pragma omp end declare target #pragma omp declare target #pragma omp declare target @@ -122,7 +181,8 @@ void def(); void fed(); #pragma omp declare target -#pragma omp threadprivate(a) // expected-note {{defined as threadprivate or thread local}} +// expected-note@+1 {{defined as threadprivate or thread local}} +#pragma omp threadprivate(a) extern int b; int g; @@ -150,27 +210,32 @@ int C::method1() { } void foo(int p) { - a = 0; // expected-error {{threadprivate variables cannot be used in target constructs}} +// expected-error@+1 {{threadprivate variables cannot be used in target constructs}} + a = 0; b = 0; - t = 1; // expected-error {{threadprivate variables cannot be used in target constructs}} +// expected-error@+1 {{threadprivate variables cannot be used in target constructs}} + t = 1; C object; VC object1; g = object.method(); g += object.method1(); g += object1.method() + p; - f(); // dev5-error {{function with 'device_type(host)' is not available on device}} + // dev5-error@+1 {{function with 'device_type(host)' is not available on device}} + f(); q(); c(); } #pragma omp declare target void foo1() { - [&](){ (void)(b+z);}(); // omp5-note {{variable 'z' is captured here}} //omp51-note {{variable 'z' is captured here}} omp52-note {{variable 'z' is captured here}} + // omp5-or-later-var-note@+1 {{variable 'z' is captured here}} + [&](){ (void)(b+z);}(); } #pragma omp end declare target #pragma omp end declare target #pragma omp end declare target -#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}} +#pragma omp end declare target int C::method() { return 0; @@ -190,12 +255,20 @@ int *y; int **w = &y; int main (int argc, char **argv) { int a = 2; -#pragma omp declare target // expected-error {{unexpected OpenMP directive '#pragma omp declare target'}} +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp declare target'}} +#pragma omp declare target int v; -#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}} +// expected-error@+1 {{unexpected OpenMP directive '#pragma omp end declare target'}} +#pragma omp end declare target foo(v); -#pragma omp declare target to(foo3) link(w) // omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} -#pragma omp declare target to(a) //omp45-error {{local variable 'a' should not be used in 'declare target' directive}} omp5-error {{local variable 'a' should not be used in 'declare target' directive}} omp51-error {{local variable 'a' should not be used in 'declare target' directive}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} + + // omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}} + // omp52-error@+1 {{unexpected 'to' clause, use 'enter' instead}} +#pragma omp declare target to(foo3) link(w) + // omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}} + // omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}} + // omp45-to-51-var-error@+1 {{local variable 'a' should not be used in 'declare target' directive}} +#pragma omp declare target to(a) return (0); } @@ -205,77 +278,134 @@ namespace { } #pragma omp end declare target -#pragma omp declare target link(S) // expected-error {{'S' used in declare target directive is not a variable or a function name}} +// expected-error@+1 {{'S' used in declare target directive is not a variable or a function name}} +#pragma omp declare target link(S) -#pragma omp declare target (x, x) // expected-error {{'x' appears multiple times in clauses on the same declare target directive}} -#pragma omp declare target to(x) to(x) // omp45-error {{'x' appears multiple times in clauses on the same declare target directive}} omp5-error {{'x' appears multiple times in clauses on the same declare target directive}} omp51-error {{'x' appears multiple times in clauses on the same declare target directive}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} -#pragma omp declare target link(x) // expected-error {{'x' must not appear in both clauses 'to' and 'link'}} +// expected-error@+1 {{'x' appears multiple times in clauses on the same declare target directive}} +#pragma omp declare target (x, x) +// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp45-to-51-clause-error@+1 {{'x' appears multiple times in clauses on the same declare target directive}} +#pragma omp declare target to(x) to(x) +// expected-error@+1 {{'x' must not appear in both clauses 'to' and 'link'}} +#pragma omp declare target link(x) void bazz() {} -#pragma omp declare target to(bazz) device_type(nohost) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} host5-note 3{{marked as 'device_type(nohost)' here}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// host5-note@+2 3 {{marked as 'device_type(nohost)' here}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(bazz) device_type(nohost) void bazzz() {bazz();} -#pragma omp declare target to(bazzz) device_type(nohost) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} -void any() {bazz();} // host5-error {{function with 'device_type(nohost)' is not available on host}} -void host1() {bazz();} // host5-error {{function with 'device_type(nohost)' is not available on host}} -#pragma omp declare target to(host1) device_type(host) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} dev5-note 3 {{marked as 'device_type(host)' here}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} -void host2() {bazz();} //host5-error {{function with 'device_type(nohost)' is not available on host}} -#pragma omp declare target to(host2) // omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} -void device() {host1();} // dev5-error {{function with 'device_type(host)' is not available on device}} -#pragma omp declare target to(device) device_type(nohost) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} host5-note 2 {{marked as 'device_type(nohost)' here}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(bazzz) device_type(nohost) +// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}} +void any() {bazz();} +// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}} +void host1() {bazz();} +// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// dev5-note@+2 3 {{marked as 'device_type(host)' here}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(host1) device_type(host) +//host5-error@+1 {{function with 'device_type(nohost)' is not available on host}} +void host2() {bazz();} +// omp52-error@+2 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+1 {{expected at least one 'enter', 'link' or 'indirect' clause}} +#pragma omp declare target to(host2) +// dev5-error@+1 {{function with 'device_type(host)' is not available on device}} +void device() {host1();} +// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// host5-note@+2 2 {{marked as 'device_type(nohost)' here}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(device) device_type(nohost) void host3() {host1();} // dev5-error {{function with 'device_type(host)' is not available on device}} -#pragma omp declare target to(host3) // omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp52-error@+2 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+1 {{expected at least one 'enter', 'link' or 'indirect' clause}} +#pragma omp declare target to(host3) #pragma omp declare target void any1() {any();} -void any2() {host1();} // dev5-error {{function with 'device_type(host)' is not available on device}} -void any3() {device();} // host5-error {{function with 'device_type(nohost)' is not available on host}} +// dev5-error@+1 {{function with 'device_type(host)' is not available on device}} +void any2() {host1();} +// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}} +void any3() {device();} void any4() {any2();} #pragma omp end declare target void any5() {any();} void any6() {host1();} -void any7() {device();} // host5-error {{function with 'device_type(nohost)' is not available on host}} +// host5-error@+1 {{function with 'device_type(nohost)' is not available on host}} +void any7() {device();} void any8() {any2();} int MultiDevTy; -#pragma omp declare target to(MultiDevTy) device_type(any) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} -#pragma omp declare target to(MultiDevTy) device_type(host) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} omp5-error {{'device_type(host)' does not match previously specified 'device_type(any)' for the same declaration}} omp51-error {{'device_type(host)' does not match previously specified 'device_type(any)' for the same declaration}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} -#pragma omp declare target to(MultiDevTy) device_type(nohost) // omp45-error {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} omp5-error {{'device_type(nohost)' does not match previously specified 'device_type(any)' for the same declaration}} // omp51-error {{'device_type(nohost)' does not match previously specified 'device_type(any)' for the same declaration}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}} - -static int variable = 100; //expected-warning {{declaration is not declared in any declare target region}} +// omp52-error@+3 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+2 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(MultiDevTy) device_type(any) +// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// host-5-and-51-error@+2 {{'device_type(host)' does not match previously specified 'device_type(any)' for the same declaration}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(MultiDevTy) device_type(host) +// omp52-error@+4 {{unexpected 'to' clause, use 'enter' instead}} +// omp52-error@+3 {{expected at least one 'enter', 'link' or 'indirect' clause}} +// no-host5-and-51-error@+2 {{'device_type(nohost)' does not match previously specified 'device_type(any)' for the same declaration}} +// omp45-error@+1 {{unexpected 'device_type' clause, only 'to' or 'link' clauses expected}} +#pragma omp declare target to(MultiDevTy) device_type(nohost) + +// expected-warning@+1 {{declaration is not declared in any declare target region}} +static int variable = 100; static float variable1 = 200; -static float variable2 = variable1; //expected-warning {{declaration is not declared in any declare target region}} +// expected-warning@+1 {{declaration is not declared in any declare target region}} +static float variable2 = variable1; -static int var = 1; //expected-warning {{declaration is not declared in any declare target region}} +// expected-warning@+1 {{declaration is not declared in any declare target region}} +static int var = 1; static int var1 = 10; static int *var2 = &var1; -static int **ptr1 = &var2; //expected-warning {{declaration is not declared in any declare target region}} +// expected-warning@+1 {{declaration is not declared in any declare target region}} +static int **ptr1 = &var2; int arr[2] = {1,2}; -int (*arrptr)[2] = &arr; //expected-warning {{declaration is not declared in any declare target region}} +// expected-warning@+1 {{declaration is not declared in any declare target region}} +int (*arrptr)[2] = &arr; class declare{ public: int x; void print(); }; declare obj1; -declare *obj2 = &obj1; //expected-warning {{declaration is not declared in any declare target region}} +// expected-warning@+1 {{declaration is not declared in any declare target region}} +declare *obj2 = &obj1; struct target{ int x; void print(); }; -static target S; //expected-warning {{declaration is not declared in any declare target region}} +// expected-warning@+1 {{declaration is not declared in any declare target region}} +static target S; #pragma omp declare target -int target_var = variable; //expected-note {{used here}} -float target_var1 = variable2; //expected-note {{used here}} -int *ptr = &var; //expected-note {{used here}} -int ***ptr2 = &ptr1; //expected-note {{used here}} -int (**ptr3)[2] = &arrptr; //expected-note {{used here}} -declare **obj3 = &obj2; //expected-note {{used here}} -target *S1 = &S; //expected-note {{used here}} +// expected-note@+1 {{used here}} +int target_var = variable; +// expected-note@+1 {{used here}} +float target_var1 = variable2; +// expected-note@+1 {{used here}} +int *ptr = &var; +// expected-note@+1 {{used here}} +int ***ptr2 = &ptr1; +// expected-note@+1 {{used here}} +int (**ptr3)[2] = &arrptr; +// expected-note@+1 {{used here}} +declare **obj3 = &obj2; +// expected-note@+1 {{used here}} +target *S1 = &S; #pragma omp end declare target #if TESTENDINC diff --git a/clang/test/OpenMP/declare_variant_ast_print.c b/clang/test/OpenMP/declare_variant_ast_print.c index 0df10263cde5e..9bd0b6d0d6162 100644 --- a/clang/test/OpenMP/declare_variant_ast_print.c +++ b/clang/test/OpenMP/declare_variant_ast_print.c @@ -20,6 +20,8 @@ int foo(void); #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm, xxx, ibm)}, device={kind(cpu, nohost)}) #pragma omp declare variant(foo) match(device={kind(host)}) #pragma omp declare variant(foo) match(device={kind(nohost), xxx}) +#pragma omp declare variant(foo) match(target_device={kind(host)}) +#pragma omp declare variant(foo) match(target_device={kind(nohost), xxx}) #pragma omp declare variant(foo) match(implementation={extension(match_all)}) #pragma omp declare variant(foo) match(implementation={extension(match_any)}) #pragma omp declare variant(foo) match(implementation={extension(match_none)}) @@ -29,6 +31,8 @@ int bar(void); // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_none)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_any)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={extension(match_all)}) +// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(nohost)}) +// CHECK-NEXT: #pragma omp declare variant(foo) match(target_device={kind(host)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(nohost)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(device={kind(host)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm)}, device={kind(cpu, nohost)}) diff --git a/clang/test/OpenMP/declare_variant_bind_to_decl.cpp b/clang/test/OpenMP/declare_variant_bind_to_decl.cpp index dca18abb36c89..34191417a3934 100644 --- a/clang/test/OpenMP/declare_variant_bind_to_decl.cpp +++ b/clang/test/OpenMP/declare_variant_bind_to_decl.cpp @@ -29,6 +29,6 @@ int main() { // CHECK-LABEL: define {{[^@]+}}@main // CHECK-SAME: () #[[ATTR1:[0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: call void @"_Z74foo$ompvariant$S2$s7$Pppc64le$Pppc64$S3$s9$Pmatch_any$Pbind_to_declarationv"() +// CHECK-NEXT: call void @{{"_Z[0-9]+foo\$ompvariant\$.*"}}() // CHECK-NEXT: ret i32 0 // diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c index 0ae276effd1be..14637d8200671 100644 --- a/clang/test/OpenMP/declare_variant_messages.c +++ b/clang/test/OpenMP/declare_variant_messages.c @@ -16,17 +16,17 @@ int foo(void); #pragma omp declare variant(foo) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foo) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foo) match // expected-error {{expected '(' after 'match'}} -#pragma omp declare variant(foo) match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} -#pragma omp declare variant(foo) match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} -#pragma omp declare variant(foo) match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} -#pragma omp declare variant(foo) match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} -#pragma omp declare variant(foo) match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} -#pragma omp declare variant(foo) match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} -#pragma omp declare variant(foo) match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} -#pragma omp declare variant(foo) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} -#pragma omp declare variant(foo) match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} -#pragma omp declare variant(foo) match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} -#pragma omp declare variant(foo) match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} +#pragma omp declare variant(foo) match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} +#pragma omp declare variant(foo) match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx=) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx=yyy) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx=yyy}) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} +#pragma omp declare variant(foo) match(xxx={) // expected-error {{expected ')'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} +#pragma omp declare variant(foo) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx={vvv, vvv}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx={vvv} xxx) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx={vvv}) xxx // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foo) match(implementation={xxx}) // expected-warning {{'xxx' is not a valid context selector for the context set 'implementation'; selector ignored}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foo) match(implementation={vendor}) // expected-warning {{the context selector 'vendor' in context set 'implementation' requires a context property defined in parentheses; selector ignored}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foo) match(implementation={vendor(}) // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'amd' 'arm' 'bsc' 'cray' 'fujitsu' 'gnu' 'ibm' 'intel' 'llvm' 'nec' 'nvidia' 'pgi' 'ti' 'unknown'}} expected-note {{to match this '('}} @@ -48,8 +48,18 @@ int foo(void); #pragma omp declare variant(foo) match(device={kind(score(5): host), kind(llvm)}) // expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('5'); score ignored}} expected-warning {{the context selector 'kind' was used already in the same 'omp declare variant' directive; selector ignored}} expected-note {{the previous context selector 'kind' used here}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foo) match(device={kind(score(5): nohost), vendor(llvm)}) // expected-warning {{the context selector 'kind' in the context set 'device' cannot have a score ('5'); score ignored}} expected-warning {{the context selector 'vendor' is not valid for the context set 'device'; selector ignored}} expected-note {{the context selector 'vendor' can be nested in the context set 'implementation'; try 'match(implementation={vendor(property)})'}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foo) match(implementation={extension("aaa")}) // expected-warning {{'aaa' is not a valid context property for the context selector 'extension' and the context set 'implementation'; property ignored}} expected-note {{context property options are: 'match_all' 'match_any' 'match_none'}} expected-note {{the ignored property spans until here}} +#pragma omp declare variant(foo) match(target_device={}) // expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'kind' 'device_num' 'arch' 'isa'}} expected-note {{the ignored selector spans until here}} +#pragma omp declare variant(foo) match(target_device={xxx}) // expected-warning {{'xxx' is not a valid context selector for the context set 'target_device'; selector ignored}} expected-note {{context selector options are: 'kind' 'device_num' 'arch' 'isa'}} expected-note {{the ignored selector spans until here}} +#pragma omp declare variant(foo) match(target_device={kind}) // expected-warning {{the context selector 'kind' in context set 'target_device' requires a context property defined in parentheses; selector ignored}} expected-note {{the ignored selector spans until here}} +#pragma omp declare variant(foo) match(target_device={kind(}) // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} expected-note {{to match this '('}} +#pragma omp declare variant(foo) match(target_device={kind()}) // expected-warning {{expected identifier or string literal describing a context property; property skipped}} expected-note {{context property options are: 'host' 'nohost' 'cpu' 'gpu' 'fpga' 'any'}} +#pragma omp declare variant(foo) match(target_device={device_num}) // expected-warning {{the context selector 'device_num' in context set 'target_device' requires a context property defined in parentheses; selector ignored}} expected-note {{the ignored selector spans until here}} +#pragma omp declare variant(foo) match(target_device={device_num()}) // expected-error {{expected expression}} +#pragma omp declare variant(foo) match(target_device={device_num(-1)}) // expected-error {{argument to 'device_num' clause must be a non-negative integer value}} +#pragma omp declare variant(foo) match(target_device={device_num(abc)}) // expected-error {{expected expression}} expected-error {{use of undeclared identifier 'abc'}} int bar(void); + #pragma omp declare variant(foo) match(implementation = {vendor(score(foo) :llvm)}) // expected-warning {{score expressions in the OpenMP context selector need to be constant; foo is not and will be ignored}} #pragma omp declare variant(foo) match(implementation = {vendor(score(foo()) :llvm)}) // expected-warning {{score expressions in the OpenMP context selector need to be constant; foo() is not and will be ignored}} #pragma omp declare variant(foo) match(implementation = {vendor(score() :llvm)}) // expected-error {{expected expression}} expected-error {{use of undeclared identifier 'expr'}} expected-error {{expected expression}} @@ -64,10 +74,10 @@ int score_and_cond_non_const(void); #pragma omp declare variant(foo) match(construct={for simd}) // expected-error {{expected ')'}} expected-warning {{expected '}' after the context selectors for the context set "construct"; '}' assumed}} expected-note {{to match this '('}} omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} int construct(void); -#pragma omp declare variant(foo) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int a; // expected-error {{'#pragma omp declare variant' can only be applied to functions}} -#pragma omp declare variant(foo) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp threadprivate(a) // expected-error {{'#pragma omp declare variant' can only be applied to functions}} int var; #pragma omp threadprivate(var) @@ -91,21 +101,21 @@ int main(void); int main(void); -#pragma omp declare variant(foo) match(xxx={}) // expected-error {{single declaration is expected after 'declare variant' directive}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foo) match(xxx={}) // expected-error {{single declaration is expected after 'declare variant' directive}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int b, c; int no_proto(); -#pragma omp declare variant(no_proto) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(no_proto) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int no_proto_too(); int proto1(int); -#pragma omp declare variant(proto1) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(proto1) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int diff_proto(); // expected-note {{previous declaration is here}} int diff_proto(double); // expected-error {{conflicting types for 'diff_proto'}} -#pragma omp declare variant(no_proto) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(no_proto) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int diff_proto1(double); int after_use_variant(void); @@ -124,24 +134,24 @@ void self_test(int n, int d_no) { self(n); } -#pragma omp declare variant(after_use_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{'#pragma omp declare variant' cannot be applied for function after first usage; the original function might be used}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(after_use_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{'#pragma omp declare variant' cannot be applied for function after first usage; the original function might be used}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int after_use(void); -#pragma omp declare variant(after_use_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(after_use_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int defined(void) { return 0; } int defined1(void) { return 0; } -#pragma omp declare variant(after_use_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{'#pragma omp declare variant' cannot be applied to the function that was defined already; the original function might be used}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(after_use_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{'#pragma omp declare variant' cannot be applied to the function that was defined already; the original function might be used}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int defined1(void); int diff_cc_variant(void); -#pragma omp declare variant(diff_cc_variant) match(xxx={}) // expected-error {{variant in '#pragma omp declare variant' with type 'int (void)' is incompatible with type 'int (void) __attribute__((vectorcall))'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(diff_cc_variant) match(xxx={}) // expected-error {{variant in '#pragma omp declare variant' with type 'int (void)' is incompatible with type 'int (void) __attribute__((vectorcall))'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} __vectorcall int diff_cc(void); int diff_ret_variant(void); -#pragma omp declare variant(diff_ret_variant) match(xxx={}) // expected-error {{variant in '#pragma omp declare variant' with type 'int (void)' is incompatible with type 'void (void)'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(diff_ret_variant) match(xxx={}) // expected-error {{variant in '#pragma omp declare variant' with type 'int (void)' is incompatible with type 'void (void)'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} void diff_ret(void); void incompat_attr_variant(void); @@ -173,7 +183,7 @@ void not_marked(void); #pragma omp declare variant(not_marked) match(implementation={vendor(unknown)}, device={kind(cpu)}) // expected-note {{marked as 'declare variant' here}} void marked_variant(void); -#pragma omp declare variant(marked_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(marked_variant) match(xxx={}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-warning {{variant function in '#pragma omp declare variant' is itself marked as '#pragma omp declare variant'}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} void marked(void); #pragma omp declare variant(foo) match(device = {isa("foo")}) @@ -214,3 +224,4 @@ int conflicting_nested_score(void); #pragma omp declare variant(foo) match(user = {condition(1)}) // expected-error {{nested user conditions in OpenMP context selector not supported (yet)}} int conflicting_nested_condition(void); #pragma omp end declare variant + diff --git a/clang/test/OpenMP/declare_variant_messages.cpp b/clang/test/OpenMP/declare_variant_messages.cpp index b8a806e7ef75b..2d6e5bfc1f2f2 100644 --- a/clang/test/OpenMP/declare_variant_messages.cpp +++ b/clang/test/OpenMP/declare_variant_messages.cpp @@ -21,8 +21,8 @@ T foofoo(); #pragma omp declare variant(foofoo ) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo ) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo ) match // expected-error {{expected '(' after 'match'}} -#pragma omp declare variant(foofoo ) match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} -#pragma omp declare variant(foofoo ) match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foofoo ) match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} +#pragma omp declare variant(foofoo ) match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp declare variant(foofoo ) match(implementation) // expected-warning {{expected '=' after the context set name "implementation"; '=' assumed}} expected-warning {{expected '{' after the '=' that follows the context set name "implementation"; '{' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-warning {{expected '}' after the context selectors for the context set "implementation"; '}' assumed}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foofoo ) match(implementation =) // expected-warning {{expected '{' after the '=' that follows the context set name "implementation"; '{' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-warning {{expected '}' after the context selectors for the context set "implementation"; '}' assumed}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foofoo ) match(implementation = yyy) // expected-warning {{expected '{' after the '=' that follows the context set name "implementation"; '{' assumed}} expected-warning {{'yyy' is not a valid context selector for the context set 'implementation'; selector ignored}} expected-warning {{expected '}' after the context selectors for the context set "implementation"; '}' assumed}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} @@ -63,8 +63,8 @@ int bar(); #pragma omp declare variant(foofoo ) // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo ) xxx // omp50-error {{expected 'match' clause on 'omp declare variant' directive}} omp51-error {{expected 'match', 'adjust_args', or 'append_args' clause on 'omp declare variant' directive}} #pragma omp declare variant(foofoo ) match // expected-error {{expected '(' after 'match'}} -#pragma omp declare variant(foofoo ) match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} -#pragma omp declare variant(foofoo ) match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(foofoo ) match( // expected-error {{expected ')'}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} expected-note {{to match this '('}} +#pragma omp declare variant(foofoo ) match() // expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp declare variant(foofoo ) match(implementation) // expected-warning {{expected '=' after the context set name "implementation"; '=' assumed}} expected-warning {{expected '{' after the '=' that follows the context set name "implementation"; '{' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-warning {{expected '}' after the context selectors for the context set "implementation"; '}' assumed}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foofoo ) match(implementation =) // expected-warning {{expected '{' after the '=' that follows the context set name "implementation"; '{' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-warning {{expected '}' after the context selectors for the context set "implementation"; '}' assumed}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} #pragma omp declare variant(foofoo ) match(implementation = {) // expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-warning {{expected '}' after the context selectors for the context set "implementation"; '}' assumed}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} @@ -200,7 +200,7 @@ int after_use(void); int fn(); int fn(int); -#pragma omp declare variant(fn) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(fn) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int overload(void); int fn1(); @@ -211,7 +211,7 @@ int overload1(float); int fn_constexpr_variant(); -#pragma omp declare variant(fn_constexpr_variant) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(fn_constexpr_variant) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} constexpr int fn_constexpr(); // expected-error {{'#pragma omp declare variant' does not support constexpr functions}} constexpr int fn_constexpr_variant1(); @@ -221,7 +221,7 @@ int fn_constexpr1(); int fn_sc_variant(); -#pragma omp declare variant(fn_sc_variant) match(xxx = {}) // expected-error {{function with '#pragma omp declare variant' has a different storage class}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(fn_sc_variant) match(xxx = {}) // expected-error {{function with '#pragma omp declare variant' has a different storage class}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} static int fn_sc(); static int fn_sc_variant1(); @@ -231,7 +231,7 @@ int fn_sc1(); int fn_inline_variant(); -#pragma omp declare variant(fn_inline_variant) match(xxx = {}) // expected-error {{function with '#pragma omp declare variant' has a different inline specification}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(fn_inline_variant) match(xxx = {}) // expected-error {{function with '#pragma omp declare variant' has a different inline specification}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} inline int fn_inline(); inline int fn_inline_variant1(); @@ -240,7 +240,7 @@ inline int fn_inline_variant1(); int fn_inline1(); auto fn_deduced_variant() { return 0; } -#pragma omp declare variant(fn_deduced_variant) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(fn_deduced_variant) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int fn_deduced(); int fn_deduced_variant1(); @@ -254,7 +254,7 @@ auto fn_deduced3(); auto fn_deduced_variant2() { return 0; } -#pragma omp declare variant(fn_deduced_variant2) match(xxx = {}) // expected-error {{variant in '#pragma omp declare variant' with type 'int ()' is incompatible with type 'float ()'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(fn_deduced_variant2) match(xxx = {}) // expected-error {{variant in '#pragma omp declare variant' with type 'int ()' is incompatible with type 'float ()'}} expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} float fn_deduced2(); @@ -266,7 +266,7 @@ int fn_except() noexcept(false); // expected-note {{previous declaration is here int fn_except_variant1() noexcept(false); // expected-error {{exception specification in declaration does not match previous declaration}} -#pragma omp declare variant(fn_except_variant1) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(fn_except_variant1) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} int fn_except1() noexcept(true); // expected-note {{previous declaration is here}} struct SpecialFuncs { @@ -275,7 +275,7 @@ struct SpecialFuncs { #pragma omp declare variant(SpecialFuncs::vd) match(implementation = {}) // expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} SpecialFuncs(); // expected-error {{'#pragma omp declare variant' does not support constructors}} -#pragma omp declare variant(SpecialFuncs::vd) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(SpecialFuncs::vd) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} ~SpecialFuncs(); // expected-error {{'#pragma omp declare variant' does not support destructors}} void baz(); @@ -288,14 +288,14 @@ struct SpecialFuncs { #pragma omp declare variant(SpecialFuncs::dar) match(construct={dispatch}) // expected-error {{'#pragma omp declare variant' does not support virtual functions}} #pragma omp declare variant(SpecialFuncs::baz) match(implementation = {}) // expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} -#pragma omp declare variant(SpecialFuncs::bar) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(SpecialFuncs::bar) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} #pragma omp declare variant(fn_sc_variant1) match(implementation = {}) // expected-error {{variant in '#pragma omp declare variant' with type 'int (*)()' is incompatible with type 'void (SpecialFuncs::*)()'}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} void foo1(); SpecialFuncs& foo(const SpecialFuncs&); SpecialFuncs& bar(SpecialFuncs&&); -#pragma omp declare variant(SpecialFuncs::foo) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp declare variant(SpecialFuncs::foo) match(xxx = {}) // expected-warning {{'xxx' is not a valid context set in a `declare variant`; set ignored}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} SpecialFuncs& operator=(const SpecialFuncs&) = default; // expected-error {{'#pragma omp declare variant' does not support defaulted functions}} #pragma omp declare variant(SpecialFuncs::bar) match(implementation = {}) // expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} diff --git a/clang/test/OpenMP/depobj_messages.cpp b/clang/test/OpenMP/depobj_messages.cpp index 9d750f651d81f..a57ae0200e086 100644 --- a/clang/test/OpenMP/depobj_messages.cpp +++ b/clang/test/OpenMP/depobj_messages.cpp @@ -4,6 +4,8 @@ // RUN: -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 \ // RUN: -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=60 \ +// RUN: -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 \ // RUN: -ferror-limit 100 %s -Wuninitialized @@ -11,6 +13,8 @@ // RUN: -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 \ // RUN: -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=60 \ +// RUN: -ferror-limit 100 %s -Wuninitialized struct S1 { // expected-note 2 {{declared here}} int a; diff --git a/clang/test/OpenMP/distribute_parallel_for_ast_print.cpp b/clang/test/OpenMP/distribute_parallel_for_ast_print.cpp index 7af4e5f6b2b44..f91afd7ae1141 100644 --- a/clang/test/OpenMP/distribute_parallel_for_ast_print.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_ast_print.cpp @@ -7,6 +7,9 @@ // RUN: %clang_cc1 -verify -std=c++11 -fopenmp -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -verify -std=c++11 -fopenmp -fopenmp-version=60 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -verify -std=c++11 -fopenmp-simd -fopenmp-version=45 -ast-print %s -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s @@ -17,6 +20,9 @@ // RUN: %clang_cc1 -verify -std=c++11 -fopenmp-simd -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -verify -std=c++11 -fopenmp-simd -fopenmp-version=60 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // expected-no-diagnostics #ifndef HEADER diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp index ae3caa88d4547..0495bff45b72a 100644 --- a/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp @@ -7,6 +7,9 @@ // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s -Wno-openmp-mapping | FileCheck %s --check-prefix CHECK --check-prefix OMP45 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s @@ -17,6 +20,9 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix CHECK --check-prefix OMP51 // expected-no-diagnostics #ifndef HEADER diff --git a/clang/test/OpenMP/distribute_simd_ast_print.cpp b/clang/test/OpenMP/distribute_simd_ast_print.cpp index 9130203008311..0fbc0e1342a57 100644 --- a/clang/test/OpenMP/distribute_simd_ast_print.cpp +++ b/clang/test/OpenMP/distribute_simd_ast_print.cpp @@ -4,6 +4,11 @@ // RUN: %clang_cc1 -verify -fopenmp -ast-print %s -Wno-openmp-mapping -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -DOMP5 // RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50 + +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 + // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 @@ -20,6 +25,9 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ast-print %s -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -Wno-openmp-mapping -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // expected-no-diagnostics // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -Wno-openmp-mapping -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52 diff --git a/clang/test/OpenMP/distribute_simd_misc_messages.c b/clang/test/OpenMP/distribute_simd_misc_messages.c index f78b0ea8c56ce..8cbf96cd7a014 100644 --- a/clang/test/OpenMP/distribute_simd_misc_messages.c +++ b/clang/test/OpenMP/distribute_simd_misc_messages.c @@ -1,16 +1,20 @@ // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=45 -verify=expected,omp45 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -verify=expected,omp50 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -verify=expected,omp50,omp-50-and-later,omp-50-and-later-temporal,omp50-temporal,omp50-and-later-var %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=60 -verify=expected,omp60,omp-clause,omp-50-and-later,omp-50-and-later-temporal,omp50-temporal,omp50-and-later-var %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -verify=expected,omp51,omp-clause,omp-50-and-later,omp-50-and-later-temporal,omp50-temporal,omp50-and-later-var %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=45 -verify=expected,omp45 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -verify=expected,omp50 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -verify=expected,omp50,omp-50-and-later,omp-50-and-later-temporal,omp50-temporal,omp50-and-later-var %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=60 -verify=expected,omp60,omp-clause,omp-50-and-later,omp-50-and-later-temporal,omp50-temporal,omp50-and-later-var %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify=expected,omp51,omp-clause,omp-50-and-later,omp-50-and-later-temporal,omp50-temporal,omp50-and-later-var %s -Wuninitialized void xxx(int argc) { - int x; // expected-note {{initialize the variable 'x' to silence this warning}} + // expected-note@+1 {{initialize the variable 'x' to silence this warning}} + int x; #pragma omp distribute simd for (int i = 0; i < 10; ++i) - argc = x; // expected-warning {{variable 'x' is uninitialized when used here}} + // expected-warning@+1 {{variable 'x' is uninitialized when used here}} + argc = x; } // expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}} @@ -49,9 +53,11 @@ void test_branch_protected_scope(void) { #pragma omp distribute simd for (i = 0; i < 16; ++i) { if (i == 5) - goto L1; // expected-error {{use of undeclared label 'L1'}} + // expected-error@+1 {{use of undeclared label 'L1'}} + goto L1; else if (i == 6) - return; // expected-error {{cannot return from OpenMP region}} + // expected-error@+1 {{cannot return from OpenMP region}} + return; else if (i == 7) goto L2; else if (i == 8) { @@ -61,7 +67,8 @@ void test_branch_protected_scope(void) { } if (x[0] == 0) - goto L2; // expected-error {{use of undeclared label 'L2'}} + // expected-error@+1 {{use of undeclared label 'L2'}} + goto L2; else if (x[1] == 1) goto L1; } @@ -411,41 +418,49 @@ void test_collapse(void) { // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp distribute simd collapse(4 for (i = 0; i < 16; ++i) - ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +// expected-error@+1 {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + ; #pragma omp target #pragma omp teams // expected-error@+2 {{expected ')'}} // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp distribute simd collapse(4, for (i = 0; i < 16; ++i) - ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +// expected-error@+1 {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + ; #pragma omp target #pragma omp teams // expected-error@+2 {{expected ')'}} // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp distribute simd collapse(4, ) for (i = 0; i < 16; ++i) - ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +// expected-error@+1 {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + ; #pragma omp target #pragma omp teams -// xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}} +// expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp distribute simd collapse(4) for (i = 0; i < 16; ++i) - ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +// expected-error@+1 {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + ; #pragma omp target #pragma omp teams -// expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} +// expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp distribute simd collapse(4 4) for (i = 0; i < 16; ++i) - ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +// expected-error@+1 {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + ; #pragma omp target #pragma omp teams -// expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} +// expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp distribute simd collapse(4, , 4) for (i = 0; i < 16; ++i) - ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +// expected-error@+1 {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + ; #pragma omp target #pragma omp teams #pragma omp distribute simd collapse(4) @@ -456,11 +471,13 @@ void test_collapse(void) { foo(); #pragma omp target #pragma omp teams -// expected-error@+2 {{expected ')'}} -// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} +// expected-note@+1 {{as specified in 'collapse' clause}} #pragma omp distribute simd collapse(4, 8) for (i = 0; i < 16; ++i) - ; // expected-error {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} +// expected-error@+1 {{expected 4 for loops after '#pragma omp distribute simd', but found only 1}} + ; #pragma omp target #pragma omp teams // expected-error@+1 {{integer constant expression}} @@ -719,14 +736,16 @@ void test_private(void) { int i; #pragma omp target #pragma omp teams -// expected-error@+2 {{expected expression}} -// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +// expected-error@+3 {{expected expression}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} #pragma omp distribute simd private( for (i = 0; i < 16; ++i) ; #pragma omp target #pragma omp teams -// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} // expected-error@+1 2 {{expected expression}} #pragma omp distribute simd private(, for (i = 0; i < 16; ++i) @@ -779,7 +798,8 @@ void test_firstprivate(void) { int i; #pragma omp target #pragma omp teams -// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} // expected-error@+1 {{expected expression}} #pragma omp distribute simd firstprivate( for (i = 0; i < 16; ++i) @@ -790,7 +810,8 @@ void test_lastprivate(void) { int i; #pragma omp target #pragma omp teams -// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} // expected-error@+1 {{expected expression}} #pragma omp distribute simd lastprivate( for (i = 0; i < 16; ++i) @@ -798,7 +819,8 @@ void test_lastprivate(void) { #pragma omp target #pragma omp teams -// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} // expected-error@+1 2 {{expected expression}} #pragma omp distribute simd lastprivate(, for (i = 0; i < 16; ++i) @@ -850,7 +872,8 @@ void test_reduction(void) { int i, x, y; #pragma omp target #pragma omp teams -// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+4 {{expected ')'}} +// expected-note@+3 {{to match this '('}} // expected-error@+2 {{expected identifier}} // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} #pragma omp distribute simd reduction( @@ -878,7 +901,8 @@ void test_reduction(void) { ; #pragma omp target #pragma omp teams -// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+4 {{expected ')'}} +// expected-note@+3 {{to match this '('}} // expected-error@+2 {{expected identifier}} // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} #pragma omp distribute simd reduction(, @@ -886,7 +910,8 @@ void test_reduction(void) { ; #pragma omp target #pragma omp teams -// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} +// expected-error@+4 {{expected ')'}} +// expected-note@+3 {{to match this '('}} // expected-error@+2 {{expected expression}} // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}} #pragma omp distribute simd reduction(+ @@ -895,8 +920,8 @@ void test_reduction(void) { #pragma omp target #pragma omp teams -// expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}} -// +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} // expected-error@+1 {{expected expression}} #pragma omp distribute simd reduction(+: for (i = 0; i < 16; ++i) @@ -938,6 +963,7 @@ void test_reduction(void) { ; #pragma omp target #pragma omp teams + // omp60-error@+1 {{incorrect reduction identifier, expected one of '+', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}} #pragma omp distribute simd reduction(- : x) for (i = 0; i < 16; ++i) ; @@ -1020,77 +1046,103 @@ void linear_modifiers(int argc) { for (k = 0; k < argc; ++k) ++k; #pragma omp target #pragma omp teams + // omp60-error@+1 {{old syntax 'linear-modifier(list)' on 'linear' clause was deprecated, use new syntax 'linear(list: [linear-modifier,] step(step-size))'}} #pragma omp distribute simd linear(val(k)) for (k = 0; k < argc; ++k) ++k; #pragma omp target #pragma omp teams -#pragma omp distribute simd linear(uval(k)) // expected-error {{expected 'val' modifier}} + // omp60-error@+2 {{old syntax 'linear-modifier(list)' on 'linear' clause was deprecated, use new syntax 'linear(list: [linear-modifier,] step(step-size))'}} + // expected-error@+1 {{expected 'val' modifier}} +#pragma omp distribute simd linear(uval(k)) for (k = 0; k < argc; ++k) ++k; #pragma omp target #pragma omp teams -#pragma omp distribute simd linear(ref(k)) // expected-error {{expected 'val' modifier}} +// omp60-error@+2 {{old syntax 'linear-modifier(list)' on 'linear' clause was deprecated, use new syntax 'linear(list: [linear-modifier,] step(step-size))'}} +// expected-error@+1 {{expected 'val' modifier}} +#pragma omp distribute simd linear(ref(k)) for (k = 0; k < argc; ++k) ++k; #pragma omp target #pragma omp teams -#pragma omp distribute simd linear(foo(k)) // expected-error {{expected 'val' modifier}} +// omp60-error@+2 {{old syntax 'linear-modifier(list)' on 'linear' clause was deprecated, use new syntax 'linear(list: [linear-modifier,] step(step-size))'}} +// expected-error@+1 {{expected 'val' modifier}} +#pragma omp distribute simd linear(foo(k)) for (k = 0; k < argc; ++k) ++k; } void test_nontemporal(void) { int i; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +// omp45-error@+4 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+3 {{expected expression}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} #pragma omp distribute simd nontemporal( for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 2 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +// omp45-error@+4 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+3 2 {{expected expression}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} #pragma omp distribute simd nontemporal(, for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 2 {{expected expression}} +// omp45-error@+2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+1 2 {{expected expression}} #pragma omp distribute simd nontemporal(, ) for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{expected expression}} +// omp45-error@+2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+1 {{expected expression}} #pragma omp distribute simd nontemporal() for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{expected expression}} +// omp45-error@+2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+1 {{expected expression}} #pragma omp distribute simd nontemporal(int) for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} omp50-error@+1 {{expected variable name}} omp51-error@+1 {{expected variable name}} +// omp45-error@+2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// omp50-and-later-var-error@+1 {{expected variable name}} #pragma omp distribute simd nontemporal(0) for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{use of undeclared identifier 'x'}} +// omp45-error@+2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+1 {{use of undeclared identifier 'x'}} #pragma omp distribute simd nontemporal(x) for (i = 0; i < 16; ++i) ; -// expected-error@+2 {{use of undeclared identifier 'x'}} -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{use of undeclared identifier 'y'}} +// expected-error@+3 {{use of undeclared identifier 'x'}} +// omp45-error@+2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+1 {{use of undeclared identifier 'y'}} #pragma omp distribute simd nontemporal(x, y) for (i = 0; i < 16; ++i) ; -// expected-error@+3 {{use of undeclared identifier 'x'}} -// expected-error@+2 {{use of undeclared identifier 'y'}} -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{use of undeclared identifier 'z'}} +// expected-error@+4 {{use of undeclared identifier 'x'}} +// expected-error@+3 {{use of undeclared identifier 'y'}} +// omp45-error@+2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+1 {{use of undeclared identifier 'z'}} #pragma omp distribute simd nontemporal(x, y, z) for (i = 0; i < 16; ++i) ; int x, y; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{expected ',' or ')' in 'nontemporal' clause}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} +// omp45-error@+4 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+3 {{expected ',' or ')' in 'nontemporal' clause}} +// expected-error@+2 {{expected ')'}} +// expected-note@+1 {{to match this '('}} #pragma omp distribute simd nontemporal(x :) for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}} expected-error@+1 {{expected ',' or ')' in 'nontemporal' clause}} +// omp45-error@+4 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-error@+3 {{expected ')'}} +// expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected ',' or ')' in 'nontemporal' clause}} #pragma omp distribute simd nontemporal(x :, ) for (i = 0; i < 16; ++i) ; -// omp51-note@+3 {{defined as nontemporal}} -// omp50-note@+2 {{defined as nontemporal}} -// omp45-error@+1 2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} omp50-error@+1 {{a variable cannot appear in more than one nontemporal clause}} omp51-error@+1 {{a variable cannot appear in more than one nontemporal clause}} +// omp50-temporal-note@+3 {{defined as nontemporal}} +// omp-50-and-later-temporal-error@+2 {{a variable cannot appear in more than one nontemporal clause}} +// omp45-error@+1 2 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} #pragma omp distribute simd nontemporal(x) nontemporal(x) for (i = 0; i < 16; ++i) ; @@ -1105,7 +1157,9 @@ void test_nontemporal(void) { for (i = 0; i < 16; ++i) ; -// omp45-error@+1 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} expected-note@+1 {{to match this '('}} expected-error@+1 {{expected ',' or ')' in 'nontemporal' clause}} expected-error@+1 {{expected ')'}} +// omp45-error@+3 {{unexpected OpenMP clause 'nontemporal' in directive '#pragma omp distribute simd'}} +// expected-note@+2 {{to match this '('}} +// expected-error@+1 {{expected ',' or ')' in 'nontemporal' clause}} expected-error@+1 {{expected ')'}} #pragma omp distribute simd nontemporal(x, y : 0) for (i = 0; i < 16; ++i) ; @@ -1119,35 +1173,60 @@ void test_nontemporal(void) { #pragma omp distribute simd lastprivate(x) nontemporal(x) for (i = 0; i < 16; ++i) ; -#pragma omp distribute simd order // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} expected-error {{expected '(' after 'order'}} +// omp45-error@+2 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +// expected-error@+1 {{expected '(' after 'order'}} +#pragma omp distribute simd order for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order( // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} omp51-error {{expected 'concurrent' in OpenMP clause 'order'}} +// omp-50-and-later-error@+4 {{expected 'concurrent' in OpenMP clause 'order'}} +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order( for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(none // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} omp51-error {{expected 'concurrent' in OpenMP clause 'order'}} +// omp-50-and-later-error@+4 {{expected 'concurrent' in OpenMP clause 'order'}} +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(none for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(concurrent // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +// expected-note@+3 {{to match this '('}} +// expected-error@+2 {{expected ')'}} +// omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(concurrent for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(concurrent) // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +// omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(concurrent) for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(unconstrained:) // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} omp51-error {{expected 'concurrent' in OpenMP clause 'order'}} + // omp-50-and-later-error@+2 {{expected 'concurrent' in OpenMP clause 'order'}} + // omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(unconstrained:) for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(reproducible:concurrent // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} + // omp50-error@+4 {{expected 'concurrent' in OpenMP clause 'order'}} + // expected-note@+3 {{to match this '('}} + // expected-error@+2 {{expected ')'}} + // omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(reproducible:concurrent for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(reproducible:concurrent) // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} + // omp50-error@+2 {{expected 'concurrent' in OpenMP clause 'order'}} + // omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(reproducible:concurrent) for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(unconstrained:concurrent) // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} + // omp50-error@+2 {{expected 'concurrent' in OpenMP clause 'order'}} + // omp45-error@+1 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(unconstrained:concurrent) for (int i = 0; i < 10; ++i) ; -#pragma omp distribute simd order(concurrent) order(concurrent) // omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} omp45-error {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} omp51-error {{directive '#pragma omp distribute simd' cannot contain more than one 'order' clause}} + // omp-clause-error@+2 {{directive '#pragma omp distribute simd' cannot contain more than one 'order' clause}} + // omp45-error@+1 2 {{unexpected OpenMP clause 'order' in directive '#pragma omp distribute simd'}} +#pragma omp distribute simd order(concurrent) order(concurrent) for (int i = 0; i < 10; ++i) ; } - diff --git a/clang/test/OpenMP/driver.c b/clang/test/OpenMP/driver.c index 0e9b2f71aae40..9ed791ba99da7 100644 --- a/clang/test/OpenMP/driver.c +++ b/clang/test/OpenMP/driver.c @@ -15,9 +15,11 @@ // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=1 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=0 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=100 | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=60 | FileCheck --check-prefix=CHECK-60-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp=libomp | FileCheck --check-prefix=CHECK-DEFAULT-VERSION %s // CHECK-DEFAULT-VERSION: #define _OPENMP 202011 +// CHECK-60-VERSION: #define _OPENMP 202411 // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=31 | FileCheck --check-prefix=CHECK-31-VERSION %s // CHECK-31-VERSION: #define _OPENMP 201107 @@ -33,6 +35,8 @@ // RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=50 | FileCheck --check-prefix=CHECK-50-VERSION %s // CHECK-50-VERSION: #define _OPENMP 201811 +// RUN: %clang %s -c -E -dM -fopenmp=libomp -fopenmp-version=60 | FileCheck --check-prefix=CHECK-60-VERSION %s + // RUN: %clang %s -c -E -dM -fopenmp=libomp | FileCheck --check-prefix=CHECK-51-VERSION %s // CHECK-51-VERSION: #define _OPENMP 202011 @@ -52,6 +56,7 @@ // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=31 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=40 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=45 | FileCheck --check-prefix=CHECK-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=60 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd | FileCheck --check-prefix=CHECK-VERSION %s // CHECK-VERSION-NOT: #define _OPENMP diff --git a/clang/test/OpenMP/error_ast_print.cpp b/clang/test/OpenMP/error_ast_print.cpp index 8e40f7da71324..43c6d8553dfde 100644 --- a/clang/test/OpenMP/error_ast_print.cpp +++ b/clang/test/OpenMP/error_ast_print.cpp @@ -2,9 +2,17 @@ // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -fopenmp-version=51 -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-version=51 -include-pch %t -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -fopenmp-version=60 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -fopenmp-version=60 -include-pch %t -verify %s -ast-print | FileCheck %s + // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s | FileCheck %s // RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -fopenmp-version=51 -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -std=c++11 -fopenmp-version=51 -include-pch %t -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -fopenmp-version=60 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -fopenmp-version=60 -include-pch %t -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER diff --git a/clang/test/OpenMP/error_codegen.cpp b/clang/test/OpenMP/error_codegen.cpp index 0f4d1863e69fc..70d493e01a709 100644 --- a/clang/test/OpenMP/error_codegen.cpp +++ b/clang/test/OpenMP/error_codegen.cpp @@ -1,23 +1,30 @@ // RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=51 -triple x86_64 \ // RUN: -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -fopenmp -fopenmp-version=60 -triple x86_64 \ +// RUN: -emit-llvm -o - %s | FileCheck %s + // RUN: %clang_cc1 -std=c++11 -fopenmp-simd -fopenmp-version=51 \ // RUN: -debug-info-kind=limited -triple x86_64 -emit-llvm -o - %s | \ // RUN: FileCheck --check-prefix SIMD %s +// RUN: %clang_cc1 -std=c++11 -fopenmp-simd -fopenmp-version=60 \ +// RUN: -debug-info-kind=limited -triple x86_64 -emit-llvm -o - %s | \ +// RUN: FileCheck --check-prefix SIMD %s + //CHECK: @.str = private unnamed_addr constant [23 x i8] c"GPU compiler required.\00", align 1 -//CHECK: @0 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;52;1;;\00", align 1 +//CHECK: @0 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;59;1;;\00", align 1 //CHECK: @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @0 }, align 8 //CHECK: @.str.1 = private unnamed_addr constant [27 x i8] c"Note this is functioncall.\00", align 1 -//CHECK: @2 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;54;1;;\00", align 1 +//CHECK: @2 = private unnamed_addr constant {{.*}}error_codegen.cpp;main;61;1;;\00", align 1 //CHECK: @3 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @2 }, align 8 //CHECK: @.str.2 = private unnamed_addr constant [23 x i8] c"GNU compiler required.\00", align 1 -//CHECK: @4 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;29;1;;\00", align 1 +//CHECK: @4 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;36;1;;\00", align 1 //CHECK: @5 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @4 }, align 8 //CHECK: @.str.3 = private unnamed_addr constant [22 x i8] c"Notice: add for loop.\00", align 1 -//CHECK: @6 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;32;1;;\00", align 1 +//CHECK: @6 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;39;1;;\00", align 1 //CHECK: @7 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @6 }, align 8 -//CHECK: @8 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;38;1;;\00", align 1 +//CHECK: @8 = private unnamed_addr constant {{.*}}error_codegen.cpp;tmain;45;1;;\00", align 1 //CHECK: @9 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{.*}}, ptr @8 }, align 8 void foo() {} diff --git a/clang/test/OpenMP/error_message.cpp b/clang/test/OpenMP/error_message.cpp index 227cbf699777f..aed2df99ea8f6 100644 --- a/clang/test/OpenMP/error_message.cpp +++ b/clang/test/OpenMP/error_message.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ferror-limit 100 %s -Wuninitialized template T tmain(T argc) { diff --git a/clang/test/OpenMP/flush_ast_print.cpp b/clang/test/OpenMP/flush_ast_print.cpp index 768282422032f..484705e200eb6 100644 --- a/clang/test/OpenMP/flush_ast_print.cpp +++ b/clang/test/OpenMP/flush_ast_print.cpp @@ -2,9 +2,17 @@ // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s + // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s | FileCheck %s // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER diff --git a/clang/test/OpenMP/flush_codegen.cpp b/clang/test/OpenMP/flush_codegen.cpp index fa2586d9fe258..022bf856d82c9 100644 --- a/clang/test/OpenMP/flush_codegen.cpp +++ b/clang/test/OpenMP/flush_codegen.cpp @@ -5,10 +5,22 @@ // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -fopenmp-enable-irbuilder -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -fopenmp-enable-irbuilder -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -fopenmp-enable-irbuilder -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s + // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s // SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} // expected-no-diagnostics #ifndef HEADER #define HEADER diff --git a/clang/test/OpenMP/for_linear_messages.cpp b/clang/test/OpenMP/for_linear_messages.cpp index d8d3391c0c271..6253a3032c0e3 100644 --- a/clang/test/OpenMP/for_linear_messages.cpp +++ b/clang/test/OpenMP/for_linear_messages.cpp @@ -1,8 +1,10 @@ // RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 -DOMP52 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=60 -DOMP52 %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 -DOMP52 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=60 -DOMP52 %s -Wuninitialized extern int omp_default_mem_alloc; diff --git a/clang/test/OpenMP/for_order_messages.cpp b/clang/test/OpenMP/for_order_messages.cpp index d38f48d2004f0..530c051849201 100644 --- a/clang/test/OpenMP/for_order_messages.cpp +++ b/clang/test/OpenMP/for_order_messages.cpp @@ -1,8 +1,12 @@ // RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=50 -triple x86_64-unknown-unknown -verify=expected,omp50 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=51 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=52 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp -fopenmp-version=60 -triple x86_64-unknown-unknown -verify=expected,omp60 %s -Wuninitialized // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=50 -triple x86_64-unknown-unknown -verify=expected,omp50 %s -Wuninitialized -// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=51 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=52 -triple x86_64-unknown-unknown -verify=expected,omp51 %s -Wuninitialized +// RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -fopenmp-version=60 -triple x86_64-unknown-unknown -verify=expected,omp60 %s -Wuninitialized extern int omp_get_num_threads (void); @@ -35,13 +39,61 @@ int main(int argc, char **argv) { #pragma omp parallel for order(reproducible: concurrent) // omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} for (int i = 0; i < 10; ++i) { -#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} +#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} omp60-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} A++; } #pragma omp parallel for order(unconstrained: concurrent) // omp50-error {{expected 'concurrent' in OpenMP clause 'order'}} for (int i = 0; i < 10; ++i) { -#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} +#pragma omp target //omp51-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} omp60-error {{construct 'target' not allowed in a region associated with a directive with 'order' clause}} A++; } + +#pragma omp loop bind(parallel) order(concurrent) + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for //omp60-error {{construct 'parallel for' not allowed in a region associated with a directive with 'order' clause}} + for (int j = 0; j < 10; ++j) { + A += j; + } + } + +#pragma omp distribute order(concurrent) + for (int i = 0; i < 10; ++i) { +#pragma omp parallel for simd //omp60-error {{construct 'parallel for simd' not allowed in a region associated with a directive with 'order' clause}} + for (int j = 0; j < 10; ++j) { + A += j; + } + } + +#pragma omp for order(concurrent) + for (int i = 0; i < 10; ++i) { +#pragma omp parallel master //omp60-error {{construct 'parallel master' not allowed in a region associated with a directive with 'order' clause}} + for (int j = 0; j < 10; ++j) { + A += j; + } + } + +#pragma omp for order(concurrent) + for (int i = 0; i < 10; ++i) { +#pragma omp parallel master taskloop //omp60-error {{construct 'parallel master taskloop' not allowed in a region associated with a directive with 'order' clause}} + for (int j = 0; j < 10; ++j) { + A += j; + } + } + +#pragma omp for order(concurrent) + for (int i = 0; i < 10; ++i) { +#pragma omp parallel master taskloop simd //omp60-error {{construct 'parallel master taskloop simd' not allowed in a region associated with a directive with 'order' clause}} + for (int j = 0; j < 10; ++j) { + A += j; + } + } + +#pragma omp for order(concurrent) + for (int i = 0; i < 10; ++i) { + #pragma omp parallel sections //omp60-error {{construct 'parallel sections' not allowed in a region associated with a directive with 'order' clause}} + { + A++; + } + } } diff --git a/clang/test/OpenMP/for_simd_ast_print.cpp b/clang/test/OpenMP/for_simd_ast_print.cpp index 7f77107b8ed7c..5ee0e3d7393b3 100644 --- a/clang/test/OpenMP/for_simd_ast_print.cpp +++ b/clang/test/OpenMP/for_simd_ast_print.cpp @@ -7,6 +7,9 @@ // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -ast-print %s -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52 +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=60 -ast-print %s -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52 // RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52 // RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52 // RUN: %clang_cc1 -fopenmp -fopenmp-version=52 -std=c++11 -include-pch %t -verify %s -ast-print -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52 @@ -20,6 +23,9 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -ast-print %s -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=51 -std=c++11 -include-pch %t -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=60 -ast-print %s -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP51 +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=60 -std=c++11 -include-pch %t -verify %s -ast-print -DOMP51 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP51 // expected-no-diagnostics // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=52 -ast-print %s -DOMP52 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP52 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=52 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP52 diff --git a/clang/test/OpenMP/metadirective_messages.cpp b/clang/test/OpenMP/metadirective_messages.cpp index b342a094a7870..7fce9fa446058 100644 --- a/clang/test/OpenMP/metadirective_messages.cpp +++ b/clang/test/OpenMP/metadirective_messages.cpp @@ -5,7 +5,7 @@ void foo() { #pragma omp metadirective // expected-error {{expected expression}} ; -#pragma omp metadirective when() // expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} +#pragma omp metadirective when() // expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}} expected-warning {{expected identifier or string literal describing a context set; set skipped}} expected-note {{context set options are: 'construct' 'device' 'target_device' 'implementation' 'user'}} expected-note {{the ignored set spans until here}} ; #pragma omp metadirective when(device{}) // expected-warning {{expected '=' after the context set name "device"; '=' assumed}} expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'kind' 'arch' 'isa'}} expected-note {{the ignored selector spans until here}} expected-error {{expected valid context selector in when clause}} expected-error {{expected expression}} ; diff --git a/clang/test/OpenMP/nvptx_declare_variant_name_mangling.cpp b/clang/test/OpenMP/nvptx_declare_variant_name_mangling.cpp index 0a5690e77a7b5..e128370d821e8 100644 --- a/clang/test/OpenMP/nvptx_declare_variant_name_mangling.cpp +++ b/clang/test/OpenMP/nvptx_declare_variant_name_mangling.cpp @@ -6,10 +6,10 @@ // CHECK-DAG: @_Z3barv // CHECK-DAG: @_Z3bazv -// CHECK-DAG: define{{.*}} @"_Z53bar$ompvariant$S2$s7$Pnvptx$Pnvptx64$S3$s9$Pmatch_anyv" -// CHECK-DAG: define{{.*}} @"_Z53baz$ompvariant$S2$s7$Pnvptx$Pnvptx64$S3$s9$Pmatch_anyv" -// CHECK-DAG: call noundef i32 @"_Z53bar$ompvariant$S2$s7$Pnvptx$Pnvptx64$S3$s9$Pmatch_anyv"() -// CHECK-DAG: call noundef i32 @"_Z53baz$ompvariant$S2$s7$Pnvptx$Pnvptx64$S3$s9$Pmatch_anyv"() +// CHECK-DAG: define{{.*}} @{{"_Z[0-9]+bar\$ompvariant\$.*"}} +// CHECK-DAG: define{{.*}} @{{"_Z[0-9]+baz\$ompvariant\$.*"}} +// CHECK-DAG: call noundef i32 @{{"_Z[0-9]+bar\$ompvariant\$.*"}}() +// CHECK-DAG: call noundef i32 @{{"_Z[0-9]+baz\$ompvariant\$.*"}}() #ifndef HEADER #define HEADER diff --git a/clang/test/OpenMP/nvptx_target_firstprivate_codegen.cpp b/clang/test/OpenMP/nvptx_target_firstprivate_codegen.cpp index d573f1cd193d6..94ace20826db4 100644 --- a/clang/test/OpenMP/nvptx_target_firstprivate_codegen.cpp +++ b/clang/test/OpenMP/nvptx_target_firstprivate_codegen.cpp @@ -90,7 +90,7 @@ int foo(int n, double *ptr) { ptr[0]++; } - // TCHECK: define weak_odr protected void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, ptr noundef [[PTR_IN:%.+]]) + // TCHECK: define weak_odr protected ptx_kernel void @__omp_offloading_{{.+}}(ptr {{[^,]+}}, ptr noundef [[PTR_IN:%.+]]) // TCHECK: [[DYN_PTR_ADDR:%.+]] = alloca ptr, // TCHECK: [[PTR_ADDR:%.+]] = alloca ptr, // TCHECK-NOT: alloca ptr, diff --git a/clang/test/OpenMP/nvptx_target_requires_unified_shared_memory.cpp b/clang/test/OpenMP/nvptx_target_requires_unified_shared_memory.cpp index c1bfe36507d14..2f2b8383bcceb 100644 --- a/clang/test/OpenMP/nvptx_target_requires_unified_shared_memory.cpp +++ b/clang/test/OpenMP/nvptx_target_requires_unified_shared_memory.cpp @@ -47,10 +47,10 @@ int bar(int n){ // CHECK-HOST: [[OFFLOAD_MAPTYPES:@.+]] = private unnamed_addr constant [2 x i64] [i64 800, i64 800] // CHECK-HOST: [[OMP_OFFLOAD_ENTRY_LINK_VAR_PTR_NAME:@.+]] = internal unnamed_addr constant [21 x i8] -// CHECK-HOST: [[OMP_OFFLOAD_ENTRY_LINK_VAR_PTR:@.+]] = weak{{.*}} constant %struct.__tgt_offload_entry { ptr [[VAR_DECL_TGT_LINK_PTR]], ptr [[OMP_OFFLOAD_ENTRY_LINK_VAR_PTR_NAME]], i64 8, i32 1, i32 0 }, section "omp_offloading_entries" +// CHECK-HOST: [[OMP_OFFLOAD_ENTRY_LINK_VAR_PTR:@.+]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 1, ptr [[VAR_DECL_TGT_LINK_PTR]], ptr [[OMP_OFFLOAD_ENTRY_LINK_VAR_PTR_NAME]], i64 8, i64 0, ptr null }, section "llvm_offload_entries" // CHECK-HOST: [[OMP_OFFLOAD_ENTRY_TO_VAR_PTR_NAME:@.+]] = internal unnamed_addr constant [24 x i8] -// CHECK-HOST: [[OMP_OFFLOAD_ENTRY_TO_VAR_PTR:@.+]] = weak{{.*}} constant %struct.__tgt_offload_entry { ptr [[VAR_DECL_TGT_TO_PTR]], ptr [[OMP_OFFLOAD_ENTRY_TO_VAR_PTR_NAME]], i64 8, i32 0, i32 0 }, section "omp_offloading_entries" +// CHECK-HOST: [[OMP_OFFLOAD_ENTRY_TO_VAR_PTR:@.+]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr [[VAR_DECL_TGT_TO_PTR]], ptr @.offloading.entry_name.1, i64 8, i64 0, ptr null }, section "llvm_offload_entries" // CHECK-HOST: [[N_CASTED:%.+]] = alloca i64 // CHECK-HOST: [[SUM_CASTED:%.+]] = alloca i64 diff --git a/clang/test/OpenMP/openmp_offload_registration.cpp b/clang/test/OpenMP/openmp_offload_registration.cpp index aff8d431650dc..be6d308fbda94 100644 --- a/clang/test/OpenMP/openmp_offload_registration.cpp +++ b/clang/test/OpenMP/openmp_offload_registration.cpp @@ -8,7 +8,7 @@ void foo(void) { {} } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // Check presence of foo() and the outlined target region // CHECK: define{{.*}} void [[FOO:@.+]]() diff --git a/clang/test/OpenMP/spirv_target_codegen_basic.cpp b/clang/test/OpenMP/spirv_target_codegen_basic.cpp new file mode 100644 index 0000000000000..fb2810e88c063 --- /dev/null +++ b/clang/test/OpenMP/spirv_target_codegen_basic.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -fopenmp-targets=spirv64-intel -emit-llvm-bc %s -o %t-host.bc +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple spirv64-intel -fopenmp-targets=spirv64-intel -emit-llvm %s -fopenmp-is-target-device -fopenmp-host-ir-file-path %t-host.bc -o - | FileCheck %s + +// expected-no-diagnostics + +// CHECK: @__omp_offloading_{{.*}}_dynamic_environment = weak_odr protected addrspace(1) global %struct.DynamicEnvironmentTy zeroinitializer +// CHECK: @__omp_offloading_{{.*}}_kernel_environment = weak_odr protected addrspace(1) constant %struct.KernelEnvironmentTy + +// CHECK: define weak_odr protected spir_kernel void @__omp_offloading_{{.*}} + +int main() { + int ret = 0; + #pragma omp target + for(int i = 0; i < 5; i++) + ret++; + return ret; +} diff --git a/clang/test/OpenMP/target_codegen.cpp b/clang/test/OpenMP/target_codegen.cpp index 1e38e9c3fe082..ff126fbe4d02c 100644 --- a/clang/test/OpenMP/target_codegen.cpp +++ b/clang/test/OpenMP/target_codegen.cpp @@ -67,12 +67,12 @@ // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } // CHECK-DAG: [[S1:%.+]] = type { double } // CHECK-DAG: [[S2:%.+]] = type { i32, i32, i32 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[ANON_T:%.+]] = type { ptr, i32, i32 } // CHECK-32-DAG: [[KMP_PRIVATES_T]] = type { [2 x i64], ptr, i32, [2 x ptr], [2 x ptr] } // CHECK-64-DAG: [[KMP_PRIVATES_T]] = type { ptr, [2 x ptr], [2 x ptr], [2 x i64], i32 } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // We have 9 target regions, but only 8 that actually will generate offloading // code and have mapped arguments, and only 6 have all-constant map sizes. @@ -180,7 +180,7 @@ int foo(int n) { local1 = global; } - // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}}) + // CHECK: call void [[HVT1:@.+]](i[[SZ:32|64]] {{[^,]+}}) #pragma omp target if(0) firstprivate(global) { global += 1; diff --git a/clang/test/OpenMP/target_codegen_registration.cpp b/clang/test/OpenMP/target_codegen_registration.cpp index 4927147d080f2..97994f0e3182a 100644 --- a/clang/test/OpenMP/target_codegen_registration.cpp +++ b/clang/test/OpenMP/target_codegen_registration.cpp @@ -51,9 +51,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -119,54 +119,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME1]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME2]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME3]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME4]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME5]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME6]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME7]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME8]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME9]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME10]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME11]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: @.offloading.entry.[[NAME12]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME1]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME2]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME3]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME4]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME5]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME6]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME7]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME8]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME9]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME10]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME11]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: @.offloading.entry.[[NAME12]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -401,31 +377,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 204, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 254, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 270, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 276, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 287, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 293, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 396, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 299, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 293, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 299, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 287, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 229, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 204, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 254, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 270, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 276, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 287, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 293, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 396, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 299, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 293, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 299, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 287, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 229, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_depend_codegen.cpp b/clang/test/OpenMP/target_depend_codegen.cpp index babd2843309f7..73ffa120452c1 100644 --- a/clang/test/OpenMP/target_depend_codegen.cpp +++ b/clang/test/OpenMP/target_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [3 x i64] [i64 0, i64 4, i64 {{16|12}}] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [3 x i64] [i64 544, i64 800, i64 3] @@ -79,7 +79,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], -// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) +// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr [[DEP_START:%.+]], i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr [[DEP_START]], i[[SZ]] 2 // CHECK: getelementptr %struct.kmp_depend_info, ptr [[DEP_START]], i[[SZ]] 3 diff --git a/clang/test/OpenMP/target_indirect_codegen.cpp b/clang/test/OpenMP/target_indirect_codegen.cpp index 974f8b20c0bfc..20a36c2935516 100644 --- a/clang/test/OpenMP/target_indirect_codegen.cpp +++ b/clang/test/OpenMP/target_indirect_codegen.cpp @@ -11,13 +11,13 @@ //. // HOST: @[[VAR:.+]] = global i8 0, align 1 // HOST: @[[FOO_ENTRY_NAME:.+]] = internal unnamed_addr constant [{{[0-9]+}} x i8] c"[[FOO_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_foo_l[0-9]+]]\00" -// HOST: @.offloading.entry.[[FOO_NAME]] = weak constant %struct.__tgt_offload_entry { ptr @_Z3foov, ptr @[[FOO_ENTRY_NAME]], i64 8, i32 8, i32 0 }, section "omp_offloading_entries", align 1 +// HOST: @.offloading.entry.[[FOO_NAME]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 8, ptr @_Z3foov, ptr @[[FOO_ENTRY_NAME]], i64 8, i64 0, ptr null } // HOST: @[[BAZ_ENTRY_NAME:.+]] = internal unnamed_addr constant [{{[0-9]+}} x i8] c"[[BAZ_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_baz_l[0-9]+]]\00" -// HOST: @.offloading.entry.[[BAZ_NAME]] = weak constant %struct.__tgt_offload_entry { ptr @_Z3bazv, ptr @[[BAZ_ENTRY_NAME]], i64 8, i32 8, i32 0 }, section "omp_offloading_entries", align 1 +// HOST: @.offloading.entry.[[BAZ_NAME]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 8, ptr @_Z3bazv, ptr @[[BAZ_ENTRY_NAME]], i64 8, i64 0, ptr null } // HOST: @[[VAR_ENTRY_NAME:.+]] = internal unnamed_addr constant [4 x i8] c"var\00" -// HOST: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @[[VAR]], ptr @[[VAR_ENTRY_NAME]], i64 1, i32 0, i32 0 }, section "omp_offloading_entries", align 1 +// HOST: @.offloading.entry.var = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @[[VAR]], ptr @[[VAR_ENTRY_NAME]], i64 1, i64 0, ptr null } // HOST: @[[BAR_ENTRY_NAME:.+]] = internal unnamed_addr constant [{{[0-9]+}} x i8] c"[[BAR_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_bar_l[0-9]+]]\00" -// HOST: @.offloading.entry.[[BAR_NAME]] = weak constant %struct.__tgt_offload_entry { ptr @_ZL3barv, ptr @[[BAR_ENTRY_NAME]], i64 8, i32 8, i32 0 }, section "omp_offloading_entries", align 1 +// HOST: @.offloading.entry.[[BAR_NAME]] = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 8, ptr @_ZL3barv, ptr @[[BAR_ENTRY_NAME]], i64 8, i64 0, ptr null } //. // DEVICE: @[[FOO_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_foo_l[0-9]+]] = protected addrspace(1) constant ptr @_Z3foov // DEVICE: @[[BAZ_NAME:__omp_offloading_[0-9a-z]+_[0-9a-z]+_baz_l[0-9]+]] = protected addrspace(1) constant ptr @_Z3bazv diff --git a/clang/test/OpenMP/target_parallel_codegen_registration.cpp b/clang/test/OpenMP/target_parallel_codegen_registration.cpp index dd3ec98bcfef7..0997a6f006b52 100644 --- a/clang/test/OpenMP/target_parallel_codegen_registration.cpp +++ b/clang/test/OpenMP/target_parallel_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -442,31 +418,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 295, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 311, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 317, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 437, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 270, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 295, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 311, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 317, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 437, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 270, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_parallel_depend_codegen.cpp b/clang/test/OpenMP/target_parallel_depend_codegen.cpp index 86c26523c2e14..52264ee79e123 100644 --- a/clang/test/OpenMP/target_parallel_depend_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], -// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) +// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_parallel_for_codegen_registration.cpp b/clang/test/OpenMP/target_parallel_for_codegen_registration.cpp index b65241109b0f8..653f5996d0142 100644 --- a/clang/test/OpenMP/target_parallel_for_codegen_registration.cpp +++ b/clang/test/OpenMP/target_parallel_for_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -452,31 +428,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp b/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp index 928ea0397571a..aec4feda15cf0 100644 --- a/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], - // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[IN:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) + // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[IN:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp b/clang/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp index 4c996c88de530..312ad5615ca1c 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -452,31 +428,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp b/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp index bb16edbb8a090..62f772ea79156 100644 --- a/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], - // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[IN:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) + // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[IN:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_simd_codegen.cpp b/clang/test/OpenMP/target_simd_codegen.cpp index e2ff3d5f53e44..c8ecaa814bafe 100644 --- a/clang/test/OpenMP/target_simd_codegen.cpp +++ b/clang/test/OpenMP/target_simd_codegen.cpp @@ -71,9 +71,9 @@ // CHECK-DAG: [[KMP_TASK_T]] = type { ptr, ptr, i32, %{{[^,]+}}, %{{[^,]+}} } // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } // CHECK-DAG: [[S1:%.+]] = type { double } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // We have 8 target regions, but only 7 that actually will generate offloading // code, only 6 will have mapped arguments, and only 4 have all-constant map @@ -136,7 +136,7 @@ int foo(int n) { for (int i = 3; i < 32; i += 5) { } - // CHECK: call void [[HVT1:@.+]](i[[SZ]] {{[^,]+}}, {{[^)]+}}) + // CHECK: call void [[HVT1:@.+]](i[[SZ:32|64]] {{[^,]+}}, {{[^)]+}}) long long k = get_val(); #pragma omp target simd if(target: 0) linear(k : 3) for (int i = 10; i > 1; i--) { diff --git a/clang/test/OpenMP/target_simd_codegen_registration.cpp b/clang/test/OpenMP/target_simd_codegen_registration.cpp index 4c0ca8947b3fc..69cfe5c8e200f 100644 --- a/clang/test/OpenMP/target_simd_codegen_registration.cpp +++ b/clang/test/OpenMP/target_simd_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -452,31 +428,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_simd_depend_codegen.cpp b/clang/test/OpenMP/target_simd_depend_codegen.cpp index d127078af5f4e..d813173dffbef 100644 --- a/clang/test/OpenMP/target_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_simd_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], -// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) +// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_teams_codegen_registration.cpp b/clang/test/OpenMP/target_teams_codegen_registration.cpp index 60c596853a64f..0627f7a822770 100644 --- a/clang/test/OpenMP/target_teams_codegen_registration.cpp +++ b/clang/test/OpenMP/target_teams_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -442,31 +418,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 295, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 311, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 317, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 437, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 270, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 295, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 311, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 317, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 437, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 340, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 328, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 270, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_teams_depend_codegen.cpp b/clang/test/OpenMP/target_teams_depend_codegen.cpp index 960c5980cbe68..b2280b80995fb 100644 --- a/clang/test/OpenMP/target_teams_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], -// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) +// CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_teams_distribute_codegen_registration.cpp b/clang/test/OpenMP/target_teams_distribute_codegen_registration.cpp index d619927d5bb80..21099be1dfc86 100644 --- a/clang/test/OpenMP/target_teams_distribute_codegen_registration.cpp +++ b/clang/test/OpenMP/target_teams_distribute_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -452,31 +428,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp index c0db03d29711f..f9306d3091ee8 100644 --- a/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], - // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) + // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp index 57e19df273825..4d93515c738ed 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], - // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) + // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp index f93ac400a2660..5a12a8de3d8fc 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -452,31 +428,31 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} #endif diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp index 15c116bad4b68..ed760d7e2e000 100644 --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_depend_codegen.cpp @@ -39,9 +39,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // CHECK-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -76,7 +76,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], - // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) + // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp b/clang/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp index 9814448d5a6b0..18acfc4f3b690 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_codegen_registration.cpp @@ -92,9 +92,9 @@ // CHECK-DAG: [[SE:%.+]] = type { [64 x i32] } // CHECK-DAG: [[ST1:%.+]] = type { [228 x i32] } // CHECK-DAG: [[ST2:%.+]] = type { [1128 x i32] } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // CHECK-DAG: [[A1:@.+]] = internal global [[SA]] // CHECK-DAG: [[A2:@.+]] ={{.*}} global [[SA]] @@ -160,54 +160,30 @@ // CHECK-NTARGET-NOT: private unnamed_addr constant [1 x i // CHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// CHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// CHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// CHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// CHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// CHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// CHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// CHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// CHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// CHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// CHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// CHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // CHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// CHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR1:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME1:__omp_offloading_[0-9a-f]+_[0-9a-f]+__Z.+_l[0-9]+]]\00" -// TCHECK-DAG: [[ENTRY1:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR1]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR2:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME2:.+]]\00" -// TCHECK-DAG: [[ENTRY2:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR2]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR3:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME3:.+]]\00" -// TCHECK-DAG: [[ENTRY3:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR3]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR4:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME4:.+]]\00" -// TCHECK-DAG: [[ENTRY4:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR4]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR5:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME5:.+]]\00" -// TCHECK-DAG: [[ENTRY5:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR5]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR6:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME6:.+]]\00" -// TCHECK-DAG: [[ENTRY6:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR6]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR7:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME7:.+]]\00" -// TCHECK-DAG: [[ENTRY7:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR7]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR8:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME8:.+]]\00" -// TCHECK-DAG: [[ENTRY8:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR8]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR9:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME9:.+]]\00" -// TCHECK-DAG: [[ENTRY9:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR9]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR10:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME10:.+]]\00" -// TCHECK-DAG: [[ENTRY10:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR10]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR11:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME11:.+]]\00" -// TCHECK-DAG: [[ENTRY11:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR11]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // TCHECK-DAG: [[NAMEPTR12:@.+]] = internal unnamed_addr constant [{{.*}} x i8] c"[[NAME12:.+]]\00" -// TCHECK-DAG: [[ENTRY12:@.+]] = weak{{.*}} constant [[ENTTY]] { ptr @{{.*}}, ptr [[NAMEPTR12]], i[[SZ]] 0, i32 0, i32 0 }, section "omp_offloading_entries", align 1 // We have 4 initializers, one for the 500 priority, another one for 501, or more for the default priority, and the last one for the offloading registration function. // CHECK: @llvm.global_ctors = appending global [3 x { i32, ptr, ptr }] [ @@ -452,32 +428,32 @@ int bar(int a){ // Check metadata is properly generated: // CHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// CHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK: !omp_offload.info = !{!{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}, !{{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 245, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 297, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 315, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 322, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 446, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 341, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 348, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 334, i32 0, i32 {{[0-9]+}}} -// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 271, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID:-?[0-9]+]], i32 [[FILEID:-?[0-9]+]], !"_ZN2SB3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SDD1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_Z3bari", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EEC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi1000EED1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2STILi100EE3fooEv", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} +// TCHECK-DAG: = !{i32 0, i32 [[DEVID]], i32 [[FILEID]], !"_ZN2SCC1Ev", i32 {{[0-9]+}}, i32 0, i32 {{[0-9]+}}} // TCHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true} // CHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true} diff --git a/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp b/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp index f3dfd1f10316f..9335c65bb2296 100644 --- a/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp +++ b/clang/test/OpenMP/target_teams_distribute_simd_depend_codegen.cpp @@ -48,9 +48,9 @@ #define HEADER // CHECK-DAG: [[TT:%.+]] = type { i64, i8 } -// CHECK-DAG: [[ENTTY:%.+]] = type { ptr, ptr, i[[SZ:32|64]], i32, i32 } +// CHECK-DAG: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// TCHECK: [[ENTTY:%.+]] = type { ptr, ptr, i{{32|64}}, i32, i32 } +// TCHECK: [[ENTTY:%.+]] = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } // OMP45-DAG: [[SIZET:@.+]] = private unnamed_addr constant [2 x i64] [i64 0, i64 4] // OMP45-DAG: [[MAPT:@.+]] = private unnamed_addr constant [2 x i64] [i64 544, i64 800] @@ -90,7 +90,7 @@ int foo(int n) { // CHECK: [[GEP:%.+]] = getelementptr inbounds nuw %{{.+}}, ptr %{{.+}}, i32 0, i32 0 // CHECK: [[DEV:%.+]] = load i32, ptr [[DEVICE_CAP]], // CHECK: store i32 [[DEV]], ptr [[GEP]], - // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) + // CHECK: [[TASK:%.+]] = call ptr @__kmpc_omp_task_alloc(ptr [[ID:@.+]], i32 [[GTID:%.+]], i32 1, i[[SZ:32|64]] {{20|40}}, i[[SZ]] 4, ptr [[TASK_ENTRY0:@.+]]) // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 0 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 1 // CHECK: getelementptr %struct.kmp_depend_info, ptr %{{.+}}, i[[SZ]] 2 diff --git a/clang/test/PCH/cuda-kernel-call.cu b/clang/test/PCH/cuda-kernel-call.cu index ffb0c1444fe69..da9d81c531c41 100644 --- a/clang/test/PCH/cuda-kernel-call.cu +++ b/clang/test/PCH/cuda-kernel-call.cu @@ -1,5 +1,7 @@ // RUN: %clang_cc1 -emit-pch -o %t %s // RUN: %clang_cc1 -include-pch %t -fsyntax-only %s +// RUN: %clang_cc1 -emit-pch -fcuda-is-device -o %t-device %s +// RUN: %clang_cc1 -fcuda-is-device -include-pch %t-device -fsyntax-only %s #ifndef HEADER #define HEADER @@ -14,12 +16,21 @@ void kcall(void (*kp)()) { __global__ void kern() { } +// Make sure that target overloaded functions remain +// available as overloads after PCH deserialization. +__host__ int overloaded_func(); +__device__ int overloaded_func(); + #else // Using the header. void test() { kcall(kern); kern<<<1, 1>>>(); + overloaded_func(); } +__device__ void test () { + overloaded_func(); +} #endif diff --git a/clang/test/Parser/cxx2c-binding-pack.cpp b/clang/test/Parser/cxx2c-binding-pack.cpp new file mode 100644 index 0000000000000..0daaad3a459ed --- /dev/null +++ b/clang/test/Parser/cxx2c-binding-pack.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2c -verify -fsyntax-only %s + +template +void decompose_array() { + int arr[4] = {1, 2, 3, 5}; + auto [x, ... // #1 + rest, ...more_rest] = arr; // expected-error{{multiple packs in structured binding declaration}} + // expected-note@#1{{previous binding pack specified here}} + + auto [y...] = arr; // expected-error{{'...' must immediately precede declared identifier}} + + auto [...] = arr; // #2 + // expected-error@#2{{expected identifier}} + // expected-error@#2{{{no names were provided}}} + // expected-warning@#2{{{does not allow a decomposition group to be empty}}} + auto [a, ..., b] = arr; // #3 + // expected-error@#3{{expected identifier}} + // expected-error@#3{{{only 1 name was provided}}} + auto [a1, ...] = arr; // #4 + // expected-error@#4{{expected identifier}} + // expected-error@#4{{{only 1 name was provided}}} + auto [..., b] = arr; // #5 + // expected-error@#5{{expected identifier}} + // expected-error@#5{{{no names were provided}}} +} diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c index 886a912713c58..f0698495a3cc2 100644 --- a/clang/test/ParserOpenACC/parse-constructs.c +++ b/clang/test/ParserOpenACC/parse-constructs.c @@ -109,30 +109,23 @@ void func() { for(int i = 0; i < 6;++i){} int i = 0, j = 0, k = 0; - // expected-warning@+1{{OpenACC construct 'atomic' not yet implemented, pragma ignored}} #pragma acc atomic - i = j; - // expected-error@+2{{invalid OpenACC clause 'garbage'}} - // expected-warning@+1{{OpenACC construct 'atomic' not yet implemented, pragma ignored}} + i = i + 1; + // expected-error@+1{{invalid OpenACC clause 'garbage'}} #pragma acc atomic garbage - i = j; - // expected-error@+2{{invalid OpenACC clause 'garbage'}} - // expected-warning@+1{{OpenACC construct 'atomic' not yet implemented, pragma ignored}} + i = i + 1; + // expected-error@+1{{invalid OpenACC clause 'garbage'}} #pragma acc atomic garbage clause list - i = j; - // expected-warning@+1{{OpenACC construct 'atomic' not yet implemented, pragma ignored}} + i = i + 1; #pragma acc atomic read i = j; - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'atomic' not yet implemented, pragma ignored}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc atomic write clause list i = i + j; - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'atomic' not yet implemented, pragma ignored}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc atomic update clause list i++; - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'atomic' not yet implemented, pragma ignored}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc atomic capture clause list i = j++; diff --git a/clang/test/Preprocessor/arm-target-features.c b/clang/test/Preprocessor/arm-target-features.c index ecf9d7eb5c19c..94dcfc2424bb1 100644 --- a/clang/test/Preprocessor/arm-target-features.c +++ b/clang/test/Preprocessor/arm-target-features.c @@ -1013,3 +1013,17 @@ // CHECK-MVE1_2: #define __ARM_FEATURE_MVE 1 // RUN: %clang -target arm-arm-none-eabi -march=armv8.1-m.main+mve.fp -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-MVE3 %s // CHECK-MVE3: #define __ARM_FEATURE_MVE 3 + +// Cortex-R52 and Cortex-R52Plus correctly enable the `fpv5-sp-d16` FPU when compiling for the SP only version of the CPU. +// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52+nosimd+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s +// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52plus+nosimd+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s +// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s +// RUN: %clang -target arm-none-eabi -mcpu=cortex-r52plus+nofp.dp -mfloat-abi=hard -x c -E -dM -o - %s | FileCheck -check-prefix=CHECK-R52 %s +// CHECK-R52: #define __ARM_FEATURE_FMA 1 +// CHECK-R52: #define __ARM_FP 0x6 +// CHECK-R52: #define __ARM_FPV5__ 1 +// CHECK-R52: #define __ARM_VFPV2__ 1 +// CHECK-R52-NEXT: #define __ARM_VFPV3__ 1 +// CHECK-R52-NEXT: #define __ARM_VFPV4__ 1 +// CHECK-R52-NOT: #define __ARM_NEON 1 +// CHECK-R52-NOT: #define __ARM_NEON__ diff --git a/clang/test/Preprocessor/builtin_aux_info.cpp b/clang/test/Preprocessor/builtin_aux_info.cpp deleted file mode 100644 index 60c8c6c492479..0000000000000 --- a/clang/test/Preprocessor/builtin_aux_info.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -fopenmp -triple=spirv64 -fopenmp-is-target-device \ -// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck -implicit-check-not=BAD %s - -// RUN: %clang_cc1 -fopenmp -triple=nvptx64 -fopenmp-is-target-device \ -// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck -implicit-check-not=BAD %s - -// RUN: %clang_cc1 -fopenmp -triple=amdgcn-amd-amdhsa -fopenmp-is-target-device \ -// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck -implicit-check-not=BAD %s - -// RUN: %clang_cc1 -fopenmp -triple=aarch64 -fopenmp-is-target-device \ -// RUN: -aux-triple x86_64-linux-unknown -E %s | FileCheck -implicit-check-not=BAD %s - -// CHECK: GOOD -#if __has_builtin(__builtin_ia32_pause) - BAD -#else - GOOD -#endif diff --git a/clang/test/Preprocessor/deprecate-threads-macro-definition-msvc1939.c b/clang/test/Preprocessor/deprecate-threads-macro-definition-msvc1939.c new file mode 100644 index 0000000000000..e197d8d403a3f --- /dev/null +++ b/clang/test/Preprocessor/deprecate-threads-macro-definition-msvc1939.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -E -dM -triple=arm64ec-windows-msvc -std=c89 -fms-compatibility-version=19.33 -ffreestanding < /dev/null | FileCheck -check-prefix=C89_MSVC33 %s +// RUN: %clang_cc1 -E -dM -triple=arm64ec-windows-msvc -std=c99 -fms-compatibility-version=19.33 -ffreestanding < /dev/null | FileCheck -check-prefix=C99_MSVC33 %s +// RUN: %clang_cc1 -E -dM -triple=arm64ec-windows-msvc -std=c11 -fms-compatibility-version=19.33 -ffreestanding < /dev/null | FileCheck -check-prefix=C11_MSVC33 %s +// RUN: %clang_cc1 -E -dM -triple=arm64ec-windows-msvc -std=c89 -fms-compatibility-version=19.39 -ffreestanding < /dev/null | FileCheck -check-prefix=C89_MSVC39 %s +// RUN: %clang_cc1 -E -dM -triple=arm64ec-windows-msvc -std=c99 -fms-compatibility-version=19.39 -ffreestanding < /dev/null | FileCheck -check-prefix=C99_MSVC39 %s +// RUN: %clang_cc1 -E -dM -triple=arm64ec-windows-msvc -std=c11 -fms-compatibility-version=19.39 -ffreestanding < /dev/null | FileCheck -check-prefix=C11_MSVC39 %s +// RUN: %clang_cc1 -E -dM -triple=arm64ec-windows-msvc -std=c11 -fms-compatibility-version=19.40 -ffreestanding < /dev/null | FileCheck -check-prefix=C11_MSVC40 %s + +// C89_MSVC33: #define __STDC_NO_THREADS__ 1 +// C99_MSVC33: #define __STDC_NO_THREADS__ 1 +// C11_MSVC33: #define __STDC_NO_THREADS__ 1 +// C89_MSVC39: #define __STDC_NO_THREADS__ 1 +// C99_MSVC39: #define __STDC_NO_THREADS__ 1 +// C11_MSVC39-NOT: #define __STDC_NO_THREADS__ +// C11_MSVC40-NOT: #define __STDC_NO_THREADS__ diff --git a/clang/test/Preprocessor/init-aarch64.c b/clang/test/Preprocessor/init-aarch64.c index 8578993dbfaeb..3036b496db25d 100644 --- a/clang/test/Preprocessor/init-aarch64.c +++ b/clang/test/Preprocessor/init-aarch64.c @@ -125,8 +125,8 @@ // AARCH64-NEXT: #define __FP_FAST_FMAF 1 // AARCH64-NEXT: #define __FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL 202430 // AARCH64-NEXT: #define __GCC_ASM_FLAG_OUTPUTS__ 1 -// AARCH64-NEXT: #define __GCC_CONSTRUCTIVE_SIZE {{.+}} -// AARCH64-NEXT: #define __GCC_DESTRUCTIVE_SIZE {{.+}} +// AARCH64-NEXT: #define __GCC_CONSTRUCTIVE_SIZE 64 +// AARCH64-NEXT: #define __GCC_DESTRUCTIVE_SIZE 256 // AARCH64-NEXT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 // AARCH64-NEXT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 1 // AARCH64-NEXT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 @@ -135,26 +135,31 @@ // AARCH64_CXX-NEXT: #define __GLIBCXX_BITSIZE_INT_N_0 128 // AARCH64_CXX-NEXT: #define __GLIBCXX_TYPE_INT_N_0 __int128 // AARCH64-NEXT: #define __HAVE_FUNCTION_MULTI_VERSIONING 1 +// AARCH64-NEXT: #define __INT16_C(c) c // AARCH64-NEXT: #define __INT16_C_SUFFIX__ // AARCH64-NEXT: #define __INT16_FMTd__ "hd" // AARCH64-NEXT: #define __INT16_FMTi__ "hi" // AARCH64-NEXT: #define __INT16_MAX__ 32767 // AARCH64-NEXT: #define __INT16_TYPE__ short +// AARCH64-NEXT: #define __INT32_C(c) c // AARCH64-NEXT: #define __INT32_C_SUFFIX__ // AARCH64-NEXT: #define __INT32_FMTd__ "d" // AARCH64-NEXT: #define __INT32_FMTi__ "i" // AARCH64-NEXT: #define __INT32_MAX__ 2147483647 // AARCH64-NEXT: #define __INT32_TYPE__ int +// AARCH64-NEXT: #define __INT64_C(c) c##L // AARCH64-NEXT: #define __INT64_C_SUFFIX__ L // AARCH64-NEXT: #define __INT64_FMTd__ "ld" // AARCH64-NEXT: #define __INT64_FMTi__ "li" // AARCH64-NEXT: #define __INT64_MAX__ 9223372036854775807L // AARCH64-NEXT: #define __INT64_TYPE__ long int +// AARCH64-NEXT: #define __INT8_C(c) c // AARCH64-NEXT: #define __INT8_C_SUFFIX__ // AARCH64-NEXT: #define __INT8_FMTd__ "hhd" // AARCH64-NEXT: #define __INT8_FMTi__ "hhi" // AARCH64-NEXT: #define __INT8_MAX__ 127 // AARCH64-NEXT: #define __INT8_TYPE__ signed char +// AARCH64-NEXT: #define __INTMAX_C(c) c##L // AARCH64-NEXT: #define __INTMAX_C_SUFFIX__ L // AARCH64-NEXT: #define __INTMAX_FMTd__ "ld" // AARCH64-NEXT: #define __INTMAX_FMTi__ "li" @@ -287,6 +292,7 @@ // AARCH64-NEXT: #define __STDC_UTF_32__ 1 // AARCH64_C: #define __STDC_VERSION__ 201710L // AARCH64-NEXT: #define __STDC__ 1 +// AARCH64-NEXT: #define __UINT16_C(c) c // AARCH64-NEXT: #define __UINT16_C_SUFFIX__ // AARCH64-NEXT: #define __UINT16_FMTX__ "hX" // AARCH64-NEXT: #define __UINT16_FMTo__ "ho" @@ -294,6 +300,7 @@ // AARCH64-NEXT: #define __UINT16_FMTx__ "hx" // AARCH64-NEXT: #define __UINT16_MAX__ 65535 // AARCH64-NEXT: #define __UINT16_TYPE__ unsigned short +// AARCH64-NEXT: #define __UINT32_C(c) c##U // AARCH64-NEXT: #define __UINT32_C_SUFFIX__ U // AARCH64-NEXT: #define __UINT32_FMTX__ "X" // AARCH64-NEXT: #define __UINT32_FMTo__ "o" @@ -301,6 +308,7 @@ // AARCH64-NEXT: #define __UINT32_FMTx__ "x" // AARCH64-NEXT: #define __UINT32_MAX__ 4294967295U // AARCH64-NEXT: #define __UINT32_TYPE__ unsigned int +// AARCH64-NEXT: #define __UINT64_C(c) c##UL // AARCH64-NEXT: #define __UINT64_C_SUFFIX__ UL // AARCH64-NEXT: #define __UINT64_FMTX__ "lX" // AARCH64-NEXT: #define __UINT64_FMTo__ "lo" @@ -308,6 +316,7 @@ // AARCH64-NEXT: #define __UINT64_FMTx__ "lx" // AARCH64-NEXT: #define __UINT64_MAX__ 18446744073709551615UL // AARCH64-NEXT: #define __UINT64_TYPE__ long unsigned int +// AARCH64-NEXT: #define __UINT8_C(c) c // AARCH64-NEXT: #define __UINT8_C_SUFFIX__ // AARCH64-NEXT: #define __UINT8_FMTX__ "hhX" // AARCH64-NEXT: #define __UINT8_FMTo__ "hho" @@ -315,6 +324,7 @@ // AARCH64-NEXT: #define __UINT8_FMTx__ "hhx" // AARCH64-NEXT: #define __UINT8_MAX__ 255 // AARCH64-NEXT: #define __UINT8_TYPE__ unsigned char +// AARCH64-NEXT: #define __UINTMAX_C(c) c##UL // AARCH64-NEXT: #define __UINTMAX_C_SUFFIX__ UL // AARCH64-NEXT: #define __UINTMAX_FMTX__ "lX" // AARCH64-NEXT: #define __UINTMAX_FMTo__ "lo" @@ -435,26 +445,31 @@ // AARCH64-DARWIN: #define __FLT_MIN__ 1.17549435e-38F // AARCH64-DARWIN: #define __FLT_RADIX__ 2 // AARCH64-DARWIN: #define __FUNCTION_MULTI_VERSIONING_SUPPORT_LEVEL 202430 +// AARCH64-DARWIN: #define __INT16_C(c) c // AARCH64-DARWIN: #define __INT16_C_SUFFIX__ // AARCH64-DARWIN: #define __INT16_FMTd__ "hd" // AARCH64-DARWIN: #define __INT16_FMTi__ "hi" // AARCH64-DARWIN: #define __INT16_MAX__ 32767 // AARCH64-DARWIN: #define __INT16_TYPE__ short +// AARCH64-DARWIN: #define __INT32_C(c) c // AARCH64-DARWIN: #define __INT32_C_SUFFIX__ // AARCH64-DARWIN: #define __INT32_FMTd__ "d" // AARCH64-DARWIN: #define __INT32_FMTi__ "i" // AARCH64-DARWIN: #define __INT32_MAX__ 2147483647 // AARCH64-DARWIN: #define __INT32_TYPE__ int +// AARCH64-DARWIN: #define __INT64_C(c) c##LL // AARCH64-DARWIN: #define __INT64_C_SUFFIX__ LL // AARCH64-DARWIN: #define __INT64_FMTd__ "lld" // AARCH64-DARWIN: #define __INT64_FMTi__ "lli" // AARCH64-DARWIN: #define __INT64_MAX__ 9223372036854775807LL // AARCH64-DARWIN: #define __INT64_TYPE__ long long int +// AARCH64-DARWIN: #define __INT8_C(c) c // AARCH64-DARWIN: #define __INT8_C_SUFFIX__ // AARCH64-DARWIN: #define __INT8_FMTd__ "hhd" // AARCH64-DARWIN: #define __INT8_FMTi__ "hhi" // AARCH64-DARWIN: #define __INT8_MAX__ 127 // AARCH64-DARWIN: #define __INT8_TYPE__ signed char +// AARCH64-DARWIN: #define __INTMAX_C(c) c##L // AARCH64-DARWIN: #define __INTMAX_C_SUFFIX__ L // AARCH64-DARWIN: #define __INTMAX_FMTd__ "ld" // AARCH64-DARWIN: #define __INTMAX_FMTi__ "li" @@ -538,18 +553,23 @@ // AARCH64-DARWIN: #define __SIZE_MAX__ 18446744073709551615UL // AARCH64-DARWIN: #define __SIZE_TYPE__ long unsigned int // AARCH64-DARWIN: #define __SIZE_WIDTH__ 64 +// AARCH64-DARWIN: #define __UINT16_C(c) c // AARCH64-DARWIN: #define __UINT16_C_SUFFIX__ // AARCH64-DARWIN: #define __UINT16_MAX__ 65535 // AARCH64-DARWIN: #define __UINT16_TYPE__ unsigned short +// AARCH64-DARWIN: #define __UINT32_C(c) c##U // AARCH64-DARWIN: #define __UINT32_C_SUFFIX__ U // AARCH64-DARWIN: #define __UINT32_MAX__ 4294967295U // AARCH64-DARWIN: #define __UINT32_TYPE__ unsigned int +// AARCH64-DARWIN: #define __UINT64_C(c) c##ULL // AARCH64-DARWIN: #define __UINT64_C_SUFFIX__ ULL // AARCH64-DARWIN: #define __UINT64_MAX__ 18446744073709551615ULL // AARCH64-DARWIN: #define __UINT64_TYPE__ long long unsigned int +// AARCH64-DARWIN: #define __UINT8_C(c) c // AARCH64-DARWIN: #define __UINT8_C_SUFFIX__ // AARCH64-DARWIN: #define __UINT8_MAX__ 255 // AARCH64-DARWIN: #define __UINT8_TYPE__ unsigned char +// AARCH64-DARWIN: #define __UINTMAX_C(c) c##UL // AARCH64-DARWIN: #define __UINTMAX_C_SUFFIX__ UL // AARCH64-DARWIN: #define __UINTMAX_MAX__ 18446744073709551615UL // AARCH64-DARWIN: #define __UINTMAX_TYPE__ long unsigned int @@ -703,18 +723,23 @@ // AARCH64-MSVC: #define __STDC_UTF_32__ 1 // AARCH64-MSVC: #define __STDC_VERSION__ 201710L // AARCH64-MSVC: #define __STDC__ 1 +// AARCH64-MSVC: #define __UINT16_C(c) c // AARCH64-MSVC: #define __UINT16_C_SUFFIX__ // AARCH64-MSVC: #define __UINT16_MAX__ 65535 // AARCH64-MSVC: #define __UINT16_TYPE__ unsigned short +// AARCH64-MSVC: #define __UINT32_C(c) c##U // AARCH64-MSVC: #define __UINT32_C_SUFFIX__ U // AARCH64-MSVC: #define __UINT32_MAX__ 4294967295U // AARCH64-MSVC: #define __UINT32_TYPE__ unsigned int +// AARCH64-MSVC: #define __UINT64_C(c) c##ULL // AARCH64-MSVC: #define __UINT64_C_SUFFIX__ ULL // AARCH64-MSVC: #define __UINT64_MAX__ 18446744073709551615ULL // AARCH64-MSVC: #define __UINT64_TYPE__ long long unsigned int +// AARCH64-MSVC: #define __UINT8_C(c) c // AARCH64-MSVC: #define __UINT8_C_SUFFIX__ // AARCH64-MSVC: #define __UINT8_MAX__ 255 // AARCH64-MSVC: #define __UINT8_TYPE__ unsigned char +// AARCH64-MSVC: #define __UINTMAX_C(c) c##ULL // AARCH64-MSVC: #define __UINTMAX_C_SUFFIX__ ULL // AARCH64-MSVC: #define __UINTMAX_MAX__ 18446744073709551615ULL // AARCH64-MSVC: #define __UINTMAX_TYPE__ long long unsigned int @@ -747,7 +772,7 @@ // AARCH64-MSVC: #define __WINT_WIDTH__ 16 // AARCH64-MSVC: #define __aarch64__ 1 -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64ec-windows-msvc < /dev/null | FileCheck -match-full-lines -check-prefix ARM64EC-MSVC %s +// RUN: %clang_cc1 -E -dM -fms-compatibility-version=19.33 -ffreestanding -triple=arm64ec-windows-msvc < /dev/null | FileCheck -match-full-lines -check-prefix ARM64EC-MSVC %s // ARM64EC-MSVC: #define _INTEGRAL_MAX_BITS 64 // ARM64EC-MSVC: #define _M_AMD64 100 @@ -867,26 +892,31 @@ // ARM64EC-MSVC: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 // ARM64EC-MSVC: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 // ARM64EC-MSVC: #define __HAVE_FUNCTION_MULTI_VERSIONING 1 +// ARM64EC-MSVC: #define __INT16_C(c) c // ARM64EC-MSVC: #define __INT16_C_SUFFIX__ // ARM64EC-MSVC: #define __INT16_FMTd__ "hd" // ARM64EC-MSVC: #define __INT16_FMTi__ "hi" // ARM64EC-MSVC: #define __INT16_MAX__ 32767 // ARM64EC-MSVC: #define __INT16_TYPE__ short +// ARM64EC-MSVC: #define __INT32_C(c) c // ARM64EC-MSVC: #define __INT32_C_SUFFIX__ // ARM64EC-MSVC: #define __INT32_FMTd__ "d" // ARM64EC-MSVC: #define __INT32_FMTi__ "i" // ARM64EC-MSVC: #define __INT32_MAX__ 2147483647 // ARM64EC-MSVC: #define __INT32_TYPE__ int +// ARM64EC-MSVC: #define __INT64_C(c) c##LL // ARM64EC-MSVC: #define __INT64_C_SUFFIX__ LL // ARM64EC-MSVC: #define __INT64_FMTd__ "lld" // ARM64EC-MSVC: #define __INT64_FMTi__ "lli" // ARM64EC-MSVC: #define __INT64_MAX__ 9223372036854775807LL // ARM64EC-MSVC: #define __INT64_TYPE__ long long int +// ARM64EC-MSVC: #define __INT8_C(c) c // ARM64EC-MSVC: #define __INT8_C_SUFFIX__ // ARM64EC-MSVC: #define __INT8_FMTd__ "hhd" // ARM64EC-MSVC: #define __INT8_FMTi__ "hhi" // ARM64EC-MSVC: #define __INT8_MAX__ 127 // ARM64EC-MSVC: #define __INT8_TYPE__ signed char +// ARM64EC-MSVC: #define __INTMAX_C(c) c##LL // ARM64EC-MSVC: #define __INTMAX_C_SUFFIX__ LL // ARM64EC-MSVC: #define __INTMAX_FMTd__ "lld" // ARM64EC-MSVC: #define __INTMAX_FMTi__ "lli" @@ -1013,6 +1043,7 @@ // ARM64EC-MSVC: #define __STDC_UTF_32__ 1 // ARM64EC-MSVC: #define __STDC_VERSION__ 201710L // ARM64EC-MSVC: #define __STDC__ 1 +// ARM64EC-MSVC: #define __UINT16_C(c) c // ARM64EC-MSVC: #define __UINT16_C_SUFFIX__ // ARM64EC-MSVC: #define __UINT16_FMTX__ "hX" // ARM64EC-MSVC: #define __UINT16_FMTo__ "ho" @@ -1020,6 +1051,7 @@ // ARM64EC-MSVC: #define __UINT16_FMTx__ "hx" // ARM64EC-MSVC: #define __UINT16_MAX__ 65535 // ARM64EC-MSVC: #define __UINT16_TYPE__ unsigned short +// ARM64EC-MSVC: #define __UINT32_C(c) c##U // ARM64EC-MSVC: #define __UINT32_C_SUFFIX__ U // ARM64EC-MSVC: #define __UINT32_FMTX__ "X" // ARM64EC-MSVC: #define __UINT32_FMTo__ "o" @@ -1027,6 +1059,7 @@ // ARM64EC-MSVC: #define __UINT32_FMTx__ "x" // ARM64EC-MSVC: #define __UINT32_MAX__ 4294967295U // ARM64EC-MSVC: #define __UINT32_TYPE__ unsigned int +// ARM64EC-MSVC: #define __UINT64_C(c) c##ULL // ARM64EC-MSVC: #define __UINT64_C_SUFFIX__ ULL // ARM64EC-MSVC: #define __UINT64_FMTX__ "llX" // ARM64EC-MSVC: #define __UINT64_FMTo__ "llo" @@ -1034,6 +1067,7 @@ // ARM64EC-MSVC: #define __UINT64_FMTx__ "llx" // ARM64EC-MSVC: #define __UINT64_MAX__ 18446744073709551615ULL // ARM64EC-MSVC: #define __UINT64_TYPE__ long long unsigned int +// ARM64EC-MSVC: #define __UINT8_C(c) c // ARM64EC-MSVC: #define __UINT8_C_SUFFIX__ // ARM64EC-MSVC: #define __UINT8_FMTX__ "hhX" // ARM64EC-MSVC: #define __UINT8_FMTo__ "hho" @@ -1041,6 +1075,7 @@ // ARM64EC-MSVC: #define __UINT8_FMTx__ "hhx" // ARM64EC-MSVC: #define __UINT8_MAX__ 255 // ARM64EC-MSVC: #define __UINT8_TYPE__ unsigned char +// ARM64EC-MSVC: #define __UINTMAX_C(c) c##ULL // ARM64EC-MSVC: #define __UINTMAX_C_SUFFIX__ ULL // ARM64EC-MSVC: #define __UINTMAX_FMTX__ "llX" // ARM64EC-MSVC: #define __UINTMAX_FMTo__ "llo" diff --git a/clang/test/Preprocessor/init-arm.c b/clang/test/Preprocessor/init-arm.c index 6e3acacc5c3a5..d2fcfe94bcd3d 100644 --- a/clang/test/Preprocessor/init-arm.c +++ b/clang/test/Preprocessor/init-arm.c @@ -46,26 +46,31 @@ // ARM:#define __FLT_MIN_EXP__ (-125) // ARM:#define __FLT_MIN__ 1.17549435e-38F // ARM:#define __FLT_RADIX__ 2 +// ARM:#define __INT16_C(c) c // ARM:#define __INT16_C_SUFFIX__ // ARM:#define __INT16_FMTd__ "hd" // ARM:#define __INT16_FMTi__ "hi" // ARM:#define __INT16_MAX__ 32767 // ARM:#define __INT16_TYPE__ short +// ARM:#define __INT32_C(c) c // ARM:#define __INT32_C_SUFFIX__ // ARM:#define __INT32_FMTd__ "d" // ARM:#define __INT32_FMTi__ "i" // ARM:#define __INT32_MAX__ 2147483647 // ARM:#define __INT32_TYPE__ int +// ARM:#define __INT64_C(c) c##LL // ARM:#define __INT64_C_SUFFIX__ LL // ARM:#define __INT64_FMTd__ "lld" // ARM:#define __INT64_FMTi__ "lli" // ARM:#define __INT64_MAX__ 9223372036854775807LL // ARM:#define __INT64_TYPE__ long long int +// ARM:#define __INT8_C(c) c // ARM:#define __INT8_C_SUFFIX__ // ARM:#define __INT8_FMTd__ "hhd" // ARM:#define __INT8_FMTi__ "hhi" // ARM:#define __INT8_MAX__ 127 // ARM:#define __INT8_TYPE__ signed char +// ARM:#define __INTMAX_C(c) c##LL // ARM:#define __INTMAX_C_SUFFIX__ LL // ARM:#define __INTMAX_FMTd__ "lld" // ARM:#define __INTMAX_FMTi__ "lli" @@ -151,18 +156,23 @@ // ARM:#define __SIZE_TYPE__ unsigned int // ARM:#define __SIZE_WIDTH__ 32 // ARM-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// ARM:#define __UINT16_C(c) c // ARM:#define __UINT16_C_SUFFIX__ // ARM:#define __UINT16_MAX__ 65535 // ARM:#define __UINT16_TYPE__ unsigned short +// ARM:#define __UINT32_C(c) c##U // ARM:#define __UINT32_C_SUFFIX__ U // ARM:#define __UINT32_MAX__ 4294967295U // ARM:#define __UINT32_TYPE__ unsigned int +// ARM:#define __UINT64_C(c) c##ULL // ARM:#define __UINT64_C_SUFFIX__ ULL // ARM:#define __UINT64_MAX__ 18446744073709551615ULL // ARM:#define __UINT64_TYPE__ long long unsigned int +// ARM:#define __UINT8_C(c) c // ARM:#define __UINT8_C_SUFFIX__ // ARM:#define __UINT8_MAX__ 255 // ARM:#define __UINT8_TYPE__ unsigned char +// ARM:#define __UINTMAX_C(c) c##ULL // ARM:#define __UINTMAX_C_SUFFIX__ ULL // ARM:#define __UINTMAX_MAX__ 18446744073709551615ULL // ARM:#define __UINTMAX_TYPE__ long long unsigned int @@ -248,26 +258,31 @@ // ARM-BE:#define __FLT_MIN_EXP__ (-125) // ARM-BE:#define __FLT_MIN__ 1.17549435e-38F // ARM-BE:#define __FLT_RADIX__ 2 +// ARM-BE:#define __INT16_C(c) c // ARM-BE:#define __INT16_C_SUFFIX__ // ARM-BE:#define __INT16_FMTd__ "hd" // ARM-BE:#define __INT16_FMTi__ "hi" // ARM-BE:#define __INT16_MAX__ 32767 // ARM-BE:#define __INT16_TYPE__ short +// ARM-BE:#define __INT32_C(c) c // ARM-BE:#define __INT32_C_SUFFIX__ // ARM-BE:#define __INT32_FMTd__ "d" // ARM-BE:#define __INT32_FMTi__ "i" // ARM-BE:#define __INT32_MAX__ 2147483647 // ARM-BE:#define __INT32_TYPE__ int +// ARM-BE:#define __INT64_C(c) c##LL // ARM-BE:#define __INT64_C_SUFFIX__ LL // ARM-BE:#define __INT64_FMTd__ "lld" // ARM-BE:#define __INT64_FMTi__ "lli" // ARM-BE:#define __INT64_MAX__ 9223372036854775807LL // ARM-BE:#define __INT64_TYPE__ long long int +// ARM-BE:#define __INT8_C(c) c // ARM-BE:#define __INT8_C_SUFFIX__ // ARM-BE:#define __INT8_FMTd__ "hhd" // ARM-BE:#define __INT8_FMTi__ "hhi" // ARM-BE:#define __INT8_MAX__ 127 // ARM-BE:#define __INT8_TYPE__ signed char +// ARM-BE:#define __INTMAX_C(c) c##LL // ARM-BE:#define __INTMAX_C_SUFFIX__ LL // ARM-BE:#define __INTMAX_FMTd__ "lld" // ARM-BE:#define __INTMAX_FMTi__ "lli" @@ -351,18 +366,23 @@ // ARM-BE:#define __SIZE_MAX__ 4294967295U // ARM-BE:#define __SIZE_TYPE__ unsigned int // ARM-BE:#define __SIZE_WIDTH__ 32 +// ARM-BE:#define __UINT16_C(c) c // ARM-BE:#define __UINT16_C_SUFFIX__ // ARM-BE:#define __UINT16_MAX__ 65535 // ARM-BE:#define __UINT16_TYPE__ unsigned short +// ARM-BE:#define __UINT32_C(c) c##U // ARM-BE:#define __UINT32_C_SUFFIX__ U // ARM-BE:#define __UINT32_MAX__ 4294967295U // ARM-BE:#define __UINT32_TYPE__ unsigned int +// ARM-BE:#define __UINT64_C(c) c##ULL // ARM-BE:#define __UINT64_C_SUFFIX__ ULL // ARM-BE:#define __UINT64_MAX__ 18446744073709551615ULL // ARM-BE:#define __UINT64_TYPE__ long long unsigned int +// ARM-BE:#define __UINT8_C(c) c // ARM-BE:#define __UINT8_C_SUFFIX__ // ARM-BE:#define __UINT8_MAX__ 255 // ARM-BE:#define __UINT8_TYPE__ unsigned char +// ARM-BE:#define __UINTMAX_C(c) c##ULL // ARM-BE:#define __UINTMAX_C_SUFFIX__ ULL // ARM-BE:#define __UINTMAX_MAX__ 18446744073709551615ULL // ARM-BE:#define __UINTMAX_TYPE__ long long unsigned int @@ -440,26 +460,31 @@ // ARMEABISOFT:#define __FLT_MIN_EXP__ (-125) // ARMEABISOFT:#define __FLT_MIN__ 1.17549435e-38F // ARMEABISOFT:#define __FLT_RADIX__ 2 +// ARMEABISOFT:#define __INT16_C(c) c // ARMEABISOFT:#define __INT16_C_SUFFIX__ // ARMEABISOFT:#define __INT16_FMTd__ "hd" // ARMEABISOFT:#define __INT16_FMTi__ "hi" // ARMEABISOFT:#define __INT16_MAX__ 32767 // ARMEABISOFT:#define __INT16_TYPE__ short +// ARMEABISOFT:#define __INT32_C(c) c // ARMEABISOFT:#define __INT32_C_SUFFIX__ // ARMEABISOFT:#define __INT32_FMTd__ "d" // ARMEABISOFT:#define __INT32_FMTi__ "i" // ARMEABISOFT:#define __INT32_MAX__ 2147483647 // ARMEABISOFT:#define __INT32_TYPE__ int +// ARMEABISOFT:#define __INT64_C(c) c##LL // ARMEABISOFT:#define __INT64_C_SUFFIX__ LL // ARMEABISOFT:#define __INT64_FMTd__ "lld" // ARMEABISOFT:#define __INT64_FMTi__ "lli" // ARMEABISOFT:#define __INT64_MAX__ 9223372036854775807LL // ARMEABISOFT:#define __INT64_TYPE__ long long int +// ARMEABISOFT:#define __INT8_C(c) c // ARMEABISOFT:#define __INT8_C_SUFFIX__ // ARMEABISOFT:#define __INT8_FMTd__ "hhd" // ARMEABISOFT:#define __INT8_FMTi__ "hhi" // ARMEABISOFT:#define __INT8_MAX__ 127 // ARMEABISOFT:#define __INT8_TYPE__ signed char +// ARMEABISOFT:#define __INTMAX_C(c) c##LL // ARMEABISOFT:#define __INTMAX_C_SUFFIX__ LL // ARMEABISOFT:#define __INTMAX_FMTd__ "lld" // ARMEABISOFT:#define __INTMAX_FMTi__ "lli" @@ -545,18 +570,23 @@ // ARMEABISOFT:#define __SIZE_TYPE__ unsigned int // ARMEABISOFT:#define __SIZE_WIDTH__ 32 // ARMEABISOFT:#define __SOFTFP__ 1 +// ARMEABISOFT:#define __UINT16_C(c) c // ARMEABISOFT:#define __UINT16_C_SUFFIX__ // ARMEABISOFT:#define __UINT16_MAX__ 65535 // ARMEABISOFT:#define __UINT16_TYPE__ unsigned short +// ARMEABISOFT:#define __UINT32_C(c) c##U // ARMEABISOFT:#define __UINT32_C_SUFFIX__ U // ARMEABISOFT:#define __UINT32_MAX__ 4294967295U // ARMEABISOFT:#define __UINT32_TYPE__ unsigned int +// ARMEABISOFT:#define __UINT64_C(c) c##ULL // ARMEABISOFT:#define __UINT64_C_SUFFIX__ ULL // ARMEABISOFT:#define __UINT64_MAX__ 18446744073709551615ULL // ARMEABISOFT:#define __UINT64_TYPE__ long long unsigned int +// ARMEABISOFT:#define __UINT8_C(c) c // ARMEABISOFT:#define __UINT8_C_SUFFIX__ // ARMEABISOFT:#define __UINT8_MAX__ 255 // ARMEABISOFT:#define __UINT8_TYPE__ unsigned char +// ARMEABISOFT:#define __UINTMAX_C(c) c##ULL // ARMEABISOFT:#define __UINTMAX_C_SUFFIX__ ULL // ARMEABISOFT:#define __UINTMAX_MAX__ 18446744073709551615ULL // ARMEABISOFT:#define __UINTMAX_TYPE__ long long unsigned int @@ -640,26 +670,31 @@ // ARMEABISOFTFP_NOFP:#define __FLT_MIN_EXP__ (-125) // ARMEABISOFTFP_NOFP:#define __FLT_MIN__ 1.17549435e-38F // ARMEABISOFTFP_NOFP:#define __FLT_RADIX__ 2 +// ARMEABISOFTFP_NOFP:#define __INT16_C(c) c // ARMEABISOFTFP_NOFP:#define __INT16_C_SUFFIX__ // ARMEABISOFTFP_NOFP:#define __INT16_FMTd__ "hd" // ARMEABISOFTFP_NOFP:#define __INT16_FMTi__ "hi" // ARMEABISOFTFP_NOFP:#define __INT16_MAX__ 32767 // ARMEABISOFTFP_NOFP:#define __INT16_TYPE__ short +// ARMEABISOFTFP_NOFP:#define __INT32_C(c) c // ARMEABISOFTFP_NOFP:#define __INT32_C_SUFFIX__ // ARMEABISOFTFP_NOFP:#define __INT32_FMTd__ "d" // ARMEABISOFTFP_NOFP:#define __INT32_FMTi__ "i" // ARMEABISOFTFP_NOFP:#define __INT32_MAX__ 2147483647 // ARMEABISOFTFP_NOFP:#define __INT32_TYPE__ int +// ARMEABISOFTFP_NOFP:#define __INT64_C(c) c##LL // ARMEABISOFTFP_NOFP:#define __INT64_C_SUFFIX__ LL // ARMEABISOFTFP_NOFP:#define __INT64_FMTd__ "lld" // ARMEABISOFTFP_NOFP:#define __INT64_FMTi__ "lli" // ARMEABISOFTFP_NOFP:#define __INT64_MAX__ 9223372036854775807LL // ARMEABISOFTFP_NOFP:#define __INT64_TYPE__ long long int +// ARMEABISOFTFP_NOFP:#define __INT8_C(c) c // ARMEABISOFTFP_NOFP:#define __INT8_C_SUFFIX__ // ARMEABISOFTFP_NOFP:#define __INT8_FMTd__ "hhd" // ARMEABISOFTFP_NOFP:#define __INT8_FMTi__ "hhi" // ARMEABISOFTFP_NOFP:#define __INT8_MAX__ 127 // ARMEABISOFTFP_NOFP:#define __INT8_TYPE__ signed char +// ARMEABISOFTFP_NOFP:#define __INTMAX_C(c) c##LL // ARMEABISOFTFP_NOFP:#define __INTMAX_C_SUFFIX__ LL // ARMEABISOFTFP_NOFP:#define __INTMAX_FMTd__ "lld" // ARMEABISOFTFP_NOFP:#define __INTMAX_FMTi__ "lli" @@ -745,18 +780,23 @@ // ARMEABISOFTFP_NOFP:#define __SIZE_TYPE__ unsigned int // ARMEABISOFTFP_NOFP:#define __SIZE_WIDTH__ 32 // ARMEABISOFTFP_NOFP:#define __SOFTFP__ 1 +// ARMEABISOFTFP_NOFP:#define __UINT16_C(c) c // ARMEABISOFTFP_NOFP:#define __UINT16_C_SUFFIX__ // ARMEABISOFTFP_NOFP:#define __UINT16_MAX__ 65535 // ARMEABISOFTFP_NOFP:#define __UINT16_TYPE__ unsigned short +// ARMEABISOFTFP_NOFP:#define __UINT32_C(c) c##U // ARMEABISOFTFP_NOFP:#define __UINT32_C_SUFFIX__ U // ARMEABISOFTFP_NOFP:#define __UINT32_MAX__ 4294967295U // ARMEABISOFTFP_NOFP:#define __UINT32_TYPE__ unsigned int +// ARMEABISOFTFP_NOFP:#define __UINT64_C(c) c##ULL // ARMEABISOFTFP_NOFP:#define __UINT64_C_SUFFIX__ ULL // ARMEABISOFTFP_NOFP:#define __UINT64_MAX__ 18446744073709551615ULL // ARMEABISOFTFP_NOFP:#define __UINT64_TYPE__ long long unsigned int +// ARMEABISOFTFP_NOFP:#define __UINT8_C(c) c // ARMEABISOFTFP_NOFP:#define __UINT8_C_SUFFIX__ // ARMEABISOFTFP_NOFP:#define __UINT8_MAX__ 255 // ARMEABISOFTFP_NOFP:#define __UINT8_TYPE__ unsigned char +// ARMEABISOFTFP_NOFP:#define __UINTMAX_C(c) c##ULL // ARMEABISOFTFP_NOFP:#define __UINTMAX_C_SUFFIX__ ULL // ARMEABISOFTFP_NOFP:#define __UINTMAX_MAX__ 18446744073709551615ULL // ARMEABISOFTFP_NOFP:#define __UINTMAX_TYPE__ long long unsigned int @@ -834,26 +874,31 @@ // ARMEABISOFTFP_FP:#define __FLT_MIN_EXP__ (-125) // ARMEABISOFTFP_FP:#define __FLT_MIN__ 1.17549435e-38F // ARMEABISOFTFP_FP:#define __FLT_RADIX__ 2 +// ARMEABISOFTFP_FP:#define __INT16_C(c) c // ARMEABISOFTFP_FP:#define __INT16_C_SUFFIX__ // ARMEABISOFTFP_FP:#define __INT16_FMTd__ "hd" // ARMEABISOFTFP_FP:#define __INT16_FMTi__ "hi" // ARMEABISOFTFP_FP:#define __INT16_MAX__ 32767 // ARMEABISOFTFP_FP:#define __INT16_TYPE__ short +// ARMEABISOFTFP_FP:#define __INT32_C(c) c // ARMEABISOFTFP_FP:#define __INT32_C_SUFFIX__ // ARMEABISOFTFP_FP:#define __INT32_FMTd__ "d" // ARMEABISOFTFP_FP:#define __INT32_FMTi__ "i" // ARMEABISOFTFP_FP:#define __INT32_MAX__ 2147483647 // ARMEABISOFTFP_FP:#define __INT32_TYPE__ int +// ARMEABISOFTFP_FP:#define __INT64_C(c) c##LL // ARMEABISOFTFP_FP:#define __INT64_C_SUFFIX__ LL // ARMEABISOFTFP_FP:#define __INT64_FMTd__ "lld" // ARMEABISOFTFP_FP:#define __INT64_FMTi__ "lli" // ARMEABISOFTFP_FP:#define __INT64_MAX__ 9223372036854775807LL // ARMEABISOFTFP_FP:#define __INT64_TYPE__ long long int +// ARMEABISOFTFP_FP:#define __INT8_C(c) c // ARMEABISOFTFP_FP:#define __INT8_C_SUFFIX__ // ARMEABISOFTFP_FP:#define __INT8_FMTd__ "hhd" // ARMEABISOFTFP_FP:#define __INT8_FMTi__ "hhi" // ARMEABISOFTFP_FP:#define __INT8_MAX__ 127 // ARMEABISOFTFP_FP:#define __INT8_TYPE__ signed char +// ARMEABISOFTFP_FP:#define __INTMAX_C(c) c##LL // ARMEABISOFTFP_FP:#define __INTMAX_C_SUFFIX__ LL // ARMEABISOFTFP_FP:#define __INTMAX_FMTd__ "lld" // ARMEABISOFTFP_FP:#define __INTMAX_FMTi__ "lli" @@ -939,18 +984,23 @@ // ARMEABISOFTFP_FP:#define __SIZE_TYPE__ unsigned int // ARMEABISOFTFP_FP:#define __SIZE_WIDTH__ 32 // ARMEABISOFTFP_FP-NOT:#define __SOFTFP__ 1 +// ARMEABISOFTFP_FP:#define __UINT16_C(c) c // ARMEABISOFTFP_FP:#define __UINT16_C_SUFFIX__ // ARMEABISOFTFP_FP:#define __UINT16_MAX__ 65535 // ARMEABISOFTFP_FP:#define __UINT16_TYPE__ unsigned short +// ARMEABISOFTFP_FP:#define __UINT32_C(c) c##U // ARMEABISOFTFP_FP:#define __UINT32_C_SUFFIX__ U // ARMEABISOFTFP_FP:#define __UINT32_MAX__ 4294967295U // ARMEABISOFTFP_FP:#define __UINT32_TYPE__ unsigned int +// ARMEABISOFTFP_FP:#define __UINT64_C(c) c##ULL // ARMEABISOFTFP_FP:#define __UINT64_C_SUFFIX__ ULL // ARMEABISOFTFP_FP:#define __UINT64_MAX__ 18446744073709551615ULL // ARMEABISOFTFP_FP:#define __UINT64_TYPE__ long long unsigned int +// ARMEABISOFTFP_FP:#define __UINT8_C(c) c // ARMEABISOFTFP_FP:#define __UINT8_C_SUFFIX__ // ARMEABISOFTFP_FP:#define __UINT8_MAX__ 255 // ARMEABISOFTFP_FP:#define __UINT8_TYPE__ unsigned char +// ARMEABISOFTFP_FP:#define __UINTMAX_C(c) c##ULL // ARMEABISOFTFP_FP:#define __UINTMAX_C_SUFFIX__ ULL // ARMEABISOFTFP_FP:#define __UINTMAX_MAX__ 18446744073709551615ULL // ARMEABISOFTFP_FP:#define __UINTMAX_TYPE__ long long unsigned int @@ -1028,26 +1078,31 @@ // ARMEABIHARDFP:#define __FLT_MIN_EXP__ (-125) // ARMEABIHARDFP:#define __FLT_MIN__ 1.17549435e-38F // ARMEABIHARDFP:#define __FLT_RADIX__ 2 +// ARMEABIHARDFP:#define __INT16_C(c) c // ARMEABIHARDFP:#define __INT16_C_SUFFIX__ // ARMEABIHARDFP:#define __INT16_FMTd__ "hd" // ARMEABIHARDFP:#define __INT16_FMTi__ "hi" // ARMEABIHARDFP:#define __INT16_MAX__ 32767 // ARMEABIHARDFP:#define __INT16_TYPE__ short +// ARMEABIHARDFP:#define __INT32_C(c) c // ARMEABIHARDFP:#define __INT32_C_SUFFIX__ // ARMEABIHARDFP:#define __INT32_FMTd__ "d" // ARMEABIHARDFP:#define __INT32_FMTi__ "i" // ARMEABIHARDFP:#define __INT32_MAX__ 2147483647 // ARMEABIHARDFP:#define __INT32_TYPE__ int +// ARMEABIHARDFP:#define __INT64_C(c) c##LL // ARMEABIHARDFP:#define __INT64_C_SUFFIX__ LL // ARMEABIHARDFP:#define __INT64_FMTd__ "lld" // ARMEABIHARDFP:#define __INT64_FMTi__ "lli" // ARMEABIHARDFP:#define __INT64_MAX__ 9223372036854775807LL // ARMEABIHARDFP:#define __INT64_TYPE__ long long int +// ARMEABIHARDFP:#define __INT8_C(c) c // ARMEABIHARDFP:#define __INT8_C_SUFFIX__ // ARMEABIHARDFP:#define __INT8_FMTd__ "hhd" // ARMEABIHARDFP:#define __INT8_FMTi__ "hhi" // ARMEABIHARDFP:#define __INT8_MAX__ 127 // ARMEABIHARDFP:#define __INT8_TYPE__ signed char +// ARMEABIHARDFP:#define __INTMAX_C(c) c##LL // ARMEABIHARDFP:#define __INTMAX_C_SUFFIX__ LL // ARMEABIHARDFP:#define __INTMAX_FMTd__ "lld" // ARMEABIHARDFP:#define __INTMAX_FMTi__ "lli" @@ -1133,18 +1188,23 @@ // ARMEABIHARDFP:#define __SIZE_TYPE__ unsigned int // ARMEABIHARDFP:#define __SIZE_WIDTH__ 32 // ARMEABIHARDFP-NOT:#define __SOFTFP__ 1 +// ARMEABIHARDFP:#define __UINT16_C(c) c // ARMEABIHARDFP:#define __UINT16_C_SUFFIX__ // ARMEABIHARDFP:#define __UINT16_MAX__ 65535 // ARMEABIHARDFP:#define __UINT16_TYPE__ unsigned short +// ARMEABIHARDFP:#define __UINT32_C(c) c##U // ARMEABIHARDFP:#define __UINT32_C_SUFFIX__ U // ARMEABIHARDFP:#define __UINT32_MAX__ 4294967295U // ARMEABIHARDFP:#define __UINT32_TYPE__ unsigned int +// ARMEABIHARDFP:#define __UINT64_C(c) c##ULL // ARMEABIHARDFP:#define __UINT64_C_SUFFIX__ ULL // ARMEABIHARDFP:#define __UINT64_MAX__ 18446744073709551615ULL // ARMEABIHARDFP:#define __UINT64_TYPE__ long long unsigned int +// ARMEABIHARDFP:#define __UINT8_C(c) c // ARMEABIHARDFP:#define __UINT8_C_SUFFIX__ // ARMEABIHARDFP:#define __UINT8_MAX__ 255 // ARMEABIHARDFP:#define __UINT8_TYPE__ unsigned char +// ARMEABIHARDFP:#define __UINTMAX_C(c) c##ULL // ARMEABIHARDFP:#define __UINTMAX_C_SUFFIX__ ULL // ARMEABIHARDFP:#define __UINTMAX_MAX__ 18446744073709551615ULL // ARMEABIHARDFP:#define __UINTMAX_TYPE__ long long unsigned int @@ -1220,26 +1280,31 @@ // ARM-NETBSD:#define __FLT_MIN_EXP__ (-125) // ARM-NETBSD:#define __FLT_MIN__ 1.17549435e-38F // ARM-NETBSD:#define __FLT_RADIX__ 2 +// ARM-NETBSD:#define __INT16_C(c) c // ARM-NETBSD:#define __INT16_C_SUFFIX__ // ARM-NETBSD:#define __INT16_FMTd__ "hd" // ARM-NETBSD:#define __INT16_FMTi__ "hi" // ARM-NETBSD:#define __INT16_MAX__ 32767 // ARM-NETBSD:#define __INT16_TYPE__ short +// ARM-NETBSD:#define __INT32_C(c) c // ARM-NETBSD:#define __INT32_C_SUFFIX__ // ARM-NETBSD:#define __INT32_FMTd__ "d" // ARM-NETBSD:#define __INT32_FMTi__ "i" // ARM-NETBSD:#define __INT32_MAX__ 2147483647 // ARM-NETBSD:#define __INT32_TYPE__ int +// ARM-NETBSD:#define __INT64_C(c) c##LL // ARM-NETBSD:#define __INT64_C_SUFFIX__ LL // ARM-NETBSD:#define __INT64_FMTd__ "lld" // ARM-NETBSD:#define __INT64_FMTi__ "lli" // ARM-NETBSD:#define __INT64_MAX__ 9223372036854775807LL // ARM-NETBSD:#define __INT64_TYPE__ long long int +// ARM-NETBSD:#define __INT8_C(c) c // ARM-NETBSD:#define __INT8_C_SUFFIX__ // ARM-NETBSD:#define __INT8_FMTd__ "hhd" // ARM-NETBSD:#define __INT8_FMTi__ "hhi" // ARM-NETBSD:#define __INT8_MAX__ 127 // ARM-NETBSD:#define __INT8_TYPE__ signed char +// ARM-NETBSD:#define __INTMAX_C(c) c##LL // ARM-NETBSD:#define __INTMAX_C_SUFFIX__ LL // ARM-NETBSD:#define __INTMAX_FMTd__ "lld" // ARM-NETBSD:#define __INTMAX_FMTi__ "lli" @@ -1325,18 +1390,23 @@ // ARM-NETBSD:#define __SIZE_TYPE__ long unsigned int // ARM-NETBSD:#define __SIZE_WIDTH__ 32 // ARM-NETBSD:#define __SOFTFP__ 1 +// ARM-NETBSD:#define __UINT16_C(c) c // ARM-NETBSD:#define __UINT16_C_SUFFIX__ // ARM-NETBSD:#define __UINT16_MAX__ 65535 // ARM-NETBSD:#define __UINT16_TYPE__ unsigned short +// ARM-NETBSD:#define __UINT32_C(c) c##U // ARM-NETBSD:#define __UINT32_C_SUFFIX__ U // ARM-NETBSD:#define __UINT32_MAX__ 4294967295U // ARM-NETBSD:#define __UINT32_TYPE__ unsigned int +// ARM-NETBSD:#define __UINT64_C(c) c##ULL // ARM-NETBSD:#define __UINT64_C_SUFFIX__ ULL // ARM-NETBSD:#define __UINT64_MAX__ 18446744073709551615ULL // ARM-NETBSD:#define __UINT64_TYPE__ long long unsigned int +// ARM-NETBSD:#define __UINT8_C(c) c // ARM-NETBSD:#define __UINT8_C_SUFFIX__ // ARM-NETBSD:#define __UINT8_MAX__ 255 // ARM-NETBSD:#define __UINT8_TYPE__ unsigned char +// ARM-NETBSD:#define __UINTMAX_C(c) c##ULL // ARM-NETBSD:#define __UINTMAX_C_SUFFIX__ ULL // ARM-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL // ARM-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int @@ -1372,6 +1442,7 @@ // RUN: %clang -E -dM -ffreestanding -target arm-netbsd-eabihf %s -o - | FileCheck -match-full-lines -check-prefix ARMHF-NETBSD %s // ARMHF-NETBSD:#define __SIZE_WIDTH__ 32 // ARMHF-NETBSD-NOT:#define __SOFTFP__ 1 +// ARMHF-NETBSD:#define __UINT16_C(c) c // ARMHF-NETBSD:#define __UINT16_C_SUFFIX__ // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-none-eabi < /dev/null | FileCheck -match-full-lines -check-prefix ARM-NONE-EABI %s diff --git a/clang/test/Preprocessor/init-csky.c b/clang/test/Preprocessor/init-csky.c index f7868e02644aa..99c5ad1010edb 100644 --- a/clang/test/Preprocessor/init-csky.c +++ b/clang/test/Preprocessor/init-csky.c @@ -66,18 +66,23 @@ // CSKY: #define __GNUC__ {{.*}} // CSKY: #define __GXX_ABI_VERSION {{.*}} // CSKY: #define __ILP32__ 1 +// CSKY: #define __INT16_C(c) c // CSKY: #define __INT16_C_SUFFIX__ // CSKY: #define __INT16_MAX__ 32767 // CSKY: #define __INT16_TYPE__ short +// CSKY: #define __INT32_C(c) c // CSKY: #define __INT32_C_SUFFIX__ // CSKY: #define __INT32_MAX__ 2147483647 // CSKY: #define __INT32_TYPE__ int +// CSKY: #define __INT64_C(c) c##LL // CSKY: #define __INT64_C_SUFFIX__ LL // CSKY: #define __INT64_MAX__ 9223372036854775807LL // CSKY: #define __INT64_TYPE__ long long int +// CSKY: #define __INT8_C(c) c // CSKY: #define __INT8_C_SUFFIX__ // CSKY: #define __INT8_MAX__ 127 // CSKY: #define __INT8_TYPE__ signed char +// CSKY: #define __INTMAX_C(c) c##LL // CSKY: #define __INTMAX_C_SUFFIX__ LL // CSKY: #define __INTMAX_MAX__ 9223372036854775807LL // CSKY: #define __INTMAX_TYPE__ long long int @@ -152,18 +157,23 @@ // CSKY: #define __STDC_UTF_32__ 1 // CSKY: #define __STDC_VERSION__ 201710L // CSKY: #define __STDC__ 1 +// CSKY: #define __UINT16_C(c) c // CSKY: #define __UINT16_C_SUFFIX__ // CSKY: #define __UINT16_MAX__ 65535 // CSKY: #define __UINT16_TYPE__ unsigned short +// CSKY: #define __UINT32_C(c) c##U // CSKY: #define __UINT32_C_SUFFIX__ U // CSKY: #define __UINT32_MAX__ 4294967295U // CSKY: #define __UINT32_TYPE__ unsigned int +// CSKY: #define __UINT64_C(c) c##ULL // CSKY: #define __UINT64_C_SUFFIX__ ULL // CSKY: #define __UINT64_MAX__ 18446744073709551615ULL // CSKY: #define __UINT64_TYPE__ long long unsigned int +// CSKY: #define __UINT8_C(c) c // CSKY: #define __UINT8_C_SUFFIX__ // CSKY: #define __UINT8_MAX__ 255 // CSKY: #define __UINT8_TYPE__ unsigned char +// CSKY: #define __UINTMAX_C(c) c##ULL // CSKY: #define __UINTMAX_C_SUFFIX__ ULL // CSKY: #define __UINTMAX_MAX__ 18446744073709551615ULL // CSKY: #define __UINTMAX_TYPE__ long long unsigned int diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c index f6fd603dc39c0..ac461b371162f 100644 --- a/clang/test/Preprocessor/init-loongarch.c +++ b/clang/test/Preprocessor/init-loongarch.c @@ -85,26 +85,31 @@ // LA32: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 // LA32: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 // LA32: #define __ILP32__ 1 +// LA32: #define __INT16_C(c) c // LA32: #define __INT16_C_SUFFIX__ // LA32: #define __INT16_FMTd__ "hd" // LA32: #define __INT16_FMTi__ "hi" // LA32: #define __INT16_MAX__ 32767 // LA32: #define __INT16_TYPE__ short +// LA32: #define __INT32_C(c) c // LA32: #define __INT32_C_SUFFIX__ // LA32: #define __INT32_FMTd__ "d" // LA32: #define __INT32_FMTi__ "i" // LA32: #define __INT32_MAX__ 2147483647 // LA32: #define __INT32_TYPE__ int +// LA32: #define __INT64_C(c) c##LL // LA32: #define __INT64_C_SUFFIX__ LL // LA32: #define __INT64_FMTd__ "lld" // LA32: #define __INT64_FMTi__ "lli" // LA32: #define __INT64_MAX__ 9223372036854775807LL // LA32: #define __INT64_TYPE__ long long int +// LA32: #define __INT8_C(c) c // LA32: #define __INT8_C_SUFFIX__ // LA32: #define __INT8_FMTd__ "hhd" // LA32: #define __INT8_FMTi__ "hhi" // LA32: #define __INT8_MAX__ 127 // LA32: #define __INT8_TYPE__ signed char +// LA32: #define __INTMAX_C(c) c##LL // LA32: #define __INTMAX_C_SUFFIX__ LL // LA32: #define __INTMAX_FMTd__ "lld" // LA32: #define __INTMAX_FMTi__ "lli" @@ -227,6 +232,7 @@ // LA32: #define __STDC_UTF_32__ 1 // LA32: #define __STDC_VERSION__ 201710L // LA32: #define __STDC__ 1 +// LA32: #define __UINT16_C(c) c // LA32: #define __UINT16_C_SUFFIX__ // LA32: #define __UINT16_FMTX__ "hX" // LA32: #define __UINT16_FMTo__ "ho" @@ -234,6 +240,7 @@ // LA32: #define __UINT16_FMTx__ "hx" // LA32: #define __UINT16_MAX__ 65535 // LA32: #define __UINT16_TYPE__ unsigned short +// LA32: #define __UINT32_C(c) c##U // LA32: #define __UINT32_C_SUFFIX__ U // LA32: #define __UINT32_FMTX__ "X" // LA32: #define __UINT32_FMTo__ "o" @@ -241,6 +248,7 @@ // LA32: #define __UINT32_FMTx__ "x" // LA32: #define __UINT32_MAX__ 4294967295U // LA32: #define __UINT32_TYPE__ unsigned int +// LA32: #define __UINT64_C(c) c##ULL // LA32: #define __UINT64_C_SUFFIX__ ULL // LA32: #define __UINT64_FMTX__ "llX" // LA32: #define __UINT64_FMTo__ "llo" @@ -248,6 +256,7 @@ // LA32: #define __UINT64_FMTx__ "llx" // LA32: #define __UINT64_MAX__ 18446744073709551615ULL // LA32: #define __UINT64_TYPE__ long long unsigned int +// LA32: #define __UINT8_C(c) c // LA32: #define __UINT8_C_SUFFIX__ // LA32: #define __UINT8_FMTX__ "hhX" // LA32: #define __UINT8_FMTo__ "hho" @@ -255,6 +264,7 @@ // LA32: #define __UINT8_FMTx__ "hhx" // LA32: #define __UINT8_MAX__ 255 // LA32: #define __UINT8_TYPE__ unsigned char +// LA32: #define __UINTMAX_C(c) c##ULL // LA32: #define __UINTMAX_C_SUFFIX__ ULL // LA32: #define __UINTMAX_FMTX__ "llX" // LA32: #define __UINTMAX_FMTo__ "llo" @@ -406,26 +416,31 @@ // LA64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 // LA64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 // LA64: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1 +// LA64: #define __INT16_C(c) c // LA64: #define __INT16_C_SUFFIX__ // LA64: #define __INT16_FMTd__ "hd" // LA64: #define __INT16_FMTi__ "hi" // LA64: #define __INT16_MAX__ 32767 // LA64: #define __INT16_TYPE__ short +// LA64: #define __INT32_C(c) c // LA64: #define __INT32_C_SUFFIX__ // LA64: #define __INT32_FMTd__ "d" // LA64: #define __INT32_FMTi__ "i" // LA64: #define __INT32_MAX__ 2147483647 // LA64: #define __INT32_TYPE__ int +// LA64: #define __INT64_C(c) c##L // LA64: #define __INT64_C_SUFFIX__ L // LA64: #define __INT64_FMTd__ "ld" // LA64: #define __INT64_FMTi__ "li" // LA64: #define __INT64_MAX__ 9223372036854775807L // LA64: #define __INT64_TYPE__ long int +// LA64: #define __INT8_C(c) c // LA64: #define __INT8_C_SUFFIX__ // LA64: #define __INT8_FMTd__ "hhd" // LA64: #define __INT8_FMTi__ "hhi" // LA64: #define __INT8_MAX__ 127 // LA64: #define __INT8_TYPE__ signed char +// LA64: #define __INTMAX_C(c) c##L // LA64: #define __INTMAX_C_SUFFIX__ L // LA64: #define __INTMAX_FMTd__ "ld" // LA64: #define __INTMAX_FMTi__ "li" @@ -549,6 +564,7 @@ // LA64: #define __STDC_UTF_32__ 1 // LA64: #define __STDC_VERSION__ 201710L // LA64: #define __STDC__ 1 +// LA64: #define __UINT16_C(c) c // LA64: #define __UINT16_C_SUFFIX__ // LA64: #define __UINT16_FMTX__ "hX" // LA64: #define __UINT16_FMTo__ "ho" @@ -556,6 +572,7 @@ // LA64: #define __UINT16_FMTx__ "hx" // LA64: #define __UINT16_MAX__ 65535 // LA64: #define __UINT16_TYPE__ unsigned short +// LA64: #define __UINT32_C(c) c##U // LA64: #define __UINT32_C_SUFFIX__ U // LA64: #define __UINT32_FMTX__ "X" // LA64: #define __UINT32_FMTo__ "o" @@ -563,6 +580,7 @@ // LA64: #define __UINT32_FMTx__ "x" // LA64: #define __UINT32_MAX__ 4294967295U // LA64: #define __UINT32_TYPE__ unsigned int +// LA64: #define __UINT64_C(c) c##UL // LA64: #define __UINT64_C_SUFFIX__ UL // LA64: #define __UINT64_FMTX__ "lX" // LA64: #define __UINT64_FMTo__ "lo" @@ -570,6 +588,7 @@ // LA64: #define __UINT64_FMTx__ "lx" // LA64: #define __UINT64_MAX__ 18446744073709551615UL // LA64: #define __UINT64_TYPE__ long unsigned int +// LA64: #define __UINT8_C(c) c // LA64: #define __UINT8_C_SUFFIX__ // LA64: #define __UINT8_FMTX__ "hhX" // LA64: #define __UINT8_FMTo__ "hho" @@ -577,6 +596,7 @@ // LA64: #define __UINT8_FMTx__ "hhx" // LA64: #define __UINT8_MAX__ 255 // LA64: #define __UINT8_TYPE__ unsigned char +// LA64: #define __UINTMAX_C(c) c##UL // LA64: #define __UINTMAX_C_SUFFIX__ UL // LA64: #define __UINTMAX_FMTX__ "lX" // LA64: #define __UINTMAX_FMTo__ "lo" diff --git a/clang/test/Preprocessor/init-mips.c b/clang/test/Preprocessor/init-mips.c index 34091ea3690da..4fead33bd826e 100644 --- a/clang/test/Preprocessor/init-mips.c +++ b/clang/test/Preprocessor/init-mips.c @@ -49,26 +49,31 @@ // MIPS32BE:#define __FLT_MIN_EXP__ (-125) // MIPS32BE:#define __FLT_MIN__ 1.17549435e-38F // MIPS32BE:#define __FLT_RADIX__ 2 +// MIPS32BE:#define __INT16_C(c) c // MIPS32BE:#define __INT16_C_SUFFIX__ // MIPS32BE:#define __INT16_FMTd__ "hd" // MIPS32BE:#define __INT16_FMTi__ "hi" // MIPS32BE:#define __INT16_MAX__ 32767 // MIPS32BE:#define __INT16_TYPE__ short +// MIPS32BE:#define __INT32_C(c) c // MIPS32BE:#define __INT32_C_SUFFIX__ // MIPS32BE:#define __INT32_FMTd__ "d" // MIPS32BE:#define __INT32_FMTi__ "i" // MIPS32BE:#define __INT32_MAX__ 2147483647 // MIPS32BE:#define __INT32_TYPE__ int +// MIPS32BE:#define __INT64_C(c) c##LL // MIPS32BE:#define __INT64_C_SUFFIX__ LL // MIPS32BE:#define __INT64_FMTd__ "lld" // MIPS32BE:#define __INT64_FMTi__ "lli" // MIPS32BE:#define __INT64_MAX__ 9223372036854775807LL // MIPS32BE:#define __INT64_TYPE__ long long int +// MIPS32BE:#define __INT8_C(c) c // MIPS32BE:#define __INT8_C_SUFFIX__ // MIPS32BE:#define __INT8_FMTd__ "hhd" // MIPS32BE:#define __INT8_FMTi__ "hhi" // MIPS32BE:#define __INT8_MAX__ 127 // MIPS32BE:#define __INT8_TYPE__ signed char +// MIPS32BE:#define __INTMAX_C(c) c##LL // MIPS32BE:#define __INTMAX_C_SUFFIX__ LL // MIPS32BE:#define __INTMAX_FMTd__ "lld" // MIPS32BE:#define __INTMAX_FMTi__ "lli" @@ -159,18 +164,23 @@ // MIPS32BE:#define __STDC_HOSTED__ 0 // MIPS32BE-C:#define __STDC_VERSION__ 201710L // MIPS32BE:#define __STDC__ 1 +// MIPS32BE:#define __UINT16_C(c) c // MIPS32BE:#define __UINT16_C_SUFFIX__ // MIPS32BE:#define __UINT16_MAX__ 65535 // MIPS32BE:#define __UINT16_TYPE__ unsigned short +// MIPS32BE:#define __UINT32_C(c) c##U // MIPS32BE:#define __UINT32_C_SUFFIX__ U // MIPS32BE:#define __UINT32_MAX__ 4294967295U // MIPS32BE:#define __UINT32_TYPE__ unsigned int +// MIPS32BE:#define __UINT64_C(c) c##ULL // MIPS32BE:#define __UINT64_C_SUFFIX__ ULL // MIPS32BE:#define __UINT64_MAX__ 18446744073709551615ULL // MIPS32BE:#define __UINT64_TYPE__ long long unsigned int +// MIPS32BE:#define __UINT8_C(c) c // MIPS32BE:#define __UINT8_C_SUFFIX__ // MIPS32BE:#define __UINT8_MAX__ 255 // MIPS32BE:#define __UINT8_TYPE__ unsigned char +// MIPS32BE:#define __UINTMAX_C(c) c##ULL // MIPS32BE:#define __UINTMAX_C_SUFFIX__ ULL // MIPS32BE:#define __UINTMAX_MAX__ 18446744073709551615ULL // MIPS32BE:#define __UINTMAX_TYPE__ long long unsigned int @@ -259,26 +269,31 @@ // MIPS32EL:#define __FLT_MIN_EXP__ (-125) // MIPS32EL:#define __FLT_MIN__ 1.17549435e-38F // MIPS32EL:#define __FLT_RADIX__ 2 +// MIPS32EL:#define __INT16_C(c) c // MIPS32EL:#define __INT16_C_SUFFIX__ // MIPS32EL:#define __INT16_FMTd__ "hd" // MIPS32EL:#define __INT16_FMTi__ "hi" // MIPS32EL:#define __INT16_MAX__ 32767 // MIPS32EL:#define __INT16_TYPE__ short +// MIPS32EL:#define __INT32_C(c) c // MIPS32EL:#define __INT32_C_SUFFIX__ // MIPS32EL:#define __INT32_FMTd__ "d" // MIPS32EL:#define __INT32_FMTi__ "i" // MIPS32EL:#define __INT32_MAX__ 2147483647 // MIPS32EL:#define __INT32_TYPE__ int +// MIPS32EL:#define __INT64_C(c) c##LL // MIPS32EL:#define __INT64_C_SUFFIX__ LL // MIPS32EL:#define __INT64_FMTd__ "lld" // MIPS32EL:#define __INT64_FMTi__ "lli" // MIPS32EL:#define __INT64_MAX__ 9223372036854775807LL // MIPS32EL:#define __INT64_TYPE__ long long int +// MIPS32EL:#define __INT8_C(c) c // MIPS32EL:#define __INT8_C_SUFFIX__ // MIPS32EL:#define __INT8_FMTd__ "hhd" // MIPS32EL:#define __INT8_FMTi__ "hhi" // MIPS32EL:#define __INT8_MAX__ 127 // MIPS32EL:#define __INT8_TYPE__ signed char +// MIPS32EL:#define __INTMAX_C(c) c##LL // MIPS32EL:#define __INTMAX_C_SUFFIX__ LL // MIPS32EL:#define __INTMAX_FMTd__ "lld" // MIPS32EL:#define __INTMAX_FMTi__ "lli" @@ -366,18 +381,23 @@ // MIPS32EL:#define __SIZE_MAX__ 4294967295U // MIPS32EL:#define __SIZE_TYPE__ unsigned int // MIPS32EL:#define __SIZE_WIDTH__ 32 +// MIPS32EL:#define __UINT16_C(c) c // MIPS32EL:#define __UINT16_C_SUFFIX__ // MIPS32EL:#define __UINT16_MAX__ 65535 // MIPS32EL:#define __UINT16_TYPE__ unsigned short +// MIPS32EL:#define __UINT32_C(c) c##U // MIPS32EL:#define __UINT32_C_SUFFIX__ U // MIPS32EL:#define __UINT32_MAX__ 4294967295U // MIPS32EL:#define __UINT32_TYPE__ unsigned int +// MIPS32EL:#define __UINT64_C(c) c##ULL // MIPS32EL:#define __UINT64_C_SUFFIX__ ULL // MIPS32EL:#define __UINT64_MAX__ 18446744073709551615ULL // MIPS32EL:#define __UINT64_TYPE__ long long unsigned int +// MIPS32EL:#define __UINT8_C(c) c // MIPS32EL:#define __UINT8_C_SUFFIX__ // MIPS32EL:#define __UINT8_MAX__ 255 // MIPS32EL:#define __UINT8_TYPE__ unsigned char +// MIPS32EL:#define __UINTMAX_C(c) c##ULL // MIPS32EL:#define __UINTMAX_C_SUFFIX__ ULL // MIPS32EL:#define __UINTMAX_MAX__ 18446744073709551615ULL // MIPS32EL:#define __UINTMAX_TYPE__ long long unsigned int @@ -496,26 +516,31 @@ // MIPSN32BE: #define __GNUC__ 4 // MIPSN32BE: #define __GXX_ABI_VERSION 1002 // MIPSN32BE: #define __ILP32__ 1 +// MIPSN32BE: #define __INT16_C(c) c // MIPSN32BE: #define __INT16_C_SUFFIX__ // MIPSN32BE: #define __INT16_FMTd__ "hd" // MIPSN32BE: #define __INT16_FMTi__ "hi" // MIPSN32BE: #define __INT16_MAX__ 32767 // MIPSN32BE: #define __INT16_TYPE__ short +// MIPSN32BE: #define __INT32_C(c) c // MIPSN32BE: #define __INT32_C_SUFFIX__ // MIPSN32BE: #define __INT32_FMTd__ "d" // MIPSN32BE: #define __INT32_FMTi__ "i" // MIPSN32BE: #define __INT32_MAX__ 2147483647 // MIPSN32BE: #define __INT32_TYPE__ int +// MIPSN32BE: #define __INT64_C(c) c##LL // MIPSN32BE: #define __INT64_C_SUFFIX__ LL // MIPSN32BE: #define __INT64_FMTd__ "lld" // MIPSN32BE: #define __INT64_FMTi__ "lli" // MIPSN32BE: #define __INT64_MAX__ 9223372036854775807LL // MIPSN32BE: #define __INT64_TYPE__ long long int +// MIPSN32BE: #define __INT8_C(c) c // MIPSN32BE: #define __INT8_C_SUFFIX__ // MIPSN32BE: #define __INT8_FMTd__ "hhd" // MIPSN32BE: #define __INT8_FMTi__ "hhi" // MIPSN32BE: #define __INT8_MAX__ 127 // MIPSN32BE: #define __INT8_TYPE__ signed char +// MIPSN32BE: #define __INTMAX_C(c) c##LL // MIPSN32BE: #define __INTMAX_C_SUFFIX__ LL // MIPSN32BE: #define __INTMAX_FMTd__ "lld" // MIPSN32BE: #define __INTMAX_FMTi__ "lli" @@ -618,6 +643,7 @@ // MIPSN32BE: #define __STDC_UTF_32__ 1 // MIPSN32BE-C: #define __STDC_VERSION__ 201710L // MIPSN32BE: #define __STDC__ 1 +// MIPSN32BE: #define __UINT16_C(c) c // MIPSN32BE: #define __UINT16_C_SUFFIX__ // MIPSN32BE: #define __UINT16_FMTX__ "hX" // MIPSN32BE: #define __UINT16_FMTo__ "ho" @@ -625,6 +651,7 @@ // MIPSN32BE: #define __UINT16_FMTx__ "hx" // MIPSN32BE: #define __UINT16_MAX__ 65535 // MIPSN32BE: #define __UINT16_TYPE__ unsigned short +// MIPSN32BE: #define __UINT32_C(c) c##U // MIPSN32BE: #define __UINT32_C_SUFFIX__ U // MIPSN32BE: #define __UINT32_FMTX__ "X" // MIPSN32BE: #define __UINT32_FMTo__ "o" @@ -632,6 +659,7 @@ // MIPSN32BE: #define __UINT32_FMTx__ "x" // MIPSN32BE: #define __UINT32_MAX__ 4294967295U // MIPSN32BE: #define __UINT32_TYPE__ unsigned int +// MIPSN32BE: #define __UINT64_C(c) c##ULL // MIPSN32BE: #define __UINT64_C_SUFFIX__ ULL // MIPSN32BE: #define __UINT64_FMTX__ "llX" // MIPSN32BE: #define __UINT64_FMTo__ "llo" @@ -639,6 +667,7 @@ // MIPSN32BE: #define __UINT64_FMTx__ "llx" // MIPSN32BE: #define __UINT64_MAX__ 18446744073709551615ULL // MIPSN32BE: #define __UINT64_TYPE__ long long unsigned int +// MIPSN32BE: #define __UINT8_C(c) c // MIPSN32BE: #define __UINT8_C_SUFFIX__ // MIPSN32BE: #define __UINT8_FMTX__ "hhX" // MIPSN32BE: #define __UINT8_FMTo__ "hho" @@ -646,6 +675,7 @@ // MIPSN32BE: #define __UINT8_FMTx__ "hhx" // MIPSN32BE: #define __UINT8_MAX__ 255 // MIPSN32BE: #define __UINT8_TYPE__ unsigned char +// MIPSN32BE: #define __UINTMAX_C(c) c##ULL // MIPSN32BE: #define __UINTMAX_C_SUFFIX__ ULL // MIPSN32BE: #define __UINTMAX_FMTX__ "llX" // MIPSN32BE: #define __UINTMAX_FMTo__ "llo" @@ -803,26 +833,31 @@ // MIPSN32EL: #define __GNUC__ 4 // MIPSN32EL: #define __GXX_ABI_VERSION 1002 // MIPSN32EL: #define __ILP32__ 1 +// MIPSN32EL: #define __INT16_C(c) c // MIPSN32EL: #define __INT16_C_SUFFIX__ // MIPSN32EL: #define __INT16_FMTd__ "hd" // MIPSN32EL: #define __INT16_FMTi__ "hi" // MIPSN32EL: #define __INT16_MAX__ 32767 // MIPSN32EL: #define __INT16_TYPE__ short +// MIPSN32EL: #define __INT32_C(c) c // MIPSN32EL: #define __INT32_C_SUFFIX__ // MIPSN32EL: #define __INT32_FMTd__ "d" // MIPSN32EL: #define __INT32_FMTi__ "i" // MIPSN32EL: #define __INT32_MAX__ 2147483647 // MIPSN32EL: #define __INT32_TYPE__ int +// MIPSN32EL: #define __INT64_C(c) c##LL // MIPSN32EL: #define __INT64_C_SUFFIX__ LL // MIPSN32EL: #define __INT64_FMTd__ "lld" // MIPSN32EL: #define __INT64_FMTi__ "lli" // MIPSN32EL: #define __INT64_MAX__ 9223372036854775807LL // MIPSN32EL: #define __INT64_TYPE__ long long int +// MIPSN32EL: #define __INT8_C(c) c // MIPSN32EL: #define __INT8_C_SUFFIX__ // MIPSN32EL: #define __INT8_FMTd__ "hhd" // MIPSN32EL: #define __INT8_FMTi__ "hhi" // MIPSN32EL: #define __INT8_MAX__ 127 // MIPSN32EL: #define __INT8_TYPE__ signed char +// MIPSN32EL: #define __INTMAX_C(c) c##LL // MIPSN32EL: #define __INTMAX_C_SUFFIX__ LL // MIPSN32EL: #define __INTMAX_FMTd__ "lld" // MIPSN32EL: #define __INTMAX_FMTi__ "lli" @@ -925,6 +960,7 @@ // MIPSN32EL: #define __STDC_UTF_32__ 1 // MIPSN32EL: #define __STDC_VERSION__ 201710L // MIPSN32EL: #define __STDC__ 1 +// MIPSN32EL: #define __UINT16_C(c) c // MIPSN32EL: #define __UINT16_C_SUFFIX__ // MIPSN32EL: #define __UINT16_FMTX__ "hX" // MIPSN32EL: #define __UINT16_FMTo__ "ho" @@ -932,6 +968,7 @@ // MIPSN32EL: #define __UINT16_FMTx__ "hx" // MIPSN32EL: #define __UINT16_MAX__ 65535 // MIPSN32EL: #define __UINT16_TYPE__ unsigned short +// MIPSN32EL: #define __UINT32_C(c) c##U // MIPSN32EL: #define __UINT32_C_SUFFIX__ U // MIPSN32EL: #define __UINT32_FMTX__ "X" // MIPSN32EL: #define __UINT32_FMTo__ "o" @@ -939,6 +976,7 @@ // MIPSN32EL: #define __UINT32_FMTx__ "x" // MIPSN32EL: #define __UINT32_MAX__ 4294967295U // MIPSN32EL: #define __UINT32_TYPE__ unsigned int +// MIPSN32EL: #define __UINT64_C(c) c##ULL // MIPSN32EL: #define __UINT64_C_SUFFIX__ ULL // MIPSN32EL: #define __UINT64_FMTX__ "llX" // MIPSN32EL: #define __UINT64_FMTo__ "llo" @@ -946,6 +984,7 @@ // MIPSN32EL: #define __UINT64_FMTx__ "llx" // MIPSN32EL: #define __UINT64_MAX__ 18446744073709551615ULL // MIPSN32EL: #define __UINT64_TYPE__ long long unsigned int +// MIPSN32EL: #define __UINT8_C(c) c // MIPSN32EL: #define __UINT8_C_SUFFIX__ // MIPSN32EL: #define __UINT8_FMTX__ "hhX" // MIPSN32EL: #define __UINT8_FMTo__ "hho" @@ -953,6 +992,7 @@ // MIPSN32EL: #define __UINT8_FMTx__ "hhx" // MIPSN32EL: #define __UINT8_MAX__ 255 // MIPSN32EL: #define __UINT8_TYPE__ unsigned char +// MIPSN32EL: #define __UINTMAX_C(c) c##ULL // MIPSN32EL: #define __UINTMAX_C_SUFFIX__ ULL // MIPSN32EL: #define __UINTMAX_FMTX__ "llX" // MIPSN32EL: #define __UINTMAX_FMTo__ "llo" @@ -1086,26 +1126,31 @@ // MIPS64BE:#define __FLT_MIN_EXP__ (-125) // MIPS64BE:#define __FLT_MIN__ 1.17549435e-38F // MIPS64BE:#define __FLT_RADIX__ 2 +// MIPS64BE:#define __INT16_C(c) c // MIPS64BE:#define __INT16_C_SUFFIX__ // MIPS64BE:#define __INT16_FMTd__ "hd" // MIPS64BE:#define __INT16_FMTi__ "hi" // MIPS64BE:#define __INT16_MAX__ 32767 // MIPS64BE:#define __INT16_TYPE__ short +// MIPS64BE:#define __INT32_C(c) c // MIPS64BE:#define __INT32_C_SUFFIX__ // MIPS64BE:#define __INT32_FMTd__ "d" // MIPS64BE:#define __INT32_FMTi__ "i" // MIPS64BE:#define __INT32_MAX__ 2147483647 // MIPS64BE:#define __INT32_TYPE__ int +// MIPS64BE:#define __INT64_C(c) c##L // MIPS64BE:#define __INT64_C_SUFFIX__ L // MIPS64BE:#define __INT64_FMTd__ "ld" // MIPS64BE:#define __INT64_FMTi__ "li" // MIPS64BE:#define __INT64_MAX__ 9223372036854775807L // MIPS64BE:#define __INT64_TYPE__ long int +// MIPS64BE:#define __INT8_C(c) c // MIPS64BE:#define __INT8_C_SUFFIX__ // MIPS64BE:#define __INT8_FMTd__ "hhd" // MIPS64BE:#define __INT8_FMTi__ "hhi" // MIPS64BE:#define __INT8_MAX__ 127 // MIPS64BE:#define __INT8_TYPE__ signed char +// MIPS64BE:#define __INTMAX_C(c) c##L // MIPS64BE:#define __INTMAX_C_SUFFIX__ L // MIPS64BE:#define __INTMAX_FMTd__ "ld" // MIPS64BE:#define __INTMAX_FMTi__ "li" @@ -1194,18 +1239,23 @@ // MIPS64BE:#define __SIZE_TYPE__ long unsigned int // MIPS64BE:#define __SIZE_WIDTH__ 64 // MIPS64BE-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// MIPS64BE:#define __UINT16_C(c) c // MIPS64BE:#define __UINT16_C_SUFFIX__ // MIPS64BE:#define __UINT16_MAX__ 65535 // MIPS64BE:#define __UINT16_TYPE__ unsigned short +// MIPS64BE:#define __UINT32_C(c) c##U // MIPS64BE:#define __UINT32_C_SUFFIX__ U // MIPS64BE:#define __UINT32_MAX__ 4294967295U // MIPS64BE:#define __UINT32_TYPE__ unsigned int +// MIPS64BE:#define __UINT64_C(c) c##UL // MIPS64BE:#define __UINT64_C_SUFFIX__ UL // MIPS64BE:#define __UINT64_MAX__ 18446744073709551615UL // MIPS64BE:#define __UINT64_TYPE__ long unsigned int +// MIPS64BE:#define __UINT8_C(c) c // MIPS64BE:#define __UINT8_C_SUFFIX__ // MIPS64BE:#define __UINT8_MAX__ 255 // MIPS64BE:#define __UINT8_TYPE__ unsigned char +// MIPS64BE:#define __UINTMAX_C(c) c##UL // MIPS64BE:#define __UINTMAX_C_SUFFIX__ UL // MIPS64BE:#define __UINTMAX_MAX__ 18446744073709551615UL // MIPS64BE:#define __UINTMAX_TYPE__ long unsigned int @@ -1296,26 +1346,31 @@ // MIPS64EL:#define __FLT_MIN_EXP__ (-125) // MIPS64EL:#define __FLT_MIN__ 1.17549435e-38F // MIPS64EL:#define __FLT_RADIX__ 2 +// MIPS64EL:#define __INT16_C(c) c // MIPS64EL:#define __INT16_C_SUFFIX__ // MIPS64EL:#define __INT16_FMTd__ "hd" // MIPS64EL:#define __INT16_FMTi__ "hi" // MIPS64EL:#define __INT16_MAX__ 32767 // MIPS64EL:#define __INT16_TYPE__ short +// MIPS64EL:#define __INT32_C(c) c // MIPS64EL:#define __INT32_C_SUFFIX__ // MIPS64EL:#define __INT32_FMTd__ "d" // MIPS64EL:#define __INT32_FMTi__ "i" // MIPS64EL:#define __INT32_MAX__ 2147483647 // MIPS64EL:#define __INT32_TYPE__ int +// MIPS64EL:#define __INT64_C(c) c##L // MIPS64EL:#define __INT64_C_SUFFIX__ L // MIPS64EL:#define __INT64_FMTd__ "ld" // MIPS64EL:#define __INT64_FMTi__ "li" // MIPS64EL:#define __INT64_MAX__ 9223372036854775807L // MIPS64EL:#define __INT64_TYPE__ long int +// MIPS64EL:#define __INT8_C(c) c // MIPS64EL:#define __INT8_C_SUFFIX__ // MIPS64EL:#define __INT8_FMTd__ "hhd" // MIPS64EL:#define __INT8_FMTi__ "hhi" // MIPS64EL:#define __INT8_MAX__ 127 // MIPS64EL:#define __INT8_TYPE__ signed char +// MIPS64EL:#define __INTMAX_C(c) c##L // MIPS64EL:#define __INTMAX_C_SUFFIX__ L // MIPS64EL:#define __INTMAX_FMTd__ "ld" // MIPS64EL:#define __INTMAX_FMTi__ "li" @@ -1404,18 +1459,23 @@ // MIPS64EL:#define __SIZE_MAX__ 18446744073709551615UL // MIPS64EL:#define __SIZE_TYPE__ long unsigned int // MIPS64EL:#define __SIZE_WIDTH__ 64 +// MIPS64EL:#define __UINT16_C(c) c // MIPS64EL:#define __UINT16_C_SUFFIX__ // MIPS64EL:#define __UINT16_MAX__ 65535 // MIPS64EL:#define __UINT16_TYPE__ unsigned short +// MIPS64EL:#define __UINT32_C(c) c##U // MIPS64EL:#define __UINT32_C_SUFFIX__ U // MIPS64EL:#define __UINT32_MAX__ 4294967295U // MIPS64EL:#define __UINT32_TYPE__ unsigned int +// MIPS64EL:#define __UINT64_C(c) c##UL // MIPS64EL:#define __UINT64_C_SUFFIX__ UL // MIPS64EL:#define __UINT64_MAX__ 18446744073709551615UL // MIPS64EL:#define __UINT64_TYPE__ long unsigned int +// MIPS64EL:#define __UINT8_C(c) c // MIPS64EL:#define __UINT8_C_SUFFIX__ // MIPS64EL:#define __UINT8_MAX__ 255 // MIPS64EL:#define __UINT8_TYPE__ unsigned char +// MIPS64EL:#define __UINTMAX_C(c) c##UL // MIPS64EL:#define __UINTMAX_C_SUFFIX__ UL // MIPS64EL:#define __UINTMAX_MAX__ 18446744073709551615UL // MIPS64EL:#define __UINTMAX_TYPE__ long unsigned int diff --git a/clang/test/Preprocessor/init-ppc.c b/clang/test/Preprocessor/init-ppc.c index 1421b102a3dfd..6b7eceda9b97b 100644 --- a/clang/test/Preprocessor/init-ppc.c +++ b/clang/test/Preprocessor/init-ppc.c @@ -41,26 +41,31 @@ // PPC603E:#define __FLT_MIN_EXP__ (-125) // PPC603E:#define __FLT_MIN__ 1.17549435e-38F // PPC603E:#define __FLT_RADIX__ 2 +// PPC603E:#define __INT16_C(c) c // PPC603E:#define __INT16_C_SUFFIX__ // PPC603E:#define __INT16_FMTd__ "hd" // PPC603E:#define __INT16_FMTi__ "hi" // PPC603E:#define __INT16_MAX__ 32767 // PPC603E:#define __INT16_TYPE__ short +// PPC603E:#define __INT32_C(c) c // PPC603E:#define __INT32_C_SUFFIX__ // PPC603E:#define __INT32_FMTd__ "d" // PPC603E:#define __INT32_FMTi__ "i" // PPC603E:#define __INT32_MAX__ 2147483647 // PPC603E:#define __INT32_TYPE__ int +// PPC603E:#define __INT64_C(c) c##LL // PPC603E:#define __INT64_C_SUFFIX__ LL // PPC603E:#define __INT64_FMTd__ "lld" // PPC603E:#define __INT64_FMTi__ "lli" // PPC603E:#define __INT64_MAX__ 9223372036854775807LL // PPC603E:#define __INT64_TYPE__ long long int +// PPC603E:#define __INT8_C(c) c // PPC603E:#define __INT8_C_SUFFIX__ // PPC603E:#define __INT8_FMTd__ "hhd" // PPC603E:#define __INT8_FMTi__ "hhi" // PPC603E:#define __INT8_MAX__ 127 // PPC603E:#define __INT8_TYPE__ signed char +// PPC603E:#define __INTMAX_C(c) c##LL // PPC603E:#define __INTMAX_C_SUFFIX__ LL // PPC603E:#define __INTMAX_FMTd__ "lld" // PPC603E:#define __INTMAX_FMTi__ "lli" @@ -150,18 +155,23 @@ // PPC603E:#define __SIZE_TYPE__ long unsigned int // PPC603E:#define __SIZE_WIDTH__ 32 // PPC603E-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// PPC603E:#define __UINT16_C(c) c // PPC603E:#define __UINT16_C_SUFFIX__ // PPC603E:#define __UINT16_MAX__ 65535 // PPC603E:#define __UINT16_TYPE__ unsigned short +// PPC603E:#define __UINT32_C(c) c##U // PPC603E:#define __UINT32_C_SUFFIX__ U // PPC603E:#define __UINT32_MAX__ 4294967295U // PPC603E:#define __UINT32_TYPE__ unsigned int +// PPC603E:#define __UINT64_C(c) c##ULL // PPC603E:#define __UINT64_C_SUFFIX__ ULL // PPC603E:#define __UINT64_MAX__ 18446744073709551615ULL // PPC603E:#define __UINT64_TYPE__ long long unsigned int +// PPC603E:#define __UINT8_C(c) c // PPC603E:#define __UINT8_C_SUFFIX__ // PPC603E:#define __UINT8_MAX__ 255 // PPC603E:#define __UINT8_TYPE__ unsigned char +// PPC603E:#define __UINTMAX_C(c) c##ULL // PPC603E:#define __UINTMAX_C_SUFFIX__ ULL // PPC603E:#define __UINTMAX_MAX__ 18446744073709551615ULL // PPC603E:#define __UINTMAX_TYPE__ long long unsigned int @@ -235,26 +245,31 @@ // PPC:#define __FLT_MIN__ 1.17549435e-38F // PPC:#define __FLT_RADIX__ 2 // PPC:#define __HAVE_BSWAP__ 1 +// PPC:#define __INT16_C(c) c // PPC:#define __INT16_C_SUFFIX__ // PPC:#define __INT16_FMTd__ "hd" // PPC:#define __INT16_FMTi__ "hi" // PPC:#define __INT16_MAX__ 32767 // PPC:#define __INT16_TYPE__ short +// PPC:#define __INT32_C(c) c // PPC:#define __INT32_C_SUFFIX__ // PPC:#define __INT32_FMTd__ "d" // PPC:#define __INT32_FMTi__ "i" // PPC:#define __INT32_MAX__ 2147483647 // PPC:#define __INT32_TYPE__ int +// PPC:#define __INT64_C(c) c##LL // PPC:#define __INT64_C_SUFFIX__ LL // PPC:#define __INT64_FMTd__ "lld" // PPC:#define __INT64_FMTi__ "lli" // PPC:#define __INT64_MAX__ 9223372036854775807LL // PPC:#define __INT64_TYPE__ long long int +// PPC:#define __INT8_C(c) c // PPC:#define __INT8_C_SUFFIX__ // PPC:#define __INT8_FMTd__ "hhd" // PPC:#define __INT8_FMTi__ "hhi" // PPC:#define __INT8_MAX__ 127 // PPC:#define __INT8_TYPE__ signed char +// PPC:#define __INTMAX_C(c) c##LL // PPC:#define __INTMAX_C_SUFFIX__ LL // PPC:#define __INTMAX_FMTd__ "lld" // PPC:#define __INTMAX_FMTi__ "lli" @@ -344,18 +359,23 @@ // PPC:#define __SIZE_MAX__ 4294967295UL // PPC:#define __SIZE_TYPE__ long unsigned int // PPC:#define __SIZE_WIDTH__ 32 +// PPC:#define __UINT16_C(c) c // PPC:#define __UINT16_C_SUFFIX__ // PPC:#define __UINT16_MAX__ 65535 // PPC:#define __UINT16_TYPE__ unsigned short +// PPC:#define __UINT32_C(c) c##U // PPC:#define __UINT32_C_SUFFIX__ U // PPC:#define __UINT32_MAX__ 4294967295U // PPC:#define __UINT32_TYPE__ unsigned int +// PPC:#define __UINT64_C(c) c##ULL // PPC:#define __UINT64_C_SUFFIX__ ULL // PPC:#define __UINT64_MAX__ 18446744073709551615ULL // PPC:#define __UINT64_TYPE__ long long unsigned int +// PPC:#define __UINT8_C(c) c // PPC:#define __UINT8_C_SUFFIX__ // PPC:#define __UINT8_MAX__ 255 // PPC:#define __UINT8_TYPE__ unsigned char +// PPC:#define __UINTMAX_C(c) c##ULL // PPC:#define __UINTMAX_C_SUFFIX__ ULL // PPC:#define __UINTMAX_MAX__ 18446744073709551615ULL // PPC:#define __UINTMAX_TYPE__ long long unsigned int @@ -435,26 +455,31 @@ // PPC-AIX:#define __FLT_MIN__ 1.17549435e-38F // PPC-AIX:#define __FLT_RADIX__ 2 // PPC-AIX:#define __HOS_AIX__ 1 +// PPC-AIX:#define __INT16_C(c) c // PPC-AIX:#define __INT16_C_SUFFIX__ // PPC-AIX:#define __INT16_FMTd__ "hd" // PPC-AIX:#define __INT16_FMTi__ "hi" // PPC-AIX:#define __INT16_MAX__ 32767 // PPC-AIX:#define __INT16_TYPE__ short +// PPC-AIX:#define __INT32_C(c) c // PPC-AIX:#define __INT32_C_SUFFIX__ // PPC-AIX:#define __INT32_FMTd__ "d" // PPC-AIX:#define __INT32_FMTi__ "i" // PPC-AIX:#define __INT32_MAX__ 2147483647 // PPC-AIX:#define __INT32_TYPE__ int +// PPC-AIX:#define __INT64_C(c) c##LL // PPC-AIX:#define __INT64_C_SUFFIX__ LL // PPC-AIX:#define __INT64_FMTd__ "lld" // PPC-AIX:#define __INT64_FMTi__ "lli" // PPC-AIX:#define __INT64_MAX__ 9223372036854775807LL // PPC-AIX:#define __INT64_TYPE__ long long int +// PPC-AIX:#define __INT8_C(c) c // PPC-AIX:#define __INT8_C_SUFFIX__ // PPC-AIX:#define __INT8_FMTd__ "hhd" // PPC-AIX:#define __INT8_FMTi__ "hhi" // PPC-AIX:#define __INT8_MAX__ 127 // PPC-AIX:#define __INT8_TYPE__ signed char +// PPC-AIX:#define __INTMAX_C(c) c##LL // PPC-AIX:#define __INTMAX_C_SUFFIX__ LL // PPC-AIX:#define __INTMAX_FMTd__ "lld" // PPC-AIX:#define __INTMAX_FMTi__ "lli" @@ -546,18 +571,23 @@ // PPC-AIX:#define __THW_BIG_ENDIAN__ 1 // PPC-AIX:#define __THW_PPC__ 1 // PPC-AIX:#define __TOS_AIX__ 1 +// PPC-AIX:#define __UINT16_C(c) c // PPC-AIX:#define __UINT16_C_SUFFIX__ // PPC-AIX:#define __UINT16_MAX__ 65535 // PPC-AIX:#define __UINT16_TYPE__ unsigned short +// PPC-AIX:#define __UINT32_C(c) c##U // PPC-AIX:#define __UINT32_C_SUFFIX__ U // PPC-AIX:#define __UINT32_MAX__ 4294967295U // PPC-AIX:#define __UINT32_TYPE__ unsigned int +// PPC-AIX:#define __UINT64_C(c) c##ULL // PPC-AIX:#define __UINT64_C_SUFFIX__ ULL // PPC-AIX:#define __UINT64_MAX__ 18446744073709551615ULL // PPC-AIX:#define __UINT64_TYPE__ long long unsigned int +// PPC-AIX:#define __UINT8_C(c) c // PPC-AIX:#define __UINT8_C_SUFFIX__ // PPC-AIX:#define __UINT8_MAX__ 255 // PPC-AIX:#define __UINT8_TYPE__ unsigned char +// PPC-AIX:#define __UINTMAX_C(c) c##ULL // PPC-AIX:#define __UINTMAX_C_SUFFIX__ ULL // PPC-AIX:#define __UINTMAX_MAX__ 18446744073709551615ULL // PPC-AIX:#define __UINTMAX_TYPE__ long long unsigned int @@ -807,26 +837,31 @@ // PPC-LINUX:#define __FLT_MIN__ 1.17549435e-38F // PPC-LINUX:#define __FLT_RADIX__ 2 // PPC-LINUX:#define __HAVE_BSWAP__ 1 +// PPC-LINUX:#define __INT16_C(c) c // PPC-LINUX:#define __INT16_C_SUFFIX__ // PPC-LINUX:#define __INT16_FMTd__ "hd" // PPC-LINUX:#define __INT16_FMTi__ "hi" // PPC-LINUX:#define __INT16_MAX__ 32767 // PPC-LINUX:#define __INT16_TYPE__ short +// PPC-LINUX:#define __INT32_C(c) c // PPC-LINUX:#define __INT32_C_SUFFIX__ // PPC-LINUX:#define __INT32_FMTd__ "d" // PPC-LINUX:#define __INT32_FMTi__ "i" // PPC-LINUX:#define __INT32_MAX__ 2147483647 // PPC-LINUX:#define __INT32_TYPE__ int +// PPC-LINUX:#define __INT64_C(c) c##LL // PPC-LINUX:#define __INT64_C_SUFFIX__ LL // PPC-LINUX:#define __INT64_FMTd__ "lld" // PPC-LINUX:#define __INT64_FMTi__ "lli" // PPC-LINUX:#define __INT64_MAX__ 9223372036854775807LL // PPC-LINUX:#define __INT64_TYPE__ long long int +// PPC-LINUX:#define __INT8_C(c) c // PPC-LINUX:#define __INT8_C_SUFFIX__ // PPC-LINUX:#define __INT8_FMTd__ "hhd" // PPC-LINUX:#define __INT8_FMTi__ "hhi" // PPC-LINUX:#define __INT8_MAX__ 127 // PPC-LINUX:#define __INT8_TYPE__ signed char +// PPC-LINUX:#define __INTMAX_C(c) c##LL // PPC-LINUX:#define __INTMAX_C_SUFFIX__ LL // PPC-LINUX:#define __INTMAX_FMTd__ "lld" // PPC-LINUX:#define __INTMAX_FMTi__ "lli" @@ -915,18 +950,23 @@ // PPC-LINUX:#define __SIZE_MAX__ 4294967295U // PPC-LINUX:#define __SIZE_TYPE__ unsigned int // PPC-LINUX:#define __SIZE_WIDTH__ 32 +// PPC-LINUX:#define __UINT16_C(c) c // PPC-LINUX:#define __UINT16_C_SUFFIX__ // PPC-LINUX:#define __UINT16_MAX__ 65535 // PPC-LINUX:#define __UINT16_TYPE__ unsigned short +// PPC-LINUX:#define __UINT32_C(c) c##U // PPC-LINUX:#define __UINT32_C_SUFFIX__ U // PPC-LINUX:#define __UINT32_MAX__ 4294967295U // PPC-LINUX:#define __UINT32_TYPE__ unsigned int +// PPC-LINUX:#define __UINT64_C(c) c##ULL // PPC-LINUX:#define __UINT64_C_SUFFIX__ ULL // PPC-LINUX:#define __UINT64_MAX__ 18446744073709551615ULL // PPC-LINUX:#define __UINT64_TYPE__ long long unsigned int +// PPC-LINUX:#define __UINT8_C(c) c // PPC-LINUX:#define __UINT8_C_SUFFIX__ // PPC-LINUX:#define __UINT8_MAX__ 255 // PPC-LINUX:#define __UINT8_TYPE__ unsigned char +// PPC-LINUX:#define __UINTMAX_C(c) c##ULL // PPC-LINUX:#define __UINTMAX_C_SUFFIX__ ULL // PPC-LINUX:#define __UINTMAX_MAX__ 18446744073709551615ULL // PPC-LINUX:#define __UINTMAX_TYPE__ long long unsigned int diff --git a/clang/test/Preprocessor/init-ppc64.c b/clang/test/Preprocessor/init-ppc64.c index 57e2ca31d5d53..7dffd4627481b 100644 --- a/clang/test/Preprocessor/init-ppc64.c +++ b/clang/test/Preprocessor/init-ppc64.c @@ -47,26 +47,31 @@ // PPC64:#define __FLT_MIN__ 1.17549435e-38F // PPC64:#define __FLT_RADIX__ 2 // PPC64:#define __HAVE_BSWAP__ 1 +// PPC64:#define __INT16_C(c) c // PPC64:#define __INT16_C_SUFFIX__ // PPC64:#define __INT16_FMTd__ "hd" // PPC64:#define __INT16_FMTi__ "hi" // PPC64:#define __INT16_MAX__ 32767 // PPC64:#define __INT16_TYPE__ short +// PPC64:#define __INT32_C(c) c // PPC64:#define __INT32_C_SUFFIX__ // PPC64:#define __INT32_FMTd__ "d" // PPC64:#define __INT32_FMTi__ "i" // PPC64:#define __INT32_MAX__ 2147483647 // PPC64:#define __INT32_TYPE__ int +// PPC64:#define __INT64_C(c) c##L // PPC64:#define __INT64_C_SUFFIX__ L // PPC64:#define __INT64_FMTd__ "ld" // PPC64:#define __INT64_FMTi__ "li" // PPC64:#define __INT64_MAX__ 9223372036854775807L // PPC64:#define __INT64_TYPE__ long int +// PPC64:#define __INT8_C(c) c // PPC64:#define __INT8_C_SUFFIX__ // PPC64:#define __INT8_FMTd__ "hhd" // PPC64:#define __INT8_FMTi__ "hhi" // PPC64:#define __INT8_MAX__ 127 // PPC64:#define __INT8_TYPE__ signed char +// PPC64:#define __INTMAX_C(c) c##L // PPC64:#define __INTMAX_C_SUFFIX__ L // PPC64:#define __INTMAX_FMTd__ "ld" // PPC64:#define __INTMAX_FMTi__ "li" @@ -157,18 +162,23 @@ // PPC64:#define __SIZE_TYPE__ long unsigned int // PPC64:#define __SIZE_WIDTH__ 64 // PPC64-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// PPC64:#define __UINT16_C(c) c // PPC64:#define __UINT16_C_SUFFIX__ // PPC64:#define __UINT16_MAX__ 65535 // PPC64:#define __UINT16_TYPE__ unsigned short +// PPC64:#define __UINT32_C(c) c##U // PPC64:#define __UINT32_C_SUFFIX__ U // PPC64:#define __UINT32_MAX__ 4294967295U // PPC64:#define __UINT32_TYPE__ unsigned int +// PPC64:#define __UINT64_C(c) c##UL // PPC64:#define __UINT64_C_SUFFIX__ UL // PPC64:#define __UINT64_MAX__ 18446744073709551615UL // PPC64:#define __UINT64_TYPE__ long unsigned int +// PPC64:#define __UINT8_C(c) c // PPC64:#define __UINT8_C_SUFFIX__ // PPC64:#define __UINT8_MAX__ 255 // PPC64:#define __UINT8_TYPE__ unsigned char +// PPC64:#define __UINTMAX_C(c) c##UL // PPC64:#define __UINTMAX_C_SUFFIX__ UL // PPC64:#define __UINTMAX_MAX__ 18446744073709551615UL // PPC64:#define __UINTMAX_TYPE__ long unsigned int @@ -250,26 +260,31 @@ // PPC64LE:#define __FLT_MIN__ 1.17549435e-38F // PPC64LE:#define __FLT_RADIX__ 2 // PPC64LE:#define __HAVE_BSWAP__ 1 +// PPC64LE:#define __INT16_C(c) c // PPC64LE:#define __INT16_C_SUFFIX__ // PPC64LE:#define __INT16_FMTd__ "hd" // PPC64LE:#define __INT16_FMTi__ "hi" // PPC64LE:#define __INT16_MAX__ 32767 // PPC64LE:#define __INT16_TYPE__ short +// PPC64LE:#define __INT32_C(c) c // PPC64LE:#define __INT32_C_SUFFIX__ // PPC64LE:#define __INT32_FMTd__ "d" // PPC64LE:#define __INT32_FMTi__ "i" // PPC64LE:#define __INT32_MAX__ 2147483647 // PPC64LE:#define __INT32_TYPE__ int +// PPC64LE:#define __INT64_C(c) c##L // PPC64LE:#define __INT64_C_SUFFIX__ L // PPC64LE:#define __INT64_FMTd__ "ld" // PPC64LE:#define __INT64_FMTi__ "li" // PPC64LE:#define __INT64_MAX__ 9223372036854775807L // PPC64LE:#define __INT64_TYPE__ long int +// PPC64LE:#define __INT8_C(c) c // PPC64LE:#define __INT8_C_SUFFIX__ // PPC64LE:#define __INT8_FMTd__ "hhd" // PPC64LE:#define __INT8_FMTi__ "hhi" // PPC64LE:#define __INT8_MAX__ 127 // PPC64LE:#define __INT8_TYPE__ signed char +// PPC64LE:#define __INTMAX_C(c) c##L // PPC64LE:#define __INTMAX_C_SUFFIX__ L // PPC64LE:#define __INTMAX_FMTd__ "ld" // PPC64LE:#define __INTMAX_FMTi__ "li" @@ -361,18 +376,23 @@ // PPC64LE:#define __SIZE_TYPE__ long unsigned int // PPC64LE:#define __SIZE_WIDTH__ 64 // PPC64LE:#define __STRUCT_PARM_ALIGN__ 16 +// PPC64LE:#define __UINT16_C(c) c // PPC64LE:#define __UINT16_C_SUFFIX__ // PPC64LE:#define __UINT16_MAX__ 65535 // PPC64LE:#define __UINT16_TYPE__ unsigned short +// PPC64LE:#define __UINT32_C(c) c##U // PPC64LE:#define __UINT32_C_SUFFIX__ U // PPC64LE:#define __UINT32_MAX__ 4294967295U // PPC64LE:#define __UINT32_TYPE__ unsigned int +// PPC64LE:#define __UINT64_C(c) c##UL // PPC64LE:#define __UINT64_C_SUFFIX__ UL // PPC64LE:#define __UINT64_MAX__ 18446744073709551615UL // PPC64LE:#define __UINT64_TYPE__ long unsigned int +// PPC64LE:#define __UINT8_C(c) c // PPC64LE:#define __UINT8_C_SUFFIX__ // PPC64LE:#define __UINT8_MAX__ 255 // PPC64LE:#define __UINT8_TYPE__ unsigned char +// PPC64LE:#define __UINTMAX_C(c) c##UL // PPC64LE:#define __UINTMAX_C_SUFFIX__ UL // PPC64LE:#define __UINTMAX_MAX__ 18446744073709551615UL // PPC64LE:#define __UINTMAX_TYPE__ long unsigned int @@ -733,26 +753,31 @@ // PPC64-AIX:#define __FLT_MIN__ 1.17549435e-38F // PPC64-AIX:#define __FLT_RADIX__ 2 // PPC64-AIX-NOT:#define __ILP32__ 1 +// PPC64-AIX:#define __INT16_C(c) c // PPC64-AIX:#define __INT16_C_SUFFIX__ // PPC64-AIX:#define __INT16_FMTd__ "hd" // PPC64-AIX:#define __INT16_FMTi__ "hi" // PPC64-AIX:#define __INT16_MAX__ 32767 // PPC64-AIX:#define __INT16_TYPE__ short +// PPC64-AIX:#define __INT32_C(c) c // PPC64-AIX:#define __INT32_C_SUFFIX__ // PPC64-AIX:#define __INT32_FMTd__ "d" // PPC64-AIX:#define __INT32_FMTi__ "i" // PPC64-AIX:#define __INT32_MAX__ 2147483647 // PPC64-AIX:#define __INT32_TYPE__ int +// PPC64-AIX:#define __INT64_C(c) c##L // PPC64-AIX:#define __INT64_C_SUFFIX__ L // PPC64-AIX:#define __INT64_FMTd__ "ld" // PPC64-AIX:#define __INT64_FMTi__ "li" // PPC64-AIX:#define __INT64_MAX__ 9223372036854775807L // PPC64-AIX:#define __INT64_TYPE__ long int +// PPC64-AIX:#define __INT8_C(c) c // PPC64-AIX:#define __INT8_C_SUFFIX__ // PPC64-AIX:#define __INT8_FMTd__ "hhd" // PPC64-AIX:#define __INT8_FMTi__ "hhi" // PPC64-AIX:#define __INT8_MAX__ 127 // PPC64-AIX:#define __INT8_TYPE__ signed char +// PPC64-AIX:#define __INTMAX_C(c) c##L // PPC64-AIX:#define __INTMAX_C_SUFFIX__ L // PPC64-AIX:#define __INTMAX_FMTd__ "ld" // PPC64-AIX:#define __INTMAX_FMTi__ "li" @@ -842,18 +867,23 @@ // PPC64-AIX:#define __SIZE_MAX__ 18446744073709551615UL // PPC64-AIX:#define __SIZE_TYPE__ long unsigned int // PPC64-AIX:#define __SIZE_WIDTH__ 64 +// PPC64-AIX:#define __UINT16_C(c) c // PPC64-AIX:#define __UINT16_C_SUFFIX__ // PPC64-AIX:#define __UINT16_MAX__ 65535 // PPC64-AIX:#define __UINT16_TYPE__ unsigned short +// PPC64-AIX:#define __UINT32_C(c) c##U // PPC64-AIX:#define __UINT32_C_SUFFIX__ U // PPC64-AIX:#define __UINT32_MAX__ 4294967295U // PPC64-AIX:#define __UINT32_TYPE__ unsigned int +// PPC64-AIX:#define __UINT64_C(c) c##UL // PPC64-AIX:#define __UINT64_C_SUFFIX__ UL // PPC64-AIX:#define __UINT64_MAX__ 18446744073709551615UL // PPC64-AIX:#define __UINT64_TYPE__ long unsigned int +// PPC64-AIX:#define __UINT8_C(c) c // PPC64-AIX:#define __UINT8_C_SUFFIX__ // PPC64-AIX:#define __UINT8_MAX__ 255 // PPC64-AIX:#define __UINT8_TYPE__ unsigned char +// PPC64-AIX:#define __UINTMAX_C(c) c##UL // PPC64-AIX:#define __UINTMAX_C_SUFFIX__ UL // PPC64-AIX:#define __UINTMAX_MAX__ 18446744073709551615UL // PPC64-AIX:#define __UINTMAX_TYPE__ long unsigned int @@ -930,26 +960,31 @@ // PPC64-LINUX:#define __FLT_MIN__ 1.17549435e-38F // PPC64-LINUX:#define __FLT_RADIX__ 2 // PPC64-LINUX:#define __HAVE_BSWAP__ 1 +// PPC64-LINUX:#define __INT16_C(c) c // PPC64-LINUX:#define __INT16_C_SUFFIX__ // PPC64-LINUX:#define __INT16_FMTd__ "hd" // PPC64-LINUX:#define __INT16_FMTi__ "hi" // PPC64-LINUX:#define __INT16_MAX__ 32767 // PPC64-LINUX:#define __INT16_TYPE__ short +// PPC64-LINUX:#define __INT32_C(c) c // PPC64-LINUX:#define __INT32_C_SUFFIX__ // PPC64-LINUX:#define __INT32_FMTd__ "d" // PPC64-LINUX:#define __INT32_FMTi__ "i" // PPC64-LINUX:#define __INT32_MAX__ 2147483647 // PPC64-LINUX:#define __INT32_TYPE__ int +// PPC64-LINUX:#define __INT64_C(c) c##L // PPC64-LINUX:#define __INT64_C_SUFFIX__ L // PPC64-LINUX:#define __INT64_FMTd__ "ld" // PPC64-LINUX:#define __INT64_FMTi__ "li" // PPC64-LINUX:#define __INT64_MAX__ 9223372036854775807L // PPC64-LINUX:#define __INT64_TYPE__ long int +// PPC64-LINUX:#define __INT8_C(c) c // PPC64-LINUX:#define __INT8_C_SUFFIX__ // PPC64-LINUX:#define __INT8_FMTd__ "hhd" // PPC64-LINUX:#define __INT8_FMTi__ "hhi" // PPC64-LINUX:#define __INT8_MAX__ 127 // PPC64-LINUX:#define __INT8_TYPE__ signed char +// PPC64-LINUX:#define __INTMAX_C(c) c##L // PPC64-LINUX:#define __INTMAX_C_SUFFIX__ L // PPC64-LINUX:#define __INTMAX_FMTd__ "ld" // PPC64-LINUX:#define __INTMAX_FMTi__ "li" @@ -1039,18 +1074,23 @@ // PPC64-LINUX:#define __SIZE_MAX__ 18446744073709551615UL // PPC64-LINUX:#define __SIZE_TYPE__ long unsigned int // PPC64-LINUX:#define __SIZE_WIDTH__ 64 +// PPC64-LINUX:#define __UINT16_C(c) c // PPC64-LINUX:#define __UINT16_C_SUFFIX__ // PPC64-LINUX:#define __UINT16_MAX__ 65535 // PPC64-LINUX:#define __UINT16_TYPE__ unsigned short +// PPC64-LINUX:#define __UINT32_C(c) c##U // PPC64-LINUX:#define __UINT32_C_SUFFIX__ U // PPC64-LINUX:#define __UINT32_MAX__ 4294967295U // PPC64-LINUX:#define __UINT32_TYPE__ unsigned int +// PPC64-LINUX:#define __UINT64_C(c) c##UL // PPC64-LINUX:#define __UINT64_C_SUFFIX__ UL // PPC64-LINUX:#define __UINT64_MAX__ 18446744073709551615UL // PPC64-LINUX:#define __UINT64_TYPE__ long unsigned int +// PPC64-LINUX:#define __UINT8_C(c) c // PPC64-LINUX:#define __UINT8_C_SUFFIX__ // PPC64-LINUX:#define __UINT8_MAX__ 255 // PPC64-LINUX:#define __UINT8_TYPE__ unsigned char +// PPC64-LINUX:#define __UINTMAX_C(c) c##UL // PPC64-LINUX:#define __UINTMAX_C_SUFFIX__ UL // PPC64-LINUX:#define __UINTMAX_MAX__ 18446744073709551615UL // PPC64-LINUX:#define __UINTMAX_TYPE__ long unsigned int diff --git a/clang/test/Preprocessor/init-s390x.c b/clang/test/Preprocessor/init-s390x.c index 6d08e9bfcb632..a8fbde46cbb75 100644 --- a/clang/test/Preprocessor/init-s390x.c +++ b/clang/test/Preprocessor/init-s390x.c @@ -34,26 +34,31 @@ // S390X:#define __FLT_MIN_EXP__ (-125) // S390X:#define __FLT_MIN__ 1.17549435e-38F // S390X:#define __FLT_RADIX__ 2 +// S390X:#define __INT16_C(c) c // S390X:#define __INT16_C_SUFFIX__ // S390X:#define __INT16_FMTd__ "hd" // S390X:#define __INT16_FMTi__ "hi" // S390X:#define __INT16_MAX__ 32767 // S390X:#define __INT16_TYPE__ short +// S390X:#define __INT32_C(c) c // S390X:#define __INT32_C_SUFFIX__ // S390X:#define __INT32_FMTd__ "d" // S390X:#define __INT32_FMTi__ "i" // S390X:#define __INT32_MAX__ 2147483647 // S390X:#define __INT32_TYPE__ int +// S390X:#define __INT64_C(c) c##L // S390X:#define __INT64_C_SUFFIX__ L // S390X:#define __INT64_FMTd__ "ld" // S390X:#define __INT64_FMTi__ "li" // S390X:#define __INT64_MAX__ 9223372036854775807L // S390X:#define __INT64_TYPE__ long int +// S390X:#define __INT8_C(c) c // S390X:#define __INT8_C_SUFFIX__ // S390X:#define __INT8_FMTd__ "hhd" // S390X:#define __INT8_FMTi__ "hhi" // S390X:#define __INT8_MAX__ 127 // S390X:#define __INT8_TYPE__ signed char +// S390X:#define __INTMAX_C(c) c##L // S390X:#define __INTMAX_C_SUFFIX__ L // S390X:#define __INTMAX_FMTd__ "ld" // S390X:#define __INTMAX_FMTi__ "li" @@ -136,18 +141,23 @@ // S390X:#define __SIZE_TYPE__ long unsigned int // S390X:#define __SIZE_WIDTH__ 64 // S390X-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8UL +// S390X:#define __UINT16_C(c) c // S390X:#define __UINT16_C_SUFFIX__ // S390X:#define __UINT16_MAX__ 65535 // S390X:#define __UINT16_TYPE__ unsigned short +// S390X:#define __UINT32_C(c) c##U // S390X:#define __UINT32_C_SUFFIX__ U // S390X:#define __UINT32_MAX__ 4294967295U // S390X:#define __UINT32_TYPE__ unsigned int +// S390X:#define __UINT64_C(c) c##UL // S390X:#define __UINT64_C_SUFFIX__ UL // S390X:#define __UINT64_MAX__ 18446744073709551615UL // S390X:#define __UINT64_TYPE__ long unsigned int +// S390X:#define __UINT8_C(c) c // S390X:#define __UINT8_C_SUFFIX__ // S390X:#define __UINT8_MAX__ 255 // S390X:#define __UINT8_TYPE__ unsigned char +// S390X:#define __UINTMAX_C(c) c##UL // S390X:#define __UINTMAX_C_SUFFIX__ UL // S390X:#define __UINTMAX_MAX__ 18446744073709551615UL // S390X:#define __UINTMAX_TYPE__ long unsigned int diff --git a/clang/test/Preprocessor/init-v7k-compat.c b/clang/test/Preprocessor/init-v7k-compat.c index ff5d4bbdea53a..a9c6e7a290646 100644 --- a/clang/test/Preprocessor/init-v7k-compat.c +++ b/clang/test/Preprocessor/init-v7k-compat.c @@ -39,26 +39,31 @@ // CHECK: #define __FLT_MIN_EXP__ (-125) // CHECK: #define __FLT_MIN__ 1.17549435e-38F // CHECK: #define __FLT_RADIX__ 2 +// CHECK: #define __INT16_C(c) c // CHECK: #define __INT16_C_SUFFIX__ {{$}} // CHECK: #define __INT16_FMTd__ "hd" // CHECK: #define __INT16_FMTi__ "hi" // CHECK: #define __INT16_MAX__ 32767 // CHECK: #define __INT16_TYPE__ short +// CHECK: #define __INT32_C(c) c // CHECK: #define __INT32_C_SUFFIX__ {{$}} // CHECK: #define __INT32_FMTd__ "d" // CHECK: #define __INT32_FMTi__ "i" // CHECK: #define __INT32_MAX__ 2147483647 // CHECK: #define __INT32_TYPE__ int +// CHECK: #define __INT64_C(c) c##LL // CHECK: #define __INT64_C_SUFFIX__ LL // CHECK: #define __INT64_FMTd__ "lld" // CHECK: #define __INT64_FMTi__ "lli" // CHECK: #define __INT64_MAX__ 9223372036854775807LL // CHECK: #define __INT64_TYPE__ long long int +// CHECK: #define __INT8_C(c) c // CHECK: #define __INT8_C_SUFFIX__ {{$}} // CHECK: #define __INT8_FMTd__ "hhd" // CHECK: #define __INT8_FMTi__ "hhi" // CHECK: #define __INT8_MAX__ 127 // CHECK: #define __INT8_TYPE__ signed char +// CHECK: #define __INTMAX_C(c) c##LL // CHECK: #define __INTMAX_C_SUFFIX__ LL // CHECK: #define __INTMAX_FMTd__ "lld" // CHECK: #define __INTMAX_FMTi__ "lli" @@ -140,18 +145,23 @@ // CHECK: #define __SIZE_MAX__ 4294967295UL // CHECK: #define __SIZE_TYPE__ long unsigned int // CHECK: #define __SIZE_WIDTH__ 32 +// CHECK: #define __UINT16_C(c) c // CHECK: #define __UINT16_C_SUFFIX__ {{$}} // CHECK: #define __UINT16_MAX__ 65535 // CHECK: #define __UINT16_TYPE__ unsigned short +// CHECK: #define __UINT32_C(c) c##U // CHECK: #define __UINT32_C_SUFFIX__ U // CHECK: #define __UINT32_MAX__ 4294967295U // CHECK: #define __UINT32_TYPE__ unsigned int +// CHECK: #define __UINT64_C(c) c##ULL // CHECK: #define __UINT64_C_SUFFIX__ ULL // CHECK: #define __UINT64_MAX__ 18446744073709551615ULL // CHECK: #define __UINT64_TYPE__ long long unsigned int +// CHECK: #define __UINT8_C(c) c // CHECK: #define __UINT8_C_SUFFIX__ {{$}} // CHECK: #define __UINT8_MAX__ 255 // CHECK: #define __UINT8_TYPE__ unsigned char +// CHECK: #define __UINTMAX_C(c) c##ULL // CHECK: #define __UINTMAX_C_SUFFIX__ ULL // CHECK: #define __UINTMAX_MAX__ 18446744073709551615ULL // CHECK: #define __UINTMAX_TYPE__ long long unsigned int diff --git a/clang/test/Preprocessor/init-ve.c b/clang/test/Preprocessor/init-ve.c index 13bdb12387db4..711c2a04865b3 100644 --- a/clang/test/Preprocessor/init-ve.c +++ b/clang/test/Preprocessor/init-ve.c @@ -45,26 +45,31 @@ // VE:#define __FLT_MIN_EXP__ (-125) // VE:#define __FLT_MIN__ 1.17549435e-38F // VE:#define __FLT_RADIX__ 2 +// VE:#define __INT16_C(c) c // VE:#define __INT16_C_SUFFIX__ // VE:#define __INT16_FMTd__ "hd" // VE:#define __INT16_FMTi__ "hi" // VE:#define __INT16_MAX__ 32767 // VE:#define __INT16_TYPE__ short +// VE:#define __INT32_C(c) c // VE:#define __INT32_C_SUFFIX__ // VE:#define __INT32_FMTd__ "d" // VE:#define __INT32_FMTi__ "i" // VE:#define __INT32_MAX__ 2147483647 // VE:#define __INT32_TYPE__ int +// VE:#define __INT64_C(c) c##L // VE:#define __INT64_C_SUFFIX__ L // VE:#define __INT64_FMTd__ "ld" // VE:#define __INT64_FMTi__ "li" // VE:#define __INT64_MAX__ 9223372036854775807L // VE:#define __INT64_TYPE__ long int +// VE:#define __INT8_C(c) c // VE:#define __INT8_C_SUFFIX__ // VE:#define __INT8_FMTd__ "hhd" // VE:#define __INT8_FMTi__ "hhi" // VE:#define __INT8_MAX__ 127 // VE:#define __INT8_TYPE__ signed char +// VE:#define __INTMAX_C(c) c##L // VE:#define __INTMAX_C_SUFFIX__ L // VE:#define __INTMAX_FMTd__ "ld" // VE:#define __INTMAX_FMTi__ "li" @@ -164,6 +169,7 @@ // VE-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL // VE-HOSTED:#define __STDC_HOSTED__ 1 // VE-FREESTANDING:#define __STDC_HOSTED__ 0 +// VE:#define __UINT16_C(c) c // VE:#define __UINT16_C_SUFFIX__ // VE:#define __UINT16_FMTX__ "hX" // VE:#define __UINT16_FMTo__ "ho" @@ -171,6 +177,7 @@ // VE:#define __UINT16_FMTx__ "hx" // VE:#define __UINT16_MAX__ 65535 // VE:#define __UINT16_TYPE__ unsigned short +// VE:#define __UINT32_C(c) c##U // VE:#define __UINT32_C_SUFFIX__ U // VE:#define __UINT32_FMTX__ "X" // VE:#define __UINT32_FMTo__ "o" @@ -178,6 +185,7 @@ // VE:#define __UINT32_FMTx__ "x" // VE:#define __UINT32_MAX__ 4294967295U // VE:#define __UINT32_TYPE__ unsigned int +// VE:#define __UINT64_C(c) c##UL // VE:#define __UINT64_C_SUFFIX__ UL // VE:#define __UINT64_FMTX__ "lX" // VE:#define __UINT64_FMTo__ "lo" @@ -185,6 +193,7 @@ // VE:#define __UINT64_FMTx__ "lx" // VE:#define __UINT64_MAX__ 18446744073709551615UL // VE:#define __UINT64_TYPE__ long unsigned int +// VE:#define __UINT8_C(c) c // VE:#define __UINT8_C_SUFFIX__ // VE:#define __UINT8_FMTX__ "hhX" // VE:#define __UINT8_FMTo__ "hho" @@ -192,6 +201,7 @@ // VE:#define __UINT8_FMTx__ "hhx" // VE:#define __UINT8_MAX__ 255 // VE:#define __UINT8_TYPE__ unsigned char +// VE:#define __UINTMAX_C(c) c##UL // VE:#define __UINTMAX_C_SUFFIX__ UL // VE:#define __UINTMAX_FMTX__ "lX" // VE:#define __UINTMAX_FMTo__ "lo" diff --git a/clang/test/Preprocessor/init-x86.c b/clang/test/Preprocessor/init-x86.c index 6f5aa5674e48e..cb77b5583407c 100644 --- a/clang/test/Preprocessor/init-x86.c +++ b/clang/test/Preprocessor/init-x86.c @@ -35,26 +35,31 @@ // I386:#define __FLT_MIN_EXP__ (-125) // I386:#define __FLT_MIN__ 1.17549435e-38F // I386:#define __FLT_RADIX__ 2 +// I386:#define __INT16_C(c) c // I386:#define __INT16_C_SUFFIX__ // I386:#define __INT16_FMTd__ "hd" // I386:#define __INT16_FMTi__ "hi" // I386:#define __INT16_MAX__ 32767 // I386:#define __INT16_TYPE__ short +// I386:#define __INT32_C(c) c // I386:#define __INT32_C_SUFFIX__ // I386:#define __INT32_FMTd__ "d" // I386:#define __INT32_FMTi__ "i" // I386:#define __INT32_MAX__ 2147483647 // I386:#define __INT32_TYPE__ int +// I386:#define __INT64_C(c) c##LL // I386:#define __INT64_C_SUFFIX__ LL // I386:#define __INT64_FMTd__ "lld" // I386:#define __INT64_FMTi__ "lli" // I386:#define __INT64_MAX__ 9223372036854775807LL // I386:#define __INT64_TYPE__ long long int +// I386:#define __INT8_C(c) c // I386:#define __INT8_C_SUFFIX__ // I386:#define __INT8_FMTd__ "hhd" // I386:#define __INT8_FMTi__ "hhi" // I386:#define __INT8_MAX__ 127 // I386:#define __INT8_TYPE__ signed char +// I386:#define __INTMAX_C(c) c##LL // I386:#define __INTMAX_C_SUFFIX__ LL // I386:#define __INTMAX_FMTd__ "lld" // I386:#define __INTMAX_FMTi__ "lli" @@ -140,18 +145,23 @@ // I386:#define __SIZE_MAX__ 4294967295U // I386:#define __SIZE_TYPE__ unsigned int // I386:#define __SIZE_WIDTH__ 32 +// I386:#define __UINT16_C(c) c // I386:#define __UINT16_C_SUFFIX__ // I386:#define __UINT16_MAX__ 65535 // I386:#define __UINT16_TYPE__ unsigned short +// I386:#define __UINT32_C(c) c##U // I386:#define __UINT32_C_SUFFIX__ U // I386:#define __UINT32_MAX__ 4294967295U // I386:#define __UINT32_TYPE__ unsigned int +// I386:#define __UINT64_C(c) c##ULL // I386:#define __UINT64_C_SUFFIX__ ULL // I386:#define __UINT64_MAX__ 18446744073709551615ULL // I386:#define __UINT64_TYPE__ long long unsigned int +// I386:#define __UINT8_C(c) c // I386:#define __UINT8_C_SUFFIX__ // I386:#define __UINT8_MAX__ 255 // I386:#define __UINT8_TYPE__ unsigned char +// I386:#define __UINTMAX_C(c) c##ULL // I386:#define __UINTMAX_C_SUFFIX__ ULL // I386:#define __UINTMAX_MAX__ 18446744073709551615ULL // I386:#define __UINTMAX_TYPE__ long long unsigned int @@ -235,26 +245,31 @@ // I386-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 // I386-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 // I386-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +// I386-LINUX:#define __INT16_C(c) c // I386-LINUX:#define __INT16_C_SUFFIX__ // I386-LINUX:#define __INT16_FMTd__ "hd" // I386-LINUX:#define __INT16_FMTi__ "hi" // I386-LINUX:#define __INT16_MAX__ 32767 // I386-LINUX:#define __INT16_TYPE__ short +// I386-LINUX:#define __INT32_C(c) c // I386-LINUX:#define __INT32_C_SUFFIX__ // I386-LINUX:#define __INT32_FMTd__ "d" // I386-LINUX:#define __INT32_FMTi__ "i" // I386-LINUX:#define __INT32_MAX__ 2147483647 // I386-LINUX:#define __INT32_TYPE__ int +// I386-LINUX:#define __INT64_C(c) c##LL // I386-LINUX:#define __INT64_C_SUFFIX__ LL // I386-LINUX:#define __INT64_FMTd__ "lld" // I386-LINUX:#define __INT64_FMTi__ "lli" // I386-LINUX:#define __INT64_MAX__ 9223372036854775807LL // I386-LINUX:#define __INT64_TYPE__ long long int +// I386-LINUX:#define __INT8_C(c) c // I386-LINUX:#define __INT8_C_SUFFIX__ // I386-LINUX:#define __INT8_FMTd__ "hhd" // I386-LINUX:#define __INT8_FMTi__ "hhi" // I386-LINUX:#define __INT8_MAX__ 127 // I386-LINUX:#define __INT8_TYPE__ signed char +// I386-LINUX:#define __INTMAX_C(c) c##LL // I386-LINUX:#define __INTMAX_C_SUFFIX__ LL // I386-LINUX:#define __INTMAX_FMTd__ "lld" // I386-LINUX:#define __INTMAX_FMTi__ "lli" @@ -341,18 +356,23 @@ // I386-LINUX:#define __SIZE_TYPE__ unsigned int // I386-LINUX:#define __SIZE_WIDTH__ 32 // I386-LINUX-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// I386-LINUX:#define __UINT16_C(c) c // I386-LINUX:#define __UINT16_C_SUFFIX__ // I386-LINUX:#define __UINT16_MAX__ 65535 // I386-LINUX:#define __UINT16_TYPE__ unsigned short +// I386-LINUX:#define __UINT32_C(c) c##U // I386-LINUX:#define __UINT32_C_SUFFIX__ U // I386-LINUX:#define __UINT32_MAX__ 4294967295U // I386-LINUX:#define __UINT32_TYPE__ unsigned int +// I386-LINUX:#define __UINT64_C(c) c##ULL // I386-LINUX:#define __UINT64_C_SUFFIX__ ULL // I386-LINUX:#define __UINT64_MAX__ 18446744073709551615ULL // I386-LINUX:#define __UINT64_TYPE__ long long unsigned int +// I386-LINUX:#define __UINT8_C(c) c // I386-LINUX:#define __UINT8_C_SUFFIX__ // I386-LINUX:#define __UINT8_MAX__ 255 // I386-LINUX:#define __UINT8_TYPE__ unsigned char +// I386-LINUX:#define __UINTMAX_C(c) c##ULL // I386-LINUX:#define __UINTMAX_C_SUFFIX__ ULL // I386-LINUX:#define __UINTMAX_MAX__ 18446744073709551615ULL // I386-LINUX:#define __UINTMAX_TYPE__ long long unsigned int @@ -436,26 +456,31 @@ // I386-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 // I386-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 // I386-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +// I386-NETBSD:#define __INT16_C(c) c // I386-NETBSD:#define __INT16_C_SUFFIX__ // I386-NETBSD:#define __INT16_FMTd__ "hd" // I386-NETBSD:#define __INT16_FMTi__ "hi" // I386-NETBSD:#define __INT16_MAX__ 32767 // I386-NETBSD:#define __INT16_TYPE__ short +// I386-NETBSD:#define __INT32_C(c) c // I386-NETBSD:#define __INT32_C_SUFFIX__ // I386-NETBSD:#define __INT32_FMTd__ "d" // I386-NETBSD:#define __INT32_FMTi__ "i" // I386-NETBSD:#define __INT32_MAX__ 2147483647 // I386-NETBSD:#define __INT32_TYPE__ int +// I386-NETBSD:#define __INT64_C(c) c##LL // I386-NETBSD:#define __INT64_C_SUFFIX__ LL // I386-NETBSD:#define __INT64_FMTd__ "lld" // I386-NETBSD:#define __INT64_FMTi__ "lli" // I386-NETBSD:#define __INT64_MAX__ 9223372036854775807LL // I386-NETBSD:#define __INT64_TYPE__ long long int +// I386-NETBSD:#define __INT8_C(c) c // I386-NETBSD:#define __INT8_C_SUFFIX__ // I386-NETBSD:#define __INT8_FMTd__ "hhd" // I386-NETBSD:#define __INT8_FMTi__ "hhi" // I386-NETBSD:#define __INT8_MAX__ 127 // I386-NETBSD:#define __INT8_TYPE__ signed char +// I386-NETBSD:#define __INTMAX_C(c) c##LL // I386-NETBSD:#define __INTMAX_C_SUFFIX__ LL // I386-NETBSD:#define __INTMAX_FMTd__ "lld" // I386-NETBSD:#define __INTMAX_FMTi__ "lli" @@ -542,18 +567,23 @@ // I386-NETBSD:#define __SIZE_TYPE__ unsigned int // I386-NETBSD:#define __SIZE_WIDTH__ 32 // I386-NETBSD-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 4U +// I386-NETBSD:#define __UINT16_C(c) c // I386-NETBSD:#define __UINT16_C_SUFFIX__ // I386-NETBSD:#define __UINT16_MAX__ 65535 // I386-NETBSD:#define __UINT16_TYPE__ unsigned short +// I386-NETBSD:#define __UINT32_C(c) c##U // I386-NETBSD:#define __UINT32_C_SUFFIX__ U // I386-NETBSD:#define __UINT32_MAX__ 4294967295U // I386-NETBSD:#define __UINT32_TYPE__ unsigned int +// I386-NETBSD:#define __UINT64_C(c) c##ULL // I386-NETBSD:#define __UINT64_C_SUFFIX__ ULL // I386-NETBSD:#define __UINT64_MAX__ 18446744073709551615ULL // I386-NETBSD:#define __UINT64_TYPE__ long long unsigned int +// I386-NETBSD:#define __UINT8_C(c) c // I386-NETBSD:#define __UINT8_C_SUFFIX__ // I386-NETBSD:#define __UINT8_MAX__ 255 // I386-NETBSD:#define __UINT8_TYPE__ unsigned char +// I386-NETBSD:#define __UINTMAX_C(c) c##ULL // I386-NETBSD:#define __UINTMAX_C_SUFFIX__ ULL // I386-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL // I386-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int @@ -636,26 +666,31 @@ // X86_64:#define __FLT_MIN_EXP__ (-125) // X86_64:#define __FLT_MIN__ 1.17549435e-38F // X86_64:#define __FLT_RADIX__ 2 +// X86_64:#define __INT16_C(c) c // X86_64:#define __INT16_C_SUFFIX__ // X86_64:#define __INT16_FMTd__ "hd" // X86_64:#define __INT16_FMTi__ "hi" // X86_64:#define __INT16_MAX__ 32767 // X86_64:#define __INT16_TYPE__ short +// X86_64:#define __INT32_C(c) c // X86_64:#define __INT32_C_SUFFIX__ // X86_64:#define __INT32_FMTd__ "d" // X86_64:#define __INT32_FMTi__ "i" // X86_64:#define __INT32_MAX__ 2147483647 // X86_64:#define __INT32_TYPE__ int +// X86_64:#define __INT64_C(c) c##L // X86_64:#define __INT64_C_SUFFIX__ L // X86_64:#define __INT64_FMTd__ "ld" // X86_64:#define __INT64_FMTi__ "li" // X86_64:#define __INT64_MAX__ 9223372036854775807L // X86_64:#define __INT64_TYPE__ long int +// X86_64:#define __INT8_C(c) c // X86_64:#define __INT8_C_SUFFIX__ // X86_64:#define __INT8_FMTd__ "hhd" // X86_64:#define __INT8_FMTi__ "hhi" // X86_64:#define __INT8_MAX__ 127 // X86_64:#define __INT8_TYPE__ signed char +// X86_64:#define __INTMAX_C(c) c##L // X86_64:#define __INTMAX_C_SUFFIX__ L // X86_64:#define __INTMAX_FMTd__ "ld" // X86_64:#define __INTMAX_FMTi__ "li" @@ -748,18 +783,23 @@ // X86_64:#define __SSE_MATH__ 1 // X86_64:#define __SSE__ 1 // X86_64-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16UL +// X86_64:#define __UINT16_C(c) c // X86_64:#define __UINT16_C_SUFFIX__ // X86_64:#define __UINT16_MAX__ 65535 // X86_64:#define __UINT16_TYPE__ unsigned short +// X86_64:#define __UINT32_C(c) c##U // X86_64:#define __UINT32_C_SUFFIX__ U // X86_64:#define __UINT32_MAX__ 4294967295U // X86_64:#define __UINT32_TYPE__ unsigned int +// X86_64:#define __UINT64_C(c) c##UL // X86_64:#define __UINT64_C_SUFFIX__ UL // X86_64:#define __UINT64_MAX__ 18446744073709551615UL // X86_64:#define __UINT64_TYPE__ long unsigned int +// X86_64:#define __UINT8_C(c) c // X86_64:#define __UINT8_C_SUFFIX__ // X86_64:#define __UINT8_MAX__ 255 // X86_64:#define __UINT8_TYPE__ unsigned char +// X86_64:#define __UINTMAX_C(c) c##UL // X86_64:#define __UINTMAX_C_SUFFIX__ UL // X86_64:#define __UINTMAX_MAX__ 18446744073709551615UL // X86_64:#define __UINTMAX_TYPE__ long unsigned int @@ -842,26 +882,31 @@ // X32:#define __FLT_RADIX__ 2 // X32:#define __ILP32__ 1 // X32-NOT:#define __LP64__ 1 +// X32:#define __INT16_C(c) c // X32:#define __INT16_C_SUFFIX__ // X32:#define __INT16_FMTd__ "hd" // X32:#define __INT16_FMTi__ "hi" // X32:#define __INT16_MAX__ 32767 // X32:#define __INT16_TYPE__ short +// X32:#define __INT32_C(c) c // X32:#define __INT32_C_SUFFIX__ // X32:#define __INT32_FMTd__ "d" // X32:#define __INT32_FMTi__ "i" // X32:#define __INT32_MAX__ 2147483647 // X32:#define __INT32_TYPE__ int +// X32:#define __INT64_C(c) c##LL // X32:#define __INT64_C_SUFFIX__ LL // X32:#define __INT64_FMTd__ "lld" // X32:#define __INT64_FMTi__ "lli" // X32:#define __INT64_MAX__ 9223372036854775807LL // X32:#define __INT64_TYPE__ long long int +// X32:#define __INT8_C(c) c // X32:#define __INT8_C_SUFFIX__ // X32:#define __INT8_FMTd__ "hhd" // X32:#define __INT8_FMTi__ "hhi" // X32:#define __INT8_MAX__ 127 // X32:#define __INT8_TYPE__ signed char +// X32:#define __INTMAX_C(c) c##LL // X32:#define __INTMAX_C_SUFFIX__ LL // X32:#define __INTMAX_FMTd__ "lld" // X32:#define __INTMAX_FMTi__ "lli" @@ -952,18 +997,23 @@ // X32:#define __SSE_MATH__ 1 // X32:#define __SSE__ 1 // X32-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16U +// X32:#define __UINT16_C(c) c // X32:#define __UINT16_C_SUFFIX__ // X32:#define __UINT16_MAX__ 65535 // X32:#define __UINT16_TYPE__ unsigned short +// X32:#define __UINT32_C(c) c##U // X32:#define __UINT32_C_SUFFIX__ U // X32:#define __UINT32_MAX__ 4294967295U // X32:#define __UINT32_TYPE__ unsigned int +// X32:#define __UINT64_C(c) c##ULL // X32:#define __UINT64_C_SUFFIX__ ULL // X32:#define __UINT64_MAX__ 18446744073709551615ULL // X32:#define __UINT64_TYPE__ long long unsigned int +// X32:#define __UINT8_C(c) c // X32:#define __UINT8_C_SUFFIX__ // X32:#define __UINT8_MAX__ 255 // X32:#define __UINT8_TYPE__ unsigned char +// X32:#define __UINTMAX_C(c) c##ULL // X32:#define __UINTMAX_C_SUFFIX__ ULL // X32:#define __UINTMAX_MAX__ 18446744073709551615ULL // X32:#define __UINTMAX_TYPE__ long long unsigned int @@ -1046,26 +1096,31 @@ // X86_64-LINUX:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 // X86_64-LINUX:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 // X86_64-LINUX:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +// X86_64-LINUX:#define __INT16_C(c) c // X86_64-LINUX:#define __INT16_C_SUFFIX__ // X86_64-LINUX:#define __INT16_FMTd__ "hd" // X86_64-LINUX:#define __INT16_FMTi__ "hi" // X86_64-LINUX:#define __INT16_MAX__ 32767 // X86_64-LINUX:#define __INT16_TYPE__ short +// X86_64-LINUX:#define __INT32_C(c) c // X86_64-LINUX:#define __INT32_C_SUFFIX__ // X86_64-LINUX:#define __INT32_FMTd__ "d" // X86_64-LINUX:#define __INT32_FMTi__ "i" // X86_64-LINUX:#define __INT32_MAX__ 2147483647 // X86_64-LINUX:#define __INT32_TYPE__ int +// X86_64-LINUX:#define __INT64_C(c) c##L // X86_64-LINUX:#define __INT64_C_SUFFIX__ L // X86_64-LINUX:#define __INT64_FMTd__ "ld" // X86_64-LINUX:#define __INT64_FMTi__ "li" // X86_64-LINUX:#define __INT64_MAX__ 9223372036854775807L // X86_64-LINUX:#define __INT64_TYPE__ long int +// X86_64-LINUX:#define __INT8_C(c) c // X86_64-LINUX:#define __INT8_C_SUFFIX__ // X86_64-LINUX:#define __INT8_FMTd__ "hhd" // X86_64-LINUX:#define __INT8_FMTi__ "hhi" // X86_64-LINUX:#define __INT8_MAX__ 127 // X86_64-LINUX:#define __INT8_TYPE__ signed char +// X86_64-LINUX:#define __INTMAX_C(c) c##L // X86_64-LINUX:#define __INTMAX_C_SUFFIX__ L // X86_64-LINUX:#define __INTMAX_FMTd__ "ld" // X86_64-LINUX:#define __INTMAX_FMTi__ "li" @@ -1156,18 +1211,23 @@ // X86_64-LINUX:#define __SSE2__ 1 // X86_64-LINUX:#define __SSE_MATH__ 1 // X86_64-LINUX:#define __SSE__ 1 +// X86_64-LINUX:#define __UINT16_C(c) c // X86_64-LINUX:#define __UINT16_C_SUFFIX__ // X86_64-LINUX:#define __UINT16_MAX__ 65535 // X86_64-LINUX:#define __UINT16_TYPE__ unsigned short +// X86_64-LINUX:#define __UINT32_C(c) c##U // X86_64-LINUX:#define __UINT32_C_SUFFIX__ U // X86_64-LINUX:#define __UINT32_MAX__ 4294967295U // X86_64-LINUX:#define __UINT32_TYPE__ unsigned int +// X86_64-LINUX:#define __UINT64_C(c) c##UL // X86_64-LINUX:#define __UINT64_C_SUFFIX__ UL // X86_64-LINUX:#define __UINT64_MAX__ 18446744073709551615UL // X86_64-LINUX:#define __UINT64_TYPE__ long unsigned int +// X86_64-LINUX:#define __UINT8_C(c) c // X86_64-LINUX:#define __UINT8_C_SUFFIX__ // X86_64-LINUX:#define __UINT8_MAX__ 255 // X86_64-LINUX:#define __UINT8_TYPE__ unsigned char +// X86_64-LINUX:#define __UINTMAX_C(c) c##UL // X86_64-LINUX:#define __UINTMAX_C_SUFFIX__ UL // X86_64-LINUX:#define __UINTMAX_MAX__ 18446744073709551615UL // X86_64-LINUX:#define __UINTMAX_TYPE__ long unsigned int @@ -1258,26 +1318,31 @@ // X86_64-NETBSD:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2 // X86_64-NETBSD:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 // X86_64-NETBSD:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2 +// X86_64-NETBSD:#define __INT16_C(c) c // X86_64-NETBSD:#define __INT16_C_SUFFIX__ // X86_64-NETBSD:#define __INT16_FMTd__ "hd" // X86_64-NETBSD:#define __INT16_FMTi__ "hi" // X86_64-NETBSD:#define __INT16_MAX__ 32767 // X86_64-NETBSD:#define __INT16_TYPE__ short +// X86_64-NETBSD:#define __INT32_C(c) c // X86_64-NETBSD:#define __INT32_C_SUFFIX__ // X86_64-NETBSD:#define __INT32_FMTd__ "d" // X86_64-NETBSD:#define __INT32_FMTi__ "i" // X86_64-NETBSD:#define __INT32_MAX__ 2147483647 // X86_64-NETBSD:#define __INT32_TYPE__ int +// X86_64-NETBSD:#define __INT64_C(c) c##L // X86_64-NETBSD:#define __INT64_C_SUFFIX__ L // X86_64-NETBSD:#define __INT64_FMTd__ "ld" // X86_64-NETBSD:#define __INT64_FMTi__ "li" // X86_64-NETBSD:#define __INT64_MAX__ 9223372036854775807L // X86_64-NETBSD:#define __INT64_TYPE__ long int +// X86_64-NETBSD:#define __INT8_C(c) c // X86_64-NETBSD:#define __INT8_C_SUFFIX__ // X86_64-NETBSD:#define __INT8_FMTd__ "hhd" // X86_64-NETBSD:#define __INT8_FMTi__ "hhi" // X86_64-NETBSD:#define __INT8_MAX__ 127 // X86_64-NETBSD:#define __INT8_TYPE__ signed char +// X86_64-NETBSD:#define __INTMAX_C(c) c##L // X86_64-NETBSD:#define __INTMAX_C_SUFFIX__ L // X86_64-NETBSD:#define __INTMAX_FMTd__ "ld" // X86_64-NETBSD:#define __INTMAX_FMTi__ "li" @@ -1368,18 +1433,23 @@ // X86_64-NETBSD:#define __SSE2__ 1 // X86_64-NETBSD:#define __SSE_MATH__ 1 // X86_64-NETBSD:#define __SSE__ 1 +// X86_64-NETBSD:#define __UINT16_C(c) c // X86_64-NETBSD:#define __UINT16_C_SUFFIX__ // X86_64-NETBSD:#define __UINT16_MAX__ 65535 // X86_64-NETBSD:#define __UINT16_TYPE__ unsigned short +// X86_64-NETBSD:#define __UINT32_C(c) c##U // X86_64-NETBSD:#define __UINT32_C_SUFFIX__ U // X86_64-NETBSD:#define __UINT32_MAX__ 4294967295U // X86_64-NETBSD:#define __UINT32_TYPE__ unsigned int +// X86_64-NETBSD:#define __UINT64_C(c) c##UL // X86_64-NETBSD:#define __UINT64_C_SUFFIX__ UL // X86_64-NETBSD:#define __UINT64_MAX__ 18446744073709551615UL // X86_64-NETBSD:#define __UINT64_TYPE__ long unsigned int +// X86_64-NETBSD:#define __UINT8_C(c) c // X86_64-NETBSD:#define __UINT8_C_SUFFIX__ // X86_64-NETBSD:#define __UINT8_MAX__ 255 // X86_64-NETBSD:#define __UINT8_TYPE__ unsigned char +// X86_64-NETBSD:#define __UINTMAX_C(c) c##UL // X86_64-NETBSD:#define __UINTMAX_C_SUFFIX__ UL // X86_64-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615UL // X86_64-NETBSD:#define __UINTMAX_TYPE__ long unsigned int diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c index 5999b9c1d1bc3..1ac325d444662 100644 --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -426,26 +426,31 @@ // MSP430:#define __FLT_MIN_EXP__ (-125) // MSP430:#define __FLT_MIN__ 1.17549435e-38F // MSP430:#define __FLT_RADIX__ 2 +// MSP430:#define __INT16_C(c) c // MSP430:#define __INT16_C_SUFFIX__ // MSP430:#define __INT16_FMTd__ "hd" // MSP430:#define __INT16_FMTi__ "hi" // MSP430:#define __INT16_MAX__ 32767 // MSP430:#define __INT16_TYPE__ short +// MSP430:#define __INT32_C(c) c##L // MSP430:#define __INT32_C_SUFFIX__ L // MSP430:#define __INT32_FMTd__ "ld" // MSP430:#define __INT32_FMTi__ "li" // MSP430:#define __INT32_MAX__ 2147483647L // MSP430:#define __INT32_TYPE__ long int +// MSP430:#define __INT64_C(c) c##LL // MSP430:#define __INT64_C_SUFFIX__ LL // MSP430:#define __INT64_FMTd__ "lld" // MSP430:#define __INT64_FMTi__ "lli" // MSP430:#define __INT64_MAX__ 9223372036854775807LL // MSP430:#define __INT64_TYPE__ long long int +// MSP430:#define __INT8_C(c) c // MSP430:#define __INT8_C_SUFFIX__ // MSP430:#define __INT8_FMTd__ "hhd" // MSP430:#define __INT8_FMTi__ "hhi" // MSP430:#define __INT8_MAX__ 127 // MSP430:#define __INT8_TYPE__ signed char +// MSP430:#define __INTMAX_C(c) c##LL // MSP430:#define __INTMAX_C_SUFFIX__ LL // MSP430:#define __INTMAX_FMTd__ "lld" // MSP430:#define __INTMAX_FMTi__ "lli" @@ -531,18 +536,23 @@ // MSP430:#define __SIZE_TYPE__ unsigned int // MSP430:#define __SIZE_WIDTH__ 16 // MSP430-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 2U +// MSP430:#define __UINT16_C(c) c##U // MSP430:#define __UINT16_C_SUFFIX__ U // MSP430:#define __UINT16_MAX__ 65535U // MSP430:#define __UINT16_TYPE__ unsigned short +// MSP430:#define __UINT32_C(c) c##UL // MSP430:#define __UINT32_C_SUFFIX__ UL // MSP430:#define __UINT32_MAX__ 4294967295UL // MSP430:#define __UINT32_TYPE__ long unsigned int +// MSP430:#define __UINT64_C(c) c##ULL // MSP430:#define __UINT64_C_SUFFIX__ ULL // MSP430:#define __UINT64_MAX__ 18446744073709551615ULL // MSP430:#define __UINT64_TYPE__ long long unsigned int +// MSP430:#define __UINT8_C(c) c // MSP430:#define __UINT8_C_SUFFIX__ // MSP430:#define __UINT8_MAX__ 255 // MSP430:#define __UINT8_TYPE__ unsigned char +// MSP430:#define __UINTMAX_C(c) c##ULL // MSP430:#define __UINTMAX_C_SUFFIX__ ULL // MSP430:#define __UINTMAX_MAX__ 18446744073709551615ULL // MSP430:#define __UINTMAX_TYPE__ long long unsigned int @@ -613,26 +623,31 @@ // NVPTX32:#define __FLT_MIN_EXP__ (-125) // NVPTX32:#define __FLT_MIN__ 1.17549435e-38F // NVPTX32:#define __FLT_RADIX__ 2 +// NVPTX32:#define __INT16_C(c) c // NVPTX32:#define __INT16_C_SUFFIX__ // NVPTX32:#define __INT16_FMTd__ "hd" // NVPTX32:#define __INT16_FMTi__ "hi" // NVPTX32:#define __INT16_MAX__ 32767 // NVPTX32:#define __INT16_TYPE__ short +// NVPTX32:#define __INT32_C(c) c // NVPTX32:#define __INT32_C_SUFFIX__ // NVPTX32:#define __INT32_FMTd__ "d" // NVPTX32:#define __INT32_FMTi__ "i" // NVPTX32:#define __INT32_MAX__ 2147483647 // NVPTX32:#define __INT32_TYPE__ int +// NVPTX32:#define __INT64_C(c) c##LL // NVPTX32:#define __INT64_C_SUFFIX__ LL // NVPTX32:#define __INT64_FMTd__ "lld" // NVPTX32:#define __INT64_FMTi__ "lli" // NVPTX32:#define __INT64_MAX__ 9223372036854775807LL // NVPTX32:#define __INT64_TYPE__ long long int +// NVPTX32:#define __INT8_C(c) c // NVPTX32:#define __INT8_C_SUFFIX__ // NVPTX32:#define __INT8_FMTd__ "hhd" // NVPTX32:#define __INT8_FMTi__ "hhi" // NVPTX32:#define __INT8_MAX__ 127 // NVPTX32:#define __INT8_TYPE__ signed char +// NVPTX32:#define __INTMAX_C(c) c##LL // NVPTX32:#define __INTMAX_C_SUFFIX__ LL // NVPTX32:#define __INTMAX_FMTd__ "lld" // NVPTX32:#define __INTMAX_FMTi__ "lli" @@ -720,18 +735,23 @@ // NVPTX32:#define __SIZE_TYPE__ unsigned int // NVPTX32:#define __SIZE_WIDTH__ 32 // NVPTX32-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// NVPTX32:#define __UINT16_C(c) c // NVPTX32:#define __UINT16_C_SUFFIX__ // NVPTX32:#define __UINT16_MAX__ 65535 // NVPTX32:#define __UINT16_TYPE__ unsigned short +// NVPTX32:#define __UINT32_C(c) c##U // NVPTX32:#define __UINT32_C_SUFFIX__ U // NVPTX32:#define __UINT32_MAX__ 4294967295U // NVPTX32:#define __UINT32_TYPE__ unsigned int +// NVPTX32:#define __UINT64_C(c) c##ULL // NVPTX32:#define __UINT64_C_SUFFIX__ ULL // NVPTX32:#define __UINT64_MAX__ 18446744073709551615ULL // NVPTX32:#define __UINT64_TYPE__ long long unsigned int +// NVPTX32:#define __UINT8_C(c) c // NVPTX32:#define __UINT8_C_SUFFIX__ // NVPTX32:#define __UINT8_MAX__ 255 // NVPTX32:#define __UINT8_TYPE__ unsigned char +// NVPTX32:#define __UINTMAX_C(c) c##ULL // NVPTX32:#define __UINTMAX_C_SUFFIX__ ULL // NVPTX32:#define __UINTMAX_MAX__ 18446744073709551615ULL // NVPTX32:#define __UINTMAX_TYPE__ long long unsigned int @@ -801,26 +821,31 @@ // NVPTX64:#define __FLT_MIN_EXP__ (-125) // NVPTX64:#define __FLT_MIN__ 1.17549435e-38F // NVPTX64:#define __FLT_RADIX__ 2 +// NVPTX64:#define __INT16_C(c) c // NVPTX64:#define __INT16_C_SUFFIX__ // NVPTX64:#define __INT16_FMTd__ "hd" // NVPTX64:#define __INT16_FMTi__ "hi" // NVPTX64:#define __INT16_MAX__ 32767 // NVPTX64:#define __INT16_TYPE__ short +// NVPTX64:#define __INT32_C(c) c // NVPTX64:#define __INT32_C_SUFFIX__ // NVPTX64:#define __INT32_FMTd__ "d" // NVPTX64:#define __INT32_FMTi__ "i" // NVPTX64:#define __INT32_MAX__ 2147483647 // NVPTX64:#define __INT32_TYPE__ int +// NVPTX64:#define __INT64_C(c) c##LL // NVPTX64:#define __INT64_C_SUFFIX__ LL // NVPTX64:#define __INT64_FMTd__ "lld" // NVPTX64:#define __INT64_FMTi__ "lli" // NVPTX64:#define __INT64_MAX__ 9223372036854775807LL // NVPTX64:#define __INT64_TYPE__ long long int +// NVPTX64:#define __INT8_C(c) c // NVPTX64:#define __INT8_C_SUFFIX__ // NVPTX64:#define __INT8_FMTd__ "hhd" // NVPTX64:#define __INT8_FMTi__ "hhi" // NVPTX64:#define __INT8_MAX__ 127 // NVPTX64:#define __INT8_TYPE__ signed char +// NVPTX64:#define __INTMAX_C(c) c##LL // NVPTX64:#define __INTMAX_C_SUFFIX__ LL // NVPTX64:#define __INTMAX_FMTd__ "lld" // NVPTX64:#define __INTMAX_FMTi__ "lli" @@ -908,18 +933,23 @@ // NVPTX64:#define __SIZE_TYPE__ long unsigned int // NVPTX64:#define __SIZE_WIDTH__ 64 // NVPTX64-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8UL +// NVPTX64:#define __UINT16_C(c) c // NVPTX64:#define __UINT16_C_SUFFIX__ // NVPTX64:#define __UINT16_MAX__ 65535 // NVPTX64:#define __UINT16_TYPE__ unsigned short +// NVPTX64:#define __UINT32_C(c) c##U // NVPTX64:#define __UINT32_C_SUFFIX__ U // NVPTX64:#define __UINT32_MAX__ 4294967295U // NVPTX64:#define __UINT32_TYPE__ unsigned int +// NVPTX64:#define __UINT64_C(c) c##ULL // NVPTX64:#define __UINT64_C_SUFFIX__ ULL // NVPTX64:#define __UINT64_MAX__ 18446744073709551615ULL // NVPTX64:#define __UINT64_TYPE__ long long unsigned int +// NVPTX64:#define __UINT8_C(c) c // NVPTX64:#define __UINT8_C_SUFFIX__ // NVPTX64:#define __UINT8_MAX__ 255 // NVPTX64:#define __UINT8_TYPE__ unsigned char +// NVPTX64:#define __UINTMAX_C(c) c##ULL // NVPTX64:#define __UINTMAX_C_SUFFIX__ ULL // NVPTX64:#define __UINTMAX_MAX__ 18446744073709551615ULL // NVPTX64:#define __UINTMAX_TYPE__ long long unsigned int @@ -1003,26 +1033,31 @@ // SPARC:#define __FLT_MIN__ 1.17549435e-38F // SPARC:#define __FLT_RADIX__ 2 // SPARC:#define __GCC_ATOMIC_LLONG_LOCK_FREE 1 +// SPARC:#define __INT16_C(c) c // SPARC:#define __INT16_C_SUFFIX__ // SPARC:#define __INT16_FMTd__ "hd" // SPARC:#define __INT16_FMTi__ "hi" // SPARC:#define __INT16_MAX__ 32767 // SPARC:#define __INT16_TYPE__ short +// SPARC:#define __INT32_C(c) c // SPARC:#define __INT32_C_SUFFIX__ // SPARC:#define __INT32_FMTd__ "d" // SPARC:#define __INT32_FMTi__ "i" // SPARC:#define __INT32_MAX__ 2147483647 // SPARC:#define __INT32_TYPE__ int +// SPARC:#define __INT64_C(c) c##LL // SPARC:#define __INT64_C_SUFFIX__ LL // SPARC:#define __INT64_FMTd__ "lld" // SPARC:#define __INT64_FMTi__ "lli" // SPARC:#define __INT64_MAX__ 9223372036854775807LL // SPARC:#define __INT64_TYPE__ long long int +// SPARC:#define __INT8_C(c) c // SPARC:#define __INT8_C_SUFFIX__ // SPARC:#define __INT8_FMTd__ "hhd" // SPARC:#define __INT8_FMTi__ "hhi" // SPARC:#define __INT8_MAX__ 127 // SPARC:#define __INT8_TYPE__ signed char +// SPARC:#define __INTMAX_C(c) c##LL // SPARC:#define __INTMAX_C_SUFFIX__ LL // SPARC:#define __INTMAX_FMTd__ "lld" // SPARC:#define __INTMAX_FMTi__ "lli" @@ -1114,18 +1149,23 @@ // SPARC-NETOPENBSD:#define __SIZE_TYPE__ long unsigned int // SPARC:#define __SIZE_WIDTH__ 32 // SPARC-DEFAULT-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 8U +// SPARC:#define __UINT16_C(c) c // SPARC:#define __UINT16_C_SUFFIX__ // SPARC:#define __UINT16_MAX__ 65535 // SPARC:#define __UINT16_TYPE__ unsigned short +// SPARC:#define __UINT32_C(c) c##U // SPARC:#define __UINT32_C_SUFFIX__ U // SPARC:#define __UINT32_MAX__ 4294967295U // SPARC:#define __UINT32_TYPE__ unsigned int +// SPARC:#define __UINT64_C(c) c##ULL // SPARC:#define __UINT64_C_SUFFIX__ ULL // SPARC:#define __UINT64_MAX__ 18446744073709551615ULL // SPARC:#define __UINT64_TYPE__ long long unsigned int +// SPARC:#define __UINT8_C(c) c // SPARC:#define __UINT8_C_SUFFIX__ // SPARC:#define __UINT8_MAX__ 255 // SPARC:#define __UINT8_TYPE__ unsigned char +// SPARC:#define __UINTMAX_C(c) c##ULL // SPARC:#define __UINTMAX_C_SUFFIX__ ULL // SPARC:#define __UINTMAX_MAX__ 18446744073709551615ULL // SPARC:#define __UINTMAX_TYPE__ long long unsigned int @@ -1201,21 +1241,25 @@ // TCE:#define __FLT_MIN_EXP__ (-125) // TCE:#define __FLT_MIN__ 1.17549435e-38F // TCE:#define __FLT_RADIX__ 2 +// TCE:#define __INT16_C(c) c // TCE:#define __INT16_C_SUFFIX__ // TCE:#define __INT16_FMTd__ "hd" // TCE:#define __INT16_FMTi__ "hi" // TCE:#define __INT16_MAX__ 32767 // TCE:#define __INT16_TYPE__ short +// TCE:#define __INT32_C(c) c // TCE:#define __INT32_C_SUFFIX__ // TCE:#define __INT32_FMTd__ "d" // TCE:#define __INT32_FMTi__ "i" // TCE:#define __INT32_MAX__ 2147483647 // TCE:#define __INT32_TYPE__ int +// TCE:#define __INT8_C(c) c // TCE:#define __INT8_C_SUFFIX__ // TCE:#define __INT8_FMTd__ "hhd" // TCE:#define __INT8_FMTi__ "hhi" // TCE:#define __INT8_MAX__ 127 // TCE:#define __INT8_TYPE__ signed char +// TCE:#define __INTMAX_C(c) c##L // TCE:#define __INTMAX_C_SUFFIX__ L // TCE:#define __INTMAX_FMTd__ "ld" // TCE:#define __INTMAX_FMTi__ "li" @@ -1293,15 +1337,19 @@ // TCE-CXX:#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 4U // TCE:#define __TCE_V1__ 1 // TCE:#define __TCE__ 1 +// TCE:#define __UINT16_C(c) c // TCE:#define __UINT16_C_SUFFIX__ // TCE:#define __UINT16_MAX__ 65535 // TCE:#define __UINT16_TYPE__ unsigned short +// TCE:#define __UINT32_C(c) c##U // TCE:#define __UINT32_C_SUFFIX__ U // TCE:#define __UINT32_MAX__ 4294967295U // TCE:#define __UINT32_TYPE__ unsigned int +// TCE:#define __UINT8_C(c) c // TCE:#define __UINT8_C_SUFFIX__ // TCE:#define __UINT8_MAX__ 255 // TCE:#define __UINT8_TYPE__ unsigned char +// TCE:#define __UINTMAX_C(c) c##UL // TCE:#define __UINTMAX_C_SUFFIX__ UL // TCE:#define __UINTMAX_MAX__ 4294967295UL // TCE:#define __UINTMAX_TYPE__ long unsigned int @@ -1373,6 +1421,7 @@ // PS4:#define __FreeBSD_cc_version 900001 // PS4:#define __INT16_TYPE__ short // PS4:#define __INT32_TYPE__ int +// PS4:#define __INT64_C(c) c##L // PS4:#define __INT64_C_SUFFIX__ L // PS4:#define __INT64_TYPE__ long int // PS4:#define __INT8_TYPE__ signed char @@ -1464,6 +1513,7 @@ // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc64-none-none < /dev/null | FileCheck -match-full-lines -check-prefix SPARCV9 %s // SPARCV9:#define __BIGGEST_ALIGNMENT__ 16 // SPARCV9:#define __INT64_TYPE__ long int +// SPARCV9:#define __INTMAX_C(c) c##L // SPARCV9:#define __INTMAX_C_SUFFIX__ L // SPARCV9:#define __INTMAX_TYPE__ long int // SPARCV9:#define __INTPTR_TYPE__ long int @@ -1475,8 +1525,10 @@ // // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc64-none-openbsd < /dev/null | FileCheck -match-full-lines -check-prefix SPARC64-OBSD %s // SPARC64-OBSD:#define __INT64_TYPE__ long long int +// SPARC64-OBSD:#define __INTMAX_C(c) c##LL // SPARC64-OBSD:#define __INTMAX_C_SUFFIX__ LL // SPARC64-OBSD:#define __INTMAX_TYPE__ long long int +// SPARC64-OBSD:#define __UINTMAX_C(c) c##ULL // SPARC64-OBSD:#define __UINTMAX_C_SUFFIX__ ULL // SPARC64-OBSD:#define __UINTMAX_TYPE__ long long unsigned int // @@ -1720,26 +1772,31 @@ // WEBASSEMBLY-NEXT:#define __GXX_ABI_VERSION 1002 // WEBASSEMBLY32-NEXT:#define __ILP32__ 1 // WEBASSEMBLY64-NOT:#define __ILP32__ +// WEBASSEMBLY-NEXT:#define __INT16_C(c) c // WEBASSEMBLY-NEXT:#define __INT16_C_SUFFIX__ // WEBASSEMBLY-NEXT:#define __INT16_FMTd__ "hd" // WEBASSEMBLY-NEXT:#define __INT16_FMTi__ "hi" // WEBASSEMBLY-NEXT:#define __INT16_MAX__ 32767 // WEBASSEMBLY-NEXT:#define __INT16_TYPE__ short +// WEBASSEMBLY-NEXT:#define __INT32_C(c) c // WEBASSEMBLY-NEXT:#define __INT32_C_SUFFIX__ // WEBASSEMBLY-NEXT:#define __INT32_FMTd__ "d" // WEBASSEMBLY-NEXT:#define __INT32_FMTi__ "i" // WEBASSEMBLY-NEXT:#define __INT32_MAX__ 2147483647 // WEBASSEMBLY-NEXT:#define __INT32_TYPE__ int +// WEBASSEMBLY-NEXT:#define __INT64_C(c) c##LL // WEBASSEMBLY-NEXT:#define __INT64_C_SUFFIX__ LL // WEBASSEMBLY-NEXT:#define __INT64_FMTd__ "lld" // WEBASSEMBLY-NEXT:#define __INT64_FMTi__ "lli" // WEBASSEMBLY-NEXT:#define __INT64_MAX__ 9223372036854775807LL // WEBASSEMBLY-NEXT:#define __INT64_TYPE__ long long int +// WEBASSEMBLY-NEXT:#define __INT8_C(c) c // WEBASSEMBLY-NEXT:#define __INT8_C_SUFFIX__ // WEBASSEMBLY-NEXT:#define __INT8_FMTd__ "hhd" // WEBASSEMBLY-NEXT:#define __INT8_FMTi__ "hhi" // WEBASSEMBLY-NEXT:#define __INT8_MAX__ 127 // WEBASSEMBLY-NEXT:#define __INT8_TYPE__ signed char +// WEBASSEMBLY-NEXT:#define __INTMAX_C(c) c##LL // WEBASSEMBLY-NEXT:#define __INTMAX_C_SUFFIX__ LL // WEBASSEMBLY-NEXT:#define __INTMAX_FMTd__ "lld" // WEBASSEMBLY-NEXT:#define __INTMAX_FMTi__ "lli" @@ -1892,6 +1949,7 @@ // WEBASSEMBLY-NEXT:#define __STDC_UTF_32__ 1 // WEBASSEMBLY-NEXT:#define __STDC_VERSION__ 201710L // WEBASSEMBLY-NEXT:#define __STDC__ 1 +// WEBASSEMBLY-NEXT:#define __UINT16_C(c) c // WEBASSEMBLY-NEXT:#define __UINT16_C_SUFFIX__ // WEBASSEMBLY-NEXT:#define __UINT16_FMTX__ "hX" // WEBASSEMBLY-NEXT:#define __UINT16_FMTo__ "ho" @@ -1899,6 +1957,7 @@ // WEBASSEMBLY-NEXT:#define __UINT16_FMTx__ "hx" // WEBASSEMBLY-NEXT:#define __UINT16_MAX__ 65535 // WEBASSEMBLY-NEXT:#define __UINT16_TYPE__ unsigned short +// WEBASSEMBLY-NEXT:#define __UINT32_C(c) c##U // WEBASSEMBLY-NEXT:#define __UINT32_C_SUFFIX__ U // WEBASSEMBLY-NEXT:#define __UINT32_FMTX__ "X" // WEBASSEMBLY-NEXT:#define __UINT32_FMTo__ "o" @@ -1906,6 +1965,7 @@ // WEBASSEMBLY-NEXT:#define __UINT32_FMTx__ "x" // WEBASSEMBLY-NEXT:#define __UINT32_MAX__ 4294967295U // WEBASSEMBLY-NEXT:#define __UINT32_TYPE__ unsigned int +// WEBASSEMBLY-NEXT:#define __UINT64_C(c) c##ULL // WEBASSEMBLY-NEXT:#define __UINT64_C_SUFFIX__ ULL // WEBASSEMBLY-NEXT:#define __UINT64_FMTX__ "llX" // WEBASSEMBLY-NEXT:#define __UINT64_FMTo__ "llo" @@ -1913,6 +1973,7 @@ // WEBASSEMBLY-NEXT:#define __UINT64_FMTx__ "llx" // WEBASSEMBLY-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL // WEBASSEMBLY-NEXT:#define __UINT64_TYPE__ long long unsigned int +// WEBASSEMBLY-NEXT:#define __UINT8_C(c) c // WEBASSEMBLY-NEXT:#define __UINT8_C_SUFFIX__ // WEBASSEMBLY-NEXT:#define __UINT8_FMTX__ "hhX" // WEBASSEMBLY-NEXT:#define __UINT8_FMTo__ "hho" @@ -1920,6 +1981,7 @@ // WEBASSEMBLY-NEXT:#define __UINT8_FMTx__ "hhx" // WEBASSEMBLY-NEXT:#define __UINT8_MAX__ 255 // WEBASSEMBLY-NEXT:#define __UINT8_TYPE__ unsigned char +// WEBASSEMBLY-NEXT:#define __UINTMAX_C(c) c##ULL // WEBASSEMBLY-NEXT:#define __UINTMAX_C_SUFFIX__ ULL // WEBASSEMBLY-NEXT:#define __UINTMAX_FMTX__ "llX" // WEBASSEMBLY-NEXT:#define __UINTMAX_FMTo__ "llo" @@ -2092,18 +2154,23 @@ // AVR:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1 // AVR:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 1 // AVR:#define __GXX_ABI_VERSION 1002 +// AVR:#define __INT16_C(c) c // AVR:#define __INT16_C_SUFFIX__ // AVR:#define __INT16_MAX__ 32767 // AVR:#define __INT16_TYPE__ int +// AVR:#define __INT32_C(c) c##L // AVR:#define __INT32_C_SUFFIX__ L // AVR:#define __INT32_MAX__ 2147483647L // AVR:#define __INT32_TYPE__ long int +// AVR:#define __INT64_C(c) c##LL // AVR:#define __INT64_C_SUFFIX__ LL // AVR:#define __INT64_MAX__ 9223372036854775807LL // AVR:#define __INT64_TYPE__ long long int +// AVR:#define __INT8_C(c) c // AVR:#define __INT8_C_SUFFIX__ // AVR:#define __INT8_MAX__ 127 // AVR:#define __INT8_TYPE__ signed char +// AVR:#define __INTMAX_C(c) c##LL // AVR:#define __INTMAX_C_SUFFIX__ LL // AVR:#define __INTMAX_MAX__ 9223372036854775807LL // AVR:#define __INTMAX_TYPE__ long long int @@ -2175,15 +2242,19 @@ // AVR:#define __STDC__ 1 // AVR:#define __UINT16_MAX__ 65535U // AVR:#define __UINT16_TYPE__ unsigned int +// AVR:#define __UINT32_C(c) c##UL // AVR:#define __UINT32_C_SUFFIX__ UL // AVR:#define __UINT32_MAX__ 4294967295UL // AVR:#define __UINT32_TYPE__ long unsigned int +// AVR:#define __UINT64_C(c) c##ULL // AVR:#define __UINT64_C_SUFFIX__ ULL // AVR:#define __UINT64_MAX__ 18446744073709551615ULL // AVR:#define __UINT64_TYPE__ long long unsigned int +// AVR:#define __UINT8_C(c) c // AVR:#define __UINT8_C_SUFFIX__ // AVR:#define __UINT8_MAX__ 255 // AVR:#define __UINT8_TYPE__ unsigned char +// AVR:#define __UINTMAX_C(c) c##ULL // AVR:#define __UINTMAX_C_SUFFIX__ ULL // AVR:#define __UINTMAX_MAX__ 18446744073709551615ULL // AVR:#define __UINTMAX_TYPE__ long long unsigned int @@ -2383,18 +2454,23 @@ // RISCV32: #define __GNUC__ {{.*}} // RISCV32: #define __GXX_ABI_VERSION {{.*}} // RISCV32: #define __ILP32__ 1 +// RISCV32: #define __INT16_C(c) c // RISCV32: #define __INT16_C_SUFFIX__ // RISCV32: #define __INT16_MAX__ 32767 // RISCV32: #define __INT16_TYPE__ short +// RISCV32: #define __INT32_C(c) c // RISCV32: #define __INT32_C_SUFFIX__ // RISCV32: #define __INT32_MAX__ 2147483647 // RISCV32: #define __INT32_TYPE__ int +// RISCV32: #define __INT64_C(c) c##LL // RISCV32: #define __INT64_C_SUFFIX__ LL // RISCV32: #define __INT64_MAX__ 9223372036854775807LL // RISCV32: #define __INT64_TYPE__ long long int +// RISCV32: #define __INT8_C(c) c // RISCV32: #define __INT8_C_SUFFIX__ // RISCV32: #define __INT8_MAX__ 127 // RISCV32: #define __INT8_TYPE__ signed char +// RISCV32: #define __INTMAX_C(c) c##LL // RISCV32: #define __INTMAX_C_SUFFIX__ LL // RISCV32: #define __INTMAX_MAX__ 9223372036854775807LL // RISCV32: #define __INTMAX_TYPE__ long long int @@ -2474,18 +2550,23 @@ // RISCV32: #define __STDC_UTF_32__ 1 // RISCV32: #define __STDC_VERSION__ 201710L // RISCV32: #define __STDC__ 1 +// RISCV32: #define __UINT16_C(c) c // RISCV32: #define __UINT16_C_SUFFIX__ // RISCV32: #define __UINT16_MAX__ 65535 // RISCV32: #define __UINT16_TYPE__ unsigned short +// RISCV32: #define __UINT32_C(c) c##U // RISCV32: #define __UINT32_C_SUFFIX__ U // RISCV32: #define __UINT32_MAX__ 4294967295U // RISCV32: #define __UINT32_TYPE__ unsigned int +// RISCV32: #define __UINT64_C(c) c##ULL // RISCV32: #define __UINT64_C_SUFFIX__ ULL // RISCV32: #define __UINT64_MAX__ 18446744073709551615ULL // RISCV32: #define __UINT64_TYPE__ long long unsigned int +// RISCV32: #define __UINT8_C(c) c // RISCV32: #define __UINT8_C_SUFFIX__ // RISCV32: #define __UINT8_MAX__ 255 // RISCV32: #define __UINT8_TYPE__ unsigned char +// RISCV32: #define __UINTMAX_C(c) c##ULL // RISCV32: #define __UINTMAX_C_SUFFIX__ ULL // RISCV32: #define __UINTMAX_MAX__ 18446744073709551615ULL // RISCV32: #define __UINTMAX_TYPE__ long long unsigned int @@ -2596,18 +2677,23 @@ // RISCV64: #define __GNUC_STDC_INLINE__ 1 // RISCV64: #define __GNUC__ {{.*}} // RISCV64: #define __GXX_ABI_VERSION {{.*}} +// RISCV64: #define __INT16_C(c) c // RISCV64: #define __INT16_C_SUFFIX__ // RISCV64: #define __INT16_MAX__ 32767 // RISCV64: #define __INT16_TYPE__ short +// RISCV64: #define __INT32_C(c) c // RISCV64: #define __INT32_C_SUFFIX__ // RISCV64: #define __INT32_MAX__ 2147483647 // RISCV64: #define __INT32_TYPE__ int +// RISCV64: #define __INT64_C(c) c##L // RISCV64: #define __INT64_C_SUFFIX__ L // RISCV64: #define __INT64_MAX__ 9223372036854775807L // RISCV64: #define __INT64_TYPE__ long int +// RISCV64: #define __INT8_C(c) c // RISCV64: #define __INT8_C_SUFFIX__ // RISCV64: #define __INT8_MAX__ 127 // RISCV64: #define __INT8_TYPE__ signed char +// RISCV64: #define __INTMAX_C(c) c##L // RISCV64: #define __INTMAX_C_SUFFIX__ L // RISCV64: #define __INTMAX_MAX__ 9223372036854775807L // RISCV64: #define __INTMAX_TYPE__ long int @@ -2687,18 +2773,23 @@ // RISCV64: #define __STDC_UTF_32__ 1 // RISCV64: #define __STDC_VERSION__ 201710L // RISCV64: #define __STDC__ 1 +// RISCV64: #define __UINT16_C(c) c // RISCV64: #define __UINT16_C_SUFFIX__ // RISCV64: #define __UINT16_MAX__ 65535 // RISCV64: #define __UINT16_TYPE__ unsigned short +// RISCV64: #define __UINT32_C(c) c##U // RISCV64: #define __UINT32_C_SUFFIX__ U // RISCV64: #define __UINT32_MAX__ 4294967295U // RISCV64: #define __UINT32_TYPE__ unsigned int +// RISCV64: #define __UINT64_C(c) c##UL // RISCV64: #define __UINT64_C_SUFFIX__ UL // RISCV64: #define __UINT64_MAX__ 18446744073709551615UL // RISCV64: #define __UINT64_TYPE__ long unsigned int +// RISCV64: #define __UINT8_C(c) c // RISCV64: #define __UINT8_C_SUFFIX__ // RISCV64: #define __UINT8_MAX__ 255 // RISCV64: #define __UINT8_TYPE__ unsigned char +// RISCV64: #define __UINTMAX_C(c) c##UL // RISCV64: #define __UINTMAX_C_SUFFIX__ UL // RISCV64: #define __UINTMAX_MAX__ 18446744073709551615UL // RISCV64: #define __UINTMAX_TYPE__ long unsigned int @@ -2837,18 +2928,23 @@ // XTENSA: #define __GNUC__ {{.*}} // XTENSA: #define __GXX_ABI_VERSION {{.*}} // XTENSA: #define __ILP32__ 1 +// XTENSA: #define __INT16_C(c) c // XTENSA: #define __INT16_C_SUFFIX__ // XTENSA: #define __INT16_MAX__ 32767 // XTENSA: #define __INT16_TYPE__ short +// XTENSA: #define __INT32_C(c) c // XTENSA: #define __INT32_C_SUFFIX__ // XTENSA: #define __INT32_MAX__ 2147483647 // XTENSA: #define __INT32_TYPE__ int +// XTENSA: #define __INT64_C(c) c##LL // XTENSA: #define __INT64_C_SUFFIX__ LL // XTENSA: #define __INT64_MAX__ 9223372036854775807LL // XTENSA: #define __INT64_TYPE__ long long int +// XTENSA: #define __INT8_C(c) c // XTENSA: #define __INT8_C_SUFFIX__ // XTENSA: #define __INT8_MAX__ 127 // XTENSA: #define __INT8_TYPE__ signed char +// XTENSA: #define __INTMAX_C(c) c##LL // XTENSA: #define __INTMAX_C_SUFFIX__ LL // XTENSA: #define __INTMAX_MAX__ 9223372036854775807LL // XTENSA: #define __INTMAX_TYPE__ long long int @@ -2945,18 +3041,23 @@ // XTENSA: #define __STDC_UTF_32__ 1 // XTENSA: #define __STDC_VERSION__ 201710L // XTENSA: #define __STDC__ 1 +// XTENSA: #define __UINT16_C(c) c // XTENSA: #define __UINT16_C_SUFFIX__ // XTENSA: #define __UINT16_MAX__ 65535 // XTENSA: #define __UINT16_TYPE__ unsigned short +// XTENSA: #define __UINT32_C(c) c##U // XTENSA: #define __UINT32_C_SUFFIX__ U // XTENSA: #define __UINT32_MAX__ 4294967295U // XTENSA: #define __UINT32_TYPE__ unsigned int +// XTENSA: #define __UINT64_C(c) c##ULL // XTENSA: #define __UINT64_C_SUFFIX__ ULL // XTENSA: #define __UINT64_MAX__ 18446744073709551615ULL // XTENSA: #define __UINT64_TYPE__ long long unsigned int +// XTENSA: #define __UINT8_C(c) c // XTENSA: #define __UINT8_C_SUFFIX__ // XTENSA: #define __UINT8_MAX__ 255 // XTENSA: #define __UINT8_TYPE__ unsigned char +// XTENSA: #define __UINTMAX_C(c) c##ULL // XTENSA: #define __UINTMAX_C_SUFFIX__ ULL // XTENSA: #define __UINTMAX_MAX__ 18446744073709551615ULL // XTENSA: #define __UINTMAX_TYPE__ long long unsigned int diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c index fa3d0038f05a9..63222a882ff53 100644 --- a/clang/test/Preprocessor/x86_target_features.c +++ b/clang/test/Preprocessor/x86_target_features.c @@ -742,10 +742,8 @@ // AVXVNNIINT16NOAVX2-NOT: #define __AVX2__ 1 // AVXVNNIINT16NOAVX2-NOT: #define __AVXVNNIINT16__ 1 -// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_256 %s // RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-256 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_256 %s // RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-256 -mno-avx512f -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_256 %s -// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.2 -x c -E -dM -o - %s | FileCheck -check-prefixes=AVX10_1_256,AVX10_2_256 %s // RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.2-256 -x c -E -dM -o - %s | FileCheck -check-prefixes=AVX10_1_256,AVX10_2_256 %s // AVX10_1_256-NOT: __AVX10_1_512__ // AVX10_1_256: #define __AVX10_1__ 1 @@ -758,6 +756,7 @@ // RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-512 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_512 %s // RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-512 -mno-avx512f -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_512 %s // RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.1-512 -mno-evex512 -x c -E -dM -o - %s | FileCheck -check-prefix=AVX10_1_512 %s +// RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.2 -x c -E -dM -o - %s | FileCheck -check-prefixes=AVX10_1_512,AVX10_2_512 %s // RUN: %clang -target i686-unknown-linux-gnu -march=atom -mavx10.2-512 -x c -E -dM -o - %s | FileCheck -check-prefixes=AVX10_1_512,AVX10_2_512 %s // AVX10_1_512: #define __AVX10_1_512__ 1 // AVX10_1_512: #define __AVX10_1__ 1 diff --git a/clang/test/Rewriter/lit.local.cfg b/clang/test/Rewriter/lit.local.cfg index f5e1d0349f52d..2fc1173d7ba31 100644 --- a/clang/test/Rewriter/lit.local.cfg +++ b/clang/test/Rewriter/lit.local.cfg @@ -1,3 +1,3 @@ # The Objective-C rewriters are currently grouped with ARCMT. -if not config.root.clang_arcmt: +if not config.root.clang_objc_rewriter: config.unsupported = True diff --git a/clang/test/Sema/MicrosoftCompatibility.c b/clang/test/Sema/MicrosoftCompatibility.c index 9a1f050747f9d..8d402d53e004d 100644 --- a/clang/test/Sema/MicrosoftCompatibility.c +++ b/clang/test/Sema/MicrosoftCompatibility.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -DMSVCCOMPAT -triple i686-pc-win32 -// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -triple i686-pc-win32 +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify=expected,compat -fms-compatibility -DMSVCCOMPAT -triple i686-pc-win32 +// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify=expected,ext -fms-extensions -triple i686-pc-win32 #ifdef MSVCCOMPAT enum ENUM1; // expected-warning {{forward references to 'enum' types are a Microsoft extension}} @@ -35,3 +35,15 @@ size_t x; #else size_t x; // expected-error {{unknown type name 'size_t'}} #endif + +/* Microsoft allows inline, __inline, and __forceinline to appear on a typedef + of a function type; this is used in their system headers such as ufxclient.h + See GitHub #124869 for more details. + */ +typedef int inline Foo1(int); // compat-warning {{'inline' can only appear on functions}} \ + ext-error {{'inline' can only appear on functions}} +typedef int __inline Foo2(int); // compat-warning {{'inline' can only appear on functions}} \ + ext-error {{'inline' can only appear on functions}} +typedef int __forceinline Foo(int); // compat-warning {{'inline' can only appear on functions}} \ + ext-error {{'inline' can only appear on functions}} \ + expected-warning {{'__forceinline' attribute only applies to functions and statements}} diff --git a/clang/test/Sema/MicrosoftCompatibility.cpp b/clang/test/Sema/MicrosoftCompatibility.cpp index 90a45dfaaf176..391977e2765c5 100644 --- a/clang/test/Sema/MicrosoftCompatibility.cpp +++ b/clang/test/Sema/MicrosoftCompatibility.cpp @@ -8,3 +8,10 @@ struct cls { }; char * cls::* __uptr wrong2 = &cls::m; // expected-error {{'__uptr' attribute cannot be used with pointers to members}} + +// Microsoft allows inline, __inline, and __forceinline to appear on a typedef +// of a function type, but only in C. See GitHub #124869 for more details. +typedef int inline Foo1(int); // expected-error {{'inline' can only appear on functions}} +typedef int __inline Foo2(int); // expected-error {{'inline' can only appear on functions}} +typedef int __forceinline Foo(int); // expected-error {{'inline' can only appear on functions}} \ + expected-warning {{'__forceinline' attribute only applies to functions and statements}} diff --git a/clang/test/Sema/aarch64-fp8-cast.c b/clang/test/Sema/aarch64-fp8-cast.c new file mode 100644 index 0000000000000..ad25401919b5a --- /dev/null +++ b/clang/test/Sema/aarch64-fp8-cast.c @@ -0,0 +1,104 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon -verify -emit-llvm -o - %s + +// REQUIRES: aarch64-registered-target + +#include + +// Bitcast between FP8 Neon vectors +mfloat8x8_t err_test_f8_f8(mfloat8x16_t x) { + return (mfloat8x8_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values) of different size}} +} + +mfloat8x16_t err_testq_f8_f8(mfloat8x8_t x) { + return (mfloat8x16_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x16_t' (vector of 16 'mfloat8_t' values) and 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) of different size}} +} + +// Bitcast between FP8 and int8 Neon vectors +mfloat8x8_t err_test_f8_s8(int8x16_t x) { + return (mfloat8x8_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'int8x16_t' (vector of 16 'int8_t' values) of different size}} +} + +int8x8_t err_test_s8_f8(mfloat8x16_t x) { + return (int8x8_t) x; +// expected-error@-1 {{invalid conversion between vector type 'int8x8_t' (vector of 8 'int8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values) of different size}} +} + +mfloat8x16_t err_testq_f8_s8(int8x8_t x) { + return (mfloat8x16_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x16_t' (vector of 16 'mfloat8_t' values) and 'int8x8_t' (vector of 8 'int8_t' values) of different size}} +} + +int8x16_t err_testq_s8_f8(mfloat8x8_t x) { + return (int8x16_t) x; +// expected-error@-1 {{invalid conversion between vector type 'int8x16_t' (vector of 16 'int8_t' values) and 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) of different size}} +} + +// Bitcast between FP8 and float32 Neon vectors +mfloat8x8_t err_test_f8_f32(float32x4_t x) { + return (mfloat8x8_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'float32x4_t' (vector of 4 'float32_t' values) of different size}} +} + +float32x2_t err_test_f32_f8(mfloat8x16_t x) { + return (float32x2_t) x; +// expected-error@-1 {{invalid conversion between vector type 'float32x2_t' (vector of 2 'float32_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values) of different size}} +} + +mfloat8x16_t err_testq_f8_f32(float32x2_t x) { + return (mfloat8x16_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x16_t' (vector of 16 'mfloat8_t' values) and 'float32x2_t' (vector of 2 'float32_t' values) of different size}} +} + +float32x4_t err_testq_f32_f8(mfloat8x8_t x) { + return (float32x4_t) x; +// expected-error@-1 {{invalid conversion between vector type 'float32x4_t' (vector of 4 'float32_t' values) and 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) of different size}} +} + +// Bitcast between FP8 and poly128_t (which is integral) +mfloat8x8_t err_testq_f8_p128(poly128_t x) { + return (mfloat8x8_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and integer type 'poly128_t' (aka 'unsigned __int128') of different size}} +} + +poly128_t err_testq_p128_f8(mfloat8x8_t x) { + return (poly128_t) x; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and integer type 'poly128_t' (aka 'unsigned __int128') of different size}} +} + +// Bitcast between FP8 and a non-integral type +mfloat8x8_t err_test_f8_ptr(void *p) { + return (mfloat8x8_t) p; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and scalar type 'void *'}} +} + +void *err_test_ptr_f8(mfloat8x8_t v) { + return (void *) v; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and scalar type 'void *'}} +} + +mfloat8x8_t err_test_f8_dbl(double v) { + return (mfloat8x8_t) v; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and scalar type 'double'}} +} + +double err_test_dbl_f8(mfloat8x8_t v) { + return (double) v; +// expected-error@-1 {{invalid conversion between vector type 'mfloat8x8_t' (vector of 8 'mfloat8_t' values) and scalar type 'double'}} +} + +struct S { + char ch[16]; +}; + +mfloat8x16_t err_test_f8_agg(struct S s) { + return (mfloat8x16_t) s; +// expected-error@-1 {{operand of type 'struct S' where arithmetic or pointer type is required}} +} + +struct S err_test_agg_f8(mfloat8x16_t v) { + return (struct S) v; +// expected-error@-1 {{used type 'struct S' where arithmetic or pointer type is required}} +} diff --git a/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_cvt.c b/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_cvt.c new file mode 100644 index 0000000000000..2c7004c7968a4 --- /dev/null +++ b/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_cvt.c @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +faminmax -emit-llvm -verify %s -o /dev/null + +// REQUIRES: aarch64-registered-target + +#include + +void test_features(float16x4_t vd4, float16x8_t vd8, float32x4_t va4, + mfloat8x8_t v8, mfloat8x16_t v16, fpm_t fpm) { + (void) vcvt1_bf16_mf8_fpm(v8, fpm); + // expected-error@-1 {{'vcvt1_bf16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt1_low_bf16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt1_low_bf16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt2_bf16_mf8_fpm(v8, fpm); + // expected-error@-1 {{'vcvt2_bf16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt2_low_bf16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt2_low_bf16_mf8_fpm' requires target feature 'fp8'}} + + (void) vcvt1_high_bf16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt1_high_bf16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt2_high_bf16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt2_high_bf16_mf8_fpm' requires target feature 'fp8'}} + + (void) vcvt1_f16_mf8_fpm(v8, fpm); + // expected-error@-1 {{'vcvt1_f16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt1_low_f16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt1_low_f16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt2_f16_mf8_fpm(v8, fpm); + // expected-error@-1 {{'vcvt2_f16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt2_low_f16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt2_low_f16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt1_high_f16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt1_high_f16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt2_high_f16_mf8_fpm(v16, fpm); + // expected-error@-1 {{'vcvt2_high_f16_mf8_fpm' requires target feature 'fp8'}} + (void) vcvt_mf8_f32_fpm(va4, va4, fpm); + // expected-error@-1 {{'vcvt_mf8_f32_fpm' requires target feature 'fp8'}} + (void) vcvt_high_mf8_f32_fpm(v8, va4, va4, fpm); + // expected-error@-1 {{'vcvt_high_mf8_f32_fpm' requires target feature 'fp8'}} + (void) vcvt_mf8_f16_fpm(vd4, vd4, fpm); + // expected-error@-1 {{'vcvt_mf8_f16_fpm' requires target feature 'fp8'}} + (void) vcvtq_mf8_f16_fpm(vd8, vd8, fpm); + // expected-error@-1 {{'vcvtq_mf8_f16_fpm' requires target feature 'fp8'}} +} diff --git a/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_fdot.c b/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_fdot.c new file mode 100644 index 0000000000000..8bfe3ac26ab2c --- /dev/null +++ b/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_fdot.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +faminmax -target-feature +fp8 -emit-llvm -verify %s -o /dev/null + +// REQUIRES: aarch64-registered-target + +#include + +void test_features(float16x4_t vd4, float16x8_t vd8, float32x4_t va4, float32x2_t va2, + mfloat8x8_t v8, mfloat8x16_t v16, fpm_t fpm) { + (void) vdot_f16_mf8_fpm(vd4, v8, v8, fpm); +// expected-error@-1 {{'vdot_f16_mf8_fpm' requires target feature 'fp8dot2'}} + (void) vdotq_f16_mf8_fpm(vd8, v16, v16, fpm); +// expected-error@-1 {{'vdotq_f16_mf8_fpm' requires target feature 'fp8dot2'}} + (void) vdot_lane_f16_mf8_fpm(vd4, v8, v8, 3, fpm); +// expected-error@-1 {{'__builtin_neon_vdot_lane_f16_mf8_fpm' needs target feature fp8dot2,neon}} + (void) vdot_laneq_f16_mf8_fpm(vd4, v8, v16, 7, fpm); +// expected-error@-1 {{'__builtin_neon_vdot_laneq_f16_mf8_fpm' needs target feature fp8dot2,neon}} + (void) vdotq_lane_f16_mf8_fpm(vd8, v16, v8, 3, fpm); +// expected-error@-1 {{'__builtin_neon_vdotq_lane_f16_mf8_fpm' needs target feature fp8dot2,neon}} + (void) vdotq_laneq_f16_mf8_fpm(vd8, v16, v16, 7, fpm); +// expected-error@-1 {{'__builtin_neon_vdotq_laneq_f16_mf8_fpm' needs target feature fp8dot2,neon}} + + (void) vdot_f32_mf8_fpm(va2, v8, v8, fpm); +// expected-error@-1 {{'vdot_f32_mf8_fpm' requires target feature 'fp8dot4'}} + (void) vdotq_f32_mf8_fpm(va4, v16, v16, fpm); +// expected-error@-1 {{'vdotq_f32_mf8_fpm' requires target feature 'fp8dot4}} + (void) vdot_lane_f32_mf8_fpm(va2, v8, v8, 1, fpm); +// expected-error@-1 {{'__builtin_neon_vdot_lane_f32_mf8_fpm' needs target feature fp8dot4,neon}} + (void) vdot_laneq_f32_mf8_fpm(va2, v8, v16, 3, fpm); +// expected-error@-1 {{'__builtin_neon_vdot_laneq_f32_mf8_fpm' needs target feature fp8dot4,neon}} + (void) vdotq_lane_f32_mf8_fpm(va4, v16, v8, 1, fpm); +// expected-error@-1 {{'__builtin_neon_vdotq_lane_f32_mf8_fpm' needs target feature fp8dot4,neon}} + (void) vdotq_laneq_f32_mf8_fpm(va4, v16, v16, 3, fpm); +// expected-error@-1 {{'__builtin_neon_vdotq_laneq_f32_mf8_fpm' needs target feature fp8dot4,neon}} +} + +void test_imm(float16x4_t vd4, float16x8_t vd8, float32x2_t va2, float32x4_t va4, + mfloat8x8_t v8, mfloat8x16_t v16, fpm_t fpm) { + (void) vdot_lane_f16_mf8_fpm(vd4, v8, v8, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 3]}} + (void) vdot_laneq_f16_mf8_fpm(vd4, v8, v16, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} + (void) vdotq_lane_f16_mf8_fpm(vd8, v16, v8, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 3]}} + (void) vdotq_laneq_f16_mf8_fpm(vd8, v16, v16, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} + (void) vdot_lane_f32_mf8_fpm(va2, v8, v8, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 1]}} + (void) vdot_laneq_f32_mf8_fpm(va2, v8, v16, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 3]}} + (void) vdotq_lane_f32_mf8_fpm(va4, v16, v8, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 1]}} + (void) vdotq_laneq_f32_mf8_fpm(va4, v16, v16, -1, fpm); + // expected-error@-1 {{argument value -1 is outside the valid range [0, 3]}} +} diff --git a/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_fmla.c b/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_fmla.c new file mode 100644 index 0000000000000..4a507b08040ff --- /dev/null +++ b/clang/test/Sema/aarch64-fp8-intrinsics/acle_neon_fp8_fmla.c @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-feature +bf16 -target-feature +faminmax -target-feature +fp8 -emit-llvm -verify %s -o /dev/null + +// REQUIRES: aarch64-registered-target + +#include + +void test_features(float16x8_t a, float32x4_t b, mfloat8x16_t u, fpm_t fpm) { + (void) vmlalbq_f16_mf8_fpm(a, u, u, fpm); + // expected-error@-1 {{'vmlalbq_f16_mf8_fpm' requires target feature 'fp8fma'}} + (void) vmlaltq_f16_mf8_fpm(a, u, u, fpm); + // expected-error@-1 {{'vmlaltq_f16_mf8_fpm' requires target feature 'fp8fma'}} + (void) vmlallbbq_f32_mf8_fpm(b, u, u, fpm); + // expected-error@-1 {{'vmlallbbq_f32_mf8_fpm' requires target feature 'fp8fma'}} + (void) vmlallbtq_f32_mf8_fpm(b, u, u, fpm); + // expected-error@-1 {{'vmlallbtq_f32_mf8_fpm' requires target feature 'fp8fma'}} + (void) vmlalltbq_f32_mf8_fpm(b, u, u, fpm); + // expected-error@-1 {{'vmlalltbq_f32_mf8_fpm' requires target feature 'fp8fma'}} + (void) vmlallttq_f32_mf8_fpm(b, u, u, fpm); + // expected-error@-1 {{'vmlallttq_f32_mf8_fpm' requires target feature 'fp8fma'}} +} + +void test_imm(float16x8_t d, float32x4_t c, mfloat8x16_t a, mfloat8x8_t b, fpm_t fpm) { +(void) vmlalbq_lane_f16_mf8_fpm(d, a, b, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} +(void) vmlalbq_laneq_f16_mf8_fpm(d, a, a, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 15]}} +(void) vmlaltq_lane_f16_mf8_fpm(d, a, b, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} +(void) vmlaltq_laneq_f16_mf8_fpm(d, a, a, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 15]}} + +(void) vmlallbbq_lane_f32_mf8_fpm(c, a, b, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} +(void) vmlallbbq_laneq_f32_mf8_fpm(c, a, a, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 15]}} +(void) vmlallbtq_lane_f32_mf8_fpm(c, a, b, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} +(void) vmlallbtq_laneq_f32_mf8_fpm(c, a, a, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 15]}} +(void) vmlalltbq_lane_f32_mf8_fpm(c, a, b, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} +(void) vmlalltbq_laneq_f32_mf8_fpm(c, a, a, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 15]}} +(void) vmlallttq_lane_f32_mf8_fpm(c, a, b, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 7]}} +(void) vmlallttq_laneq_f32_mf8_fpm(c, a, a, -1, fpm); +// expected-error@-1 {{argument value -1 is outside the valid range [0, 15]}} +} + diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c deleted file mode 100644 index 27fa8f7c9dccb..0000000000000 --- a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.c +++ /dev/null @@ -1,128 +0,0 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py -// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve \ -// RUN: -target-feature +bf16 -target-feature +sve -target-feature +sme -target-feature +sme2 -target-feature +sve2 -target-feature +neon -Waarch64-sme-attributes -fsyntax-only -verify %s - -// REQUIRES: aarch64-registered-target - -#include "arm_neon.h" -#include "arm_sme.h" -#include "arm_sve.h" - -int16x8_t incompat_neon_sm(int16x8_t splat) __arm_streaming { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); -} - -__arm_locally_streaming int16x8_t incompat_neon_ls(int16x8_t splat) { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); -} - -int16x8_t incompat_neon_smc(int16x8_t splat) __arm_streaming_compatible { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); -} - -void incompat_sme_smc(svbool_t pg, void const *ptr) __arm_streaming_compatible __arm_inout("za") { - // expected-error@+1 {{builtin can only be called from a streaming function}} - return __builtin_sme_svld1_hor_za128(0, 0, pg, ptr); -} - -float incomp_sve_sm_fadda_sm(void) __arm_streaming { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return svadda(svptrue_b32(), 0, svdup_f32(1)); -} - -float incomp_sve_sm_fadda_smc(void) __arm_streaming_compatible { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return svadda(svptrue_b32(), 0, svdup_f32(1)); -} - -svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); -} - -// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); -} - -svuint32_t incompat_sve_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); -} - -svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); -} - -// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); -} - -svuint32_t incompat_sve2_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible { - // expected-error@+1 {{builtin can only be called from a non-streaming function}} - return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); -} - -void incompat_sme_sm(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) __arm_inout("za") { - // expected-error@+1 {{builtin can only be called from a streaming function}} - svmops_za32_f32_m(0, pn, pm, zn, zm); -} - -svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming { - return svadd_n_f64_m(pg, a, b); -} - -// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) { - return svadd_n_f64_m(pg, a, b); -} - -svfloat64_t streaming_compatible_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming_compatible { - return svadd_n_f64_m(pg, a, b); -} - -svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming { - return svmul_lane_s16(op1, op2, 0); -} - -// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} -__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) { - return svmul_lane_s16(op1, op2, 0); -} - -svint16_t streaming_compatible_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming_compatible { - return svmul_lane_s16(op1, op2, 0); -} - -svbool_t streaming_caller_ptrue(void) __arm_streaming { - return svand_z(svptrue_b16(), svptrue_pat_b16(SV_ALL), svptrue_pat_b16(SV_VL4)); -} - -svint8_t missing_za(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming { - // expected-warning@+1 {{builtin call is not valid when calling from a function without active ZA state}} - return svread_hor_za8_s8_m(zd, pg, 0, slice_base); -} - -__arm_new("za") -svint8_t new_za(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming { - return svread_hor_za8_s8_m(zd, pg, 0, slice_base); -} - -void missing_zt0(void) __arm_streaming { - // expected-warning@+1 {{builtin call is not valid when calling from a function without active ZT0 state}} - svzero_zt(0); -} - -__arm_new("zt0") -void new_zt0(void) __arm_streaming { svzero_zt(0); } diff --git a/clang/test/Sema/aarch64-incompat-sm-builtin-calls.cpp b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.cpp new file mode 100644 index 0000000000000..3fbcaf4a13d67 --- /dev/null +++ b/clang/test/Sema/aarch64-incompat-sm-builtin-calls.cpp @@ -0,0 +1,194 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -std=c++23 -triple aarch64-none-linux-gnu -target-feature +sve \ +// RUN: -target-feature +bf16 -target-feature +sve -target-feature +sme -target-feature +sme2 -target-feature +sve2 -target-feature +neon -Waarch64-sme-attributes -fsyntax-only -verify %s + +// REQUIRES: aarch64-registered-target + +#include "arm_neon.h" +#include "arm_sme.h" +#include "arm_sve.h" + +int16x8_t incompat_neon_sm(int16x8_t splat) __arm_streaming { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); +} + +__arm_locally_streaming int16x8_t incompat_neon_ls(int16x8_t splat) { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); +} + +int16x8_t incompat_neon_smc(int16x8_t splat) __arm_streaming_compatible { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); +} + +void incompat_sme_smc(svbool_t pg, void const *ptr) __arm_streaming_compatible __arm_inout("za") { + // expected-error@+1 {{builtin can only be called from a streaming function}} + return __builtin_sme_svld1_hor_za128(0, 0, pg, ptr); +} + +float incomp_sve_sm_fadda_sm(void) __arm_streaming { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return svadda(svptrue_b32(), 0, svdup_f32(1)); +} + +float incomp_sve_sm_fadda_smc(void) __arm_streaming_compatible { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return svadda(svptrue_b32(), 0, svdup_f32(1)); +} + +svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); +} + +// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); +} + +svuint32_t incompat_sve_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b); +} + +svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); +} + +// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); +} + +svuint32_t incompat_sve2_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b); +} + +void incompat_sme_sm(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) __arm_inout("za") { + // expected-error@+1 {{builtin can only be called from a streaming function}} + svmops_za32_f32_m(0, pn, pm, zn, zm); +} + +svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming { + return svadd_n_f64_m(pg, a, b); +} + +// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) { + return svadd_n_f64_m(pg, a, b); +} + +svfloat64_t streaming_compatible_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming_compatible { + return svadd_n_f64_m(pg, a, b); +} + +svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming { + return svmul_lane_s16(op1, op2, 0); +} + +// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} +__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) { + return svmul_lane_s16(op1, op2, 0); +} + +svint16_t streaming_compatible_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming_compatible { + return svmul_lane_s16(op1, op2, 0); +} + +svbool_t streaming_caller_ptrue(void) __arm_streaming { + return svand_z(svptrue_b16(), svptrue_pat_b16(SV_ALL), svptrue_pat_b16(SV_VL4)); +} + +svint8_t missing_za(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming { + // expected-warning@+1 {{builtin call is not valid when calling from a function without active ZA state}} + return svread_hor_za8_s8_m(zd, pg, 0, slice_base); +} + +__arm_new("za") +svint8_t new_za(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming { + return svread_hor_za8_s8_m(zd, pg, 0, slice_base); +} + +void missing_zt0(void) __arm_streaming { + // expected-warning@+1 {{builtin call is not valid when calling from a function without active ZT0 state}} + svzero_zt(0); +} + +__arm_new("zt0") +void new_zt0(void) __arm_streaming { svzero_zt(0); } + +/// C++ lambda tests: + +void use_streaming_builtin_in_lambda(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_out("za") +{ + [&]{ + /// The lambda is its own function and does not inherit the SME attributes (so this should error). + // expected-error@+1 {{builtin can only be called from a streaming function}} + svld1_hor_za64(0, slice_base, pg, ptr); + }(); +} + +void use_streaming_builtin(uint32_t slice_base, svbool_t pg, const void *ptr) __arm_streaming __arm_out("za") +{ + /// Without the lambda the same builtin is okay (as the SME attributes apply). + svld1_hor_za64(0, slice_base, pg, ptr); +} + +int16x8_t use_neon_builtin_sm(int16x8_t splat) __arm_streaming_compatible { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); +} + +int16x8_t use_neon_builtin_sm_in_lambda(int16x8_t splat) __arm_streaming_compatible { + return [&]{ + /// This should not error (as we switch out of streaming mode to execute the lambda). + /// Note: The result int16x8_t is spilled and reloaded as a q-register. + return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); + }(); +} + +float use_incomp_sve_builtin_sm() __arm_streaming { + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return svadda(svptrue_b32(), 0, svdup_f32(1)); +} + +float incomp_sve_sm_fadda_sm_in_lambda(void) __arm_streaming { + return [&]{ + /// This should work like the Neon builtin. + return svadda(svptrue_b32(), 0, svdup_f32(1)); + }(); +} + +void use_streaming_builtin_in_streaming_lambda(uint32_t slice_base, const void *ptr) +{ + [&] __arm_new("za") () __arm_streaming { + // Here the lambda is streaming with ZA state, so this is okay. + svld1_hor_za64(0, slice_base, svptrue_b64(), ptr); + }(); +} + +int16x8_t use_neon_builtin_in_streaming_lambda(int16x8_t splat) { + return [&]() __arm_streaming_compatible { + /// This should error as the lambda is streaming-compatible. + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33); + }(); +} + +float incomp_sve_fadda_in_streaming_lambda(void) { + return [&]() __arm_streaming { + // Should error (like the Neon case above). + // expected-error@+1 {{builtin can only be called from a non-streaming function}} + return svadda(svptrue_b32(), 0, svdup_f32(1)); + }(); +} diff --git a/clang/test/Sema/aarch64-sme-attrs-openmp-captured-region.c b/clang/test/Sema/aarch64-sme-attrs-openmp-captured-region.c new file mode 100644 index 0000000000000..6fb7c60d02cd7 --- /dev/null +++ b/clang/test/Sema/aarch64-sme-attrs-openmp-captured-region.c @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -fopenmp -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -fopenmp -fsyntax-only -verify=expected-cpp -x c++ %s + +int compute(int); + +void streaming_openmp_captured_region(int * out) __arm_streaming { + // expected-error@+2 {{OpenMP captured regions are not yet supported in streaming functions}} + // expected-cpp-error@+1 {{OpenMP captured regions are not yet supported in streaming functions}} + #pragma omp parallel for num_threads(32) + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +__arm_locally_streaming void locally_streaming_openmp_captured_region(int * out) { + // expected-error@+2 {{OpenMP captured regions are not yet supported in streaming functions}} + // expected-cpp-error@+1 {{OpenMP captured regions are not yet supported in streaming functions}} + #pragma omp parallel for num_threads(32) + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +void za_state_captured_region(int * out) __arm_inout("za") { + // expected-error@+2 {{OpenMP captured regions are not yet supported in functions with ZA state}} + // expected-cpp-error@+1 {{OpenMP captured regions are not yet supported in functions with ZA state}} + #pragma omp parallel for num_threads(32) + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +__arm_new("za") void new_za_state_captured_region(int * out) { + // expected-error@+2 {{OpenMP captured regions are not yet supported in functions with ZA state}} + // expected-cpp-error@+1 {{OpenMP captured regions are not yet supported in functions with ZA state}} + #pragma omp parallel for num_threads(32) + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +void zt0_state_openmp_captured_region(int * out) __arm_inout("zt0") { + // expected-error@+2 {{OpenMP captured regions are not yet supported in functions with ZT0 state}} + // expected-cpp-error@+1 {{OpenMP captured regions are not yet supported in functions with ZT0 state}} + #pragma omp parallel for num_threads(32) + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +__arm_new("zt0") void new_zt0_state_openmp_captured_region(int * out) { + // expected-error@+2 {{OpenMP captured regions are not yet supported in functions with ZT0 state}} + // expected-cpp-error@+1 {{OpenMP captured regions are not yet supported in functions with ZT0 state}} + #pragma omp parallel for num_threads(32) + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +/// OpenMP directives that don't create a captured region are okay: + +void streaming_function_openmp(int * out) __arm_streaming __arm_inout("za", "zt0") { + #pragma omp unroll full + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +__arm_locally_streaming void locally_streaming_openmp(int * out) __arm_inout("za", "zt0") { + #pragma omp unroll full + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} + +__arm_new("za", "zt0") void arm_new_openmp(int * out) { + #pragma omp unroll full + for (int ci = 0; ci < 8; ci++) { + out[ci] = compute(ci); + } +} diff --git a/clang/test/Sema/arm-execute-only-tls.c b/clang/test/Sema/arm-execute-only-tls.c new file mode 100644 index 0000000000000..b17ff450cb74d --- /dev/null +++ b/clang/test/Sema/arm-execute-only-tls.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple arm-none-eabi -fsyntax-only -verify=default %s +// RUN: %clang_cc1 -triple arm-none-eabi -target-feature +execute-only -fsyntax-only -verify=execute-only %s + +// default-no-diagnostics + +/// Thread-local code generation requires constant pools because most of the +/// relocations needed for it operate on data, so it cannot be used with +/// -mexecute-only (or -mpure-code, which is aliased in the driver). + +_Thread_local int t; // execute-only-error {{thread-local storage is not supported for the current target}} diff --git a/clang/test/Sema/arm-mfp8.cpp b/clang/test/Sema/arm-mfp8.cpp index be5bc9bb71dbd..1b4e6791420ec 100644 --- a/clang/test/Sema/arm-mfp8.cpp +++ b/clang/test/Sema/arm-mfp8.cpp @@ -48,17 +48,27 @@ void test_vector_sve(svmfloat8_t a, svuint8_t c) { #include void test_vector(mfloat8x8_t a, mfloat8x16_t b, uint8x8_t c) { - a + b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} - a - b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} - a * b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} - a / b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + a + a; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x8_t')}} + a - a; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x8_t')}} + a * a; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x8_t')}} + a / a; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x8_t')}} - a + c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} - a - c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} - a * c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} - a / c; // neon-error {{cannot convert between vector and non-scalar values ('mfloat8x8_t' (aka '__MFloat8x8_t') and 'uint8x8_t' (vector of 8 'uint8_t' values))}} - c + b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} - c - b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} - c * b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} - c / b; // neon-error {{cannot convert between vector and non-scalar values ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (aka '__MFloat8x16_t'))}} + b + b; // neon-error {{invalid operands to binary expression ('mfloat8x16_t' (vector of 16 'mfloat8_t' values) and 'mfloat8x16_t')}} + b - b; // neon-error {{invalid operands to binary expression ('mfloat8x16_t' (vector of 16 'mfloat8_t' values) and 'mfloat8x16_t')}} + b * b; // neon-error {{invalid operands to binary expression ('mfloat8x16_t' (vector of 16 'mfloat8_t' values) and 'mfloat8x16_t')}} + b / b; // neon-error {{invalid operands to binary expression ('mfloat8x16_t' (vector of 16 'mfloat8_t' values) and 'mfloat8x16_t')}} + + a + b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} + a - b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} + a * b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} + a / b; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} + + a + c; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + a - c; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + a * c; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + a / c; // neon-error {{invalid operands to binary expression ('mfloat8x8_t' (vector of 8 'mfloat8_t' values) and 'uint8x8_t' (vector of 8 'uint8_t' values))}} + c + b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} + c - b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} + c * b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} + c / b; // neon-error {{invalid operands to binary expression ('uint8x8_t' (vector of 8 'uint8_t' values) and 'mfloat8x16_t' (vector of 16 'mfloat8_t' values))}} } diff --git a/clang/test/Sema/attr-cpuspecific.c b/clang/test/Sema/attr-cpuspecific.c index 3cd58f49faa5e..238db0ac0b85d 100644 --- a/clang/test/Sema/attr-cpuspecific.c +++ b/clang/test/Sema/attr-cpuspecific.c @@ -44,7 +44,8 @@ int allow_fwd_decl2(void); void use_fwd_decl(void) { allow_fwd_decl2(); } -// expected-error@+1 {{function declaration cannot become a multiversioned function after first usage}} +// expected-error@+2 {{function declaration cannot become a multiversioned function after first usage}} +// expected-note@-5 {{previous declaration is here}} int __attribute__((cpu_dispatch(atom))) allow_fwd_decl2(void) {} diff --git a/clang/test/Sema/attr-target-mv.c b/clang/test/Sema/attr-target-mv.c index ddb1d82b02f09..dfc3d614dc1e0 100644 --- a/clang/test/Sema/attr-target-mv.c +++ b/clang/test/Sema/attr-target-mv.c @@ -66,7 +66,8 @@ int use3(void) { return mv_after_use(); } -// expected-error@+1 {{function declaration cannot become a multiversioned function after first usage}} +// expected-error@+2 {{function declaration cannot become a multiversioned function after first usage}} +// expected-note@-6 {{previous declaration is here}} int __attribute__((target("arch=sandybridge"))) mv_after_use(void) { return 2; } int __attribute__((target("sse4.2,arch=sandybridge"))) mangle(void) { return 1; } diff --git a/clang/test/Sema/attr-target-version.c b/clang/test/Sema/attr-target-version.c index cfcc1622abe5c..d062212848daf 100644 --- a/clang/test/Sema/attr-target-version.c +++ b/clang/test/Sema/attr-target-version.c @@ -88,7 +88,8 @@ int bar() { nodef(); return def(); } -// expected-error@+1 {{function declaration cannot become a multiversioned function after first usage}} +// expected-error@+2 {{function declaration cannot become a multiversioned function after first usage}} +// expected-note@-13 {{previous declaration is here}} int __attribute__((target_version("sha2"))) def(void) { return 1; } int __attribute__((target_version("sve"))) prot(); diff --git a/clang/test/Sema/avr-interript-signal-attr.c b/clang/test/Sema/avr-interript-signal-attr.c new file mode 100644 index 0000000000000..7360dbdedb695 --- /dev/null +++ b/clang/test/Sema/avr-interript-signal-attr.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}} + +__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}} + +__attribute__((interrupt)) int fooa(void) { return 0; } // expected-warning {{'interrupt' attribute only applies to functions that have a 'void' return type}} + +__attribute__((interrupt)) void foob(int a) {} // expected-warning {{'interrupt' attribute only applies to functions that have no parameters}} + +__attribute__((signal)) int fooc(void) { return 0; } // expected-warning {{'signal' attribute only applies to functions that have a 'void' return type}} + +__attribute__((signal)) void food(int a) {} // expected-warning {{'signal' attribute only applies to functions that have no parameters}} + +__attribute__((interrupt)) void fooe(void) {} + +__attribute__((interrupt)) void foof() {} + +__attribute__((signal)) void foog(void) {} + +__attribute__((signal)) void fooh() {} diff --git a/clang/test/Sema/avr-interrupt-attr.c b/clang/test/Sema/avr-interrupt-attr.c deleted file mode 100644 index 7aee7babcbe16..0000000000000 --- a/clang/test/Sema/avr-interrupt-attr.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only -struct a { int b; }; - -struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}} - -__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}} - -__attribute__((interrupt)) void food(void) {} diff --git a/clang/test/Sema/avr-signal-attr.c b/clang/test/Sema/avr-signal-attr.c deleted file mode 100644 index 1ec36c74a25eb..0000000000000 --- a/clang/test/Sema/avr-signal-attr.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only -struct a { int b; }; - -struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions}} - -__attribute__((signal(12))) void foo(void) { } // expected-error {{'signal' attribute takes no arguments}} - -__attribute__((signal)) void food(void) {} diff --git a/clang/test/Sema/builtins-elementwise-math.c b/clang/test/Sema/builtins-elementwise-math.c index 6002e91f8ec6f..d6785f78340ca 100644 --- a/clang/test/Sema/builtins-elementwise-math.c +++ b/clang/test/Sema/builtins-elementwise-math.c @@ -69,14 +69,18 @@ void test_builtin_elementwise_add_sat(int i, short s, double d, float4 v, int3 i // expected-error@-1 {{1st argument must be a vector of integers (was 'float4' (vector of 4 'float' values))}} s = __builtin_elementwise_add_sat(i, s); + // expected-error@-1 {{arguments are of different types ('int' vs 'short')}} enum e { one, two }; i = __builtin_elementwise_add_sat(one, two); + i = __builtin_elementwise_add_sat(one, d); + // expected-error@-1 {{arguments are of different types ('int' vs 'double')}} + enum f { three }; enum f x = __builtin_elementwise_add_sat(one, three); - // expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}} + // expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}} _BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}} ext = __builtin_elementwise_add_sat(ext, ext); @@ -128,14 +132,18 @@ void test_builtin_elementwise_sub_sat(int i, short s, double d, float4 v, int3 i // expected-error@-1 {{1st argument must be a vector of integers (was 'float4' (vector of 4 'float' values))}} s = __builtin_elementwise_sub_sat(i, s); + // expected-error@-1 {{arguments are of different types ('int' vs 'short')}} enum e { one, two }; i = __builtin_elementwise_sub_sat(one, two); + i = __builtin_elementwise_sub_sat(one, d); + // expected-error@-1 {{arguments are of different types ('int' vs 'double')}} + enum f { three }; enum f x = __builtin_elementwise_sub_sat(one, three); - // expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}} + // expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}} _BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}} ext = __builtin_elementwise_sub_sat(ext, ext); @@ -184,14 +192,18 @@ void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, u // expected-error@-1 {{arguments are of different types ('unsigned3' (vector of 3 'unsigned int' values) vs 'int3' (vector of 3 'int' values))}} s = __builtin_elementwise_max(i, s); + // expected-error@-1 {{arguments are of different types ('int' vs 'short')}} enum e { one, two }; i = __builtin_elementwise_max(one, two); + i = __builtin_elementwise_max(one, d); + // expected-error@-1 {{arguments are of different types ('int' vs 'double')}} + enum f { three }; enum f x = __builtin_elementwise_max(one, three); - // expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}} + // expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}} _BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}} ext = __builtin_elementwise_max(ext, ext); @@ -240,14 +252,18 @@ void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, u // expected-error@-1 {{arguments are of different types ('unsigned3' (vector of 3 'unsigned int' values) vs 'int3' (vector of 3 'int' values))}} s = __builtin_elementwise_min(i, s); + // expected-error@-1 {{arguments are of different types ('int' vs 'short')}} enum e { one, two }; i = __builtin_elementwise_min(one, two); + i = __builtin_elementwise_min(one, d); + // expected-error@-1 {{arguments are of different types ('int' vs 'double')}} + enum f { three }; enum f x = __builtin_elementwise_min(one, three); - // expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}} + // expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}} _BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}} ext = __builtin_elementwise_min(ext, ext); @@ -273,7 +289,7 @@ void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, u // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was '_Complex float')}} } -void test_builtin_elementwise_maximum(int i, short s, float f, double d, float4 v, int3 iv, unsigned3 uv, int *p) { +void test_builtin_elementwise_maximum(int i, short s, float f, double d, float4 fv, double4 dv, int3 iv, unsigned3 uv, int *p) { i = __builtin_elementwise_maximum(p, d); // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}} @@ -289,15 +305,19 @@ void test_builtin_elementwise_maximum(int i, short s, float f, double d, float4 i = __builtin_elementwise_maximum(i, i, i); // expected-error@-1 {{too many arguments to function call, expected 2, have 3}} - i = __builtin_elementwise_maximum(v, iv); + i = __builtin_elementwise_maximum(fv, iv); // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 'int' values))}} i = __builtin_elementwise_maximum(uv, iv); // expected-error@-1 {{arguments are of different types ('unsigned3' (vector of 3 'unsigned int' values) vs 'int3' (vector of 3 'int' values))}} + dv = __builtin_elementwise_maximum(fv, dv); + // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'double4' (vector of 4 'double' values))}} + d = __builtin_elementwise_maximum(f, d); + // expected-error@-1 {{arguments are of different types ('float' vs 'double')}} - v = __builtin_elementwise_maximum(v, v); + fv = __builtin_elementwise_maximum(fv, fv); i = __builtin_elementwise_maximum(iv, iv); // expected-error@-1 {{1st argument must be a floating point type (was 'int3' (vector of 3 'int' values))}} @@ -314,7 +334,7 @@ void test_builtin_elementwise_maximum(int i, short s, float f, double d, float4 // expected-error@-1 {{1st argument must be a floating point type (was '_Complex float')}} } -void test_builtin_elementwise_minimum(int i, short s, float f, double d, float4 v, int3 iv, unsigned3 uv, int *p) { +void test_builtin_elementwise_minimum(int i, short s, float f, double d, float4 fv, double4 dv, int3 iv, unsigned3 uv, int *p) { i = __builtin_elementwise_minimum(p, d); // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}} @@ -330,15 +350,19 @@ void test_builtin_elementwise_minimum(int i, short s, float f, double d, float4 i = __builtin_elementwise_minimum(i, i, i); // expected-error@-1 {{too many arguments to function call, expected 2, have 3}} - i = __builtin_elementwise_minimum(v, iv); + i = __builtin_elementwise_minimum(fv, iv); // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 'int' values))}} i = __builtin_elementwise_minimum(uv, iv); // expected-error@-1 {{arguments are of different types ('unsigned3' (vector of 3 'unsigned int' values) vs 'int3' (vector of 3 'int' values))}} + dv = __builtin_elementwise_minimum(fv, dv); + // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'double4' (vector of 4 'double' values))}} + d = __builtin_elementwise_minimum(f, d); + // expected-error@-1 {{arguments are of different types ('float' vs 'double')}} - v = __builtin_elementwise_minimum(v, v); + fv = __builtin_elementwise_minimum(fv, fv); i = __builtin_elementwise_minimum(iv, iv); // expected-error@-1 {{1st argument must be a floating point type (was 'int3' (vector of 3 'int' values))}} diff --git a/clang/test/Sema/diagnose_if.c b/clang/test/Sema/diagnose_if.c index 4df39916c031e..e9b8497d5ca4e 100644 --- a/clang/test/Sema/diagnose_if.c +++ b/clang/test/Sema/diagnose_if.c @@ -2,10 +2,10 @@ #define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__))) -void failure1(void) _diagnose_if(); // expected-error{{exactly 3 arguments}} -void failure2(void) _diagnose_if(0); // expected-error{{exactly 3 arguments}} -void failure3(void) _diagnose_if(0, ""); // expected-error{{exactly 3 arguments}} -void failure4(void) _diagnose_if(0, "", "error", 1); // expected-error{{exactly 3 arguments}} +void failure1(void) _diagnose_if(); // expected-error{{at least 3 arguments}} +void failure2(void) _diagnose_if(0); // expected-error{{at least 3 arguments}} +void failure3(void) _diagnose_if(0, ""); // expected-error{{at least 3 arguments}} +void failure4(void) _diagnose_if(0, "", "error", 1); // expected-error{{expected string literal as argument}} void failure5(void) _diagnose_if(0, 0, "error"); // expected-error{{expected string literal as argument of 'diagnose_if' attribute}} void failure6(void) _diagnose_if(0, "", "invalid"); // expected-error{{invalid diagnostic type for 'diagnose_if'; use "error" or "warning" instead}} void failure7(void) _diagnose_if(0, "", "ERROR"); // expected-error{{invalid diagnostic type}} diff --git a/clang/test/Rewriter/missing-dllimport.c b/clang/test/Sema/missing-dllimport.c similarity index 100% rename from clang/test/Rewriter/missing-dllimport.c rename to clang/test/Sema/missing-dllimport.c diff --git a/clang/test/Sema/nullptr-prec2x.c b/clang/test/Sema/nullptr-prec2x.c index 39479d4343a56..c516c448ca1ab 100644 --- a/clang/test/Sema/nullptr-prec2x.c +++ b/clang/test/Sema/nullptr-prec2x.c @@ -6,3 +6,7 @@ int nullptr; // expected-warning {{'nullptr' is a keyword in C23}} nullptr_t val; // expected-error {{unknown type name 'nullptr_t'}} +void foo(void *); +void bar() { foo(__nullptr); } // Test that it converts properly to an arbitrary pointer type without warning +_Static_assert(__nullptr == 0, "value of __nullptr"); // Test that its value matches that of NULL +_Static_assert(_Generic(__typeof(__nullptr), int : 0, void * : 0, default : 1), "type of __nullptr"); // Test that it's type is not the same as what NULL would generally have. diff --git a/clang/test/Sema/nullptr.c b/clang/test/Sema/nullptr.c index d11765a9c881a..b8c371a418e3e 100644 --- a/clang/test/Sema/nullptr.c +++ b/clang/test/Sema/nullptr.c @@ -108,3 +108,10 @@ void test_f1() { int ir = (f1)(nullptr); } +// __nullptr keyword in C +void foo(void *); +void bar() { foo(__nullptr); } +static_assert(nullptr == __nullptr); +static_assert(__nullptr == 0); // Test that its value matches that of NULL +static_assert(_Generic(typeof(__nullptr), nullptr_t: true, default: false)); +static_assert(_Generic(__typeof(__nullptr), int : 0, void * : 0, default : 1)); // Test that it's type is not the same as what NULL would generally have. diff --git a/clang/test/Sema/tautological-pointer-comparison.c b/clang/test/Sema/tautological-pointer-comparison.c index 1c5973b01a30d..f2a944b5305e4 100644 --- a/clang/test/Sema/tautological-pointer-comparison.c +++ b/clang/test/Sema/tautological-pointer-comparison.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -fwrapv -verify=fwrapv %s +// RUN: %clang_cc1 -fsyntax-only -fwrapv-pointer -verify=fwrapv %s // fwrapv-no-diagnostics diff --git a/clang/test/SemaCUDA/device-var-init.cu b/clang/test/SemaCUDA/device-var-init.cu index 1555d151c2590..a9e3557c20ebf 100644 --- a/clang/test/SemaCUDA/device-var-init.cu +++ b/clang/test/SemaCUDA/device-var-init.cu @@ -485,3 +485,12 @@ void instantiate() { bar<<<1, 1>>>(); // expected-note@-1 {{in instantiation of function template specialization 'bar' requested here}} } + +__device__ void *ptr1 = nullptr; +__device__ void *ptr2 = ptr1; +// expected-error@-1 {{dynamic initialization is not supported for __device__, __constant__, __shared__, and __managed__ variables}} + +__device__ [[gnu::constructor(101)]] void ctor() {} +// expected-error@-1 {{CUDA does not support global constructors for __device__ functions}} +__device__ [[gnu::destructor(101)]] void dtor() {} +// expected-error@-1 {{CUDA does not support global destructors for __device__ functions}} diff --git a/clang/test/SemaCUDA/inherited-ctor.cu b/clang/test/SemaCUDA/inherited-ctor.cu index 8ac59e7b539f3..ef3938555b983 100644 --- a/clang/test/SemaCUDA/inherited-ctor.cu +++ b/clang/test/SemaCUDA/inherited-ctor.cu @@ -81,7 +81,7 @@ namespace DefaultCtorInvalid { }; struct C { - struct B b; + struct B b; // expected-note{{default constructed field 'b' declared here}} C() {} // expected-error{{call to implicitly-deleted default constructor of 'struct B'}} // expected-note@-6{{default constructor of 'B' is implicitly deleted because field 's' has a deleted default constructor}} // expected-note@-15{{'S' has been explicitly marked deleted here}} diff --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp index 5189405e23db5..b49d36a6267e6 100644 --- a/clang/test/SemaCXX/alias-template.cpp +++ b/clang/test/SemaCXX/alias-template.cpp @@ -54,18 +54,24 @@ namespace LookupFilter { template using S = S*; // ok } -namespace InFunctions { +namespace UnexpandedPack { template struct S0 { template using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} U u; }; +} +namespace InvalidType { template using T1 = int; template using T2 = int[-1]; // expected-error {{array size is negative}} +} + +namespace ShadowTemplateParam { template struct S3 { // expected-note {{template parameter is declared here}} template using T = int; // expected-error {{declaration of 'T' shadows template parameter}} }; - template using Z = Z; + template // expected-note {{template parameter is declared here}} + using Z = Z; // expected-error {{declaration of 'Z' shadows template parameter}} } namespace ClassNameRedecl { diff --git a/clang/test/SemaCXX/array-type-trait-with-template.cpp b/clang/test/SemaCXX/array-type-trait-with-template.cpp new file mode 100644 index 0000000000000..942714ec5d55a --- /dev/null +++ b/clang/test/SemaCXX/array-type-trait-with-template.cpp @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 -fsyntax-only %s +// RUN: %clang_cc1 -fsyntax-only -std=c++20 -DWITH_AUTO_FUNCTION_PARAMETER=1 %s + +// When __array_rank is used with a template type parameter, this test +// ensures clang considers the final expression could be used with +// static_assert/constexpr. +// +// Although array_extent was handled well, we add it as a precaution. + +template +using remove_reference_t = __remove_reference_t(T); + +template +constexpr int array_rank(T (&lhs)[N]) { + return __array_rank(T[N]); +} + +template + constexpr int array_extent(T (&lhs)[N]) { + return __array_extent(T[N], I); +} + +template +struct Rank { + using ArrayT = remove_reference_t; + + template + static constexpr int call(ArrayT (&lhs)[N]) { + return __array_rank(ArrayT[N]); + } +}; + +template +struct Extent { + using ArrayT = remove_reference_t; + + template + static constexpr int call(ArrayT (&lhs)[N]) { + return __array_extent(ArrayT[N], I); + } +}; + +#ifdef WITH_AUTO_FUNCTION_PARAMETER +template +constexpr int array_rank_auto(auto (&lhs)[N]) { + return __array_rank(remove_reference_t[N]); +} + +template +constexpr int array_extent_auto(auto (&lhs)[N]) { + return __array_extent(remove_reference_t[N], I); +} +#endif + +template +constexpr int array_rank_int(const int (&lhs)[N]) { + return __array_rank(const int[N]); +} + +template +constexpr int array_extent_int(const int (&lhs)[N]) { + return __array_extent(const int[N], I); +} + +template +constexpr int array_rank_int(const int (&lhs)[M][N]) { + return __array_rank(const int[M][N]); +} + +template +constexpr int array_extent_int(const int (&lhs)[M][N]) { + return __array_extent(const int[M][N], I); +} + +int main() { + constexpr int vec[] = {0, 1, 2, 1}; + constexpr int mat[4][4] = { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1} + }; + +#define ATT_TESTS_WITH_ASSERT(ATT_ASSERT) \ + { ATT_ASSERT(RANK(vec) == 1); } \ + { ATT_ASSERT(RANK(mat) == 2); } \ + { ATT_ASSERT(EXTENT(vec, 0) == 4); } \ + { ATT_ASSERT(EXTENT(vec, 1) == 0); } \ + { ATT_ASSERT(EXTENT(mat, 1) == 4); } + +#define ATT_TESTS() \ + ATT_TESTS_WITH_ASSERT( constexpr bool cst = ) \ + ATT_TESTS_WITH_ASSERT( (void) ) \ + ATT_TESTS_WITH_ASSERT( static_assert ) + + { +#define RANK(lhs) array_rank(lhs) +#define EXTENT(lhs, i) array_extent(lhs) + ATT_TESTS(); +#undef RANK +#undef EXTENT + } + + { +#define RANK(lhs) Rank::call(lhs) +#define EXTENT(lhs, i) Extent::call(lhs) + ATT_TESTS(); +#undef RANK +#undef EXTENT + } + +#ifdef WITH_AUTO_FUNCTION_PARAMETER + { +#define RANK(lhs) array_rank_auto(lhs) +#define EXTENT(lhs, i) array_extent_auto(lhs) + ATT_TESTS(); +#undef RANK +#undef EXTENT + } +#endif + + { +#define RANK(lhs) array_rank_int(lhs) +#define EXTENT(lhs, i) array_extent_int(lhs) + ATT_TESTS(); +#undef RANK +#undef EXTENT + } +} diff --git a/clang/test/SemaCXX/attr-annotate.cpp b/clang/test/SemaCXX/attr-annotate.cpp index 846ef4119f1d7..ff538fee9cb3c 100644 --- a/clang/test/SemaCXX/attr-annotate.cpp +++ b/clang/test/SemaCXX/attr-annotate.cpp @@ -134,3 +134,7 @@ constexpr int foldable_but_invalid() { template [[clang::annotate()]] void f2() {} // expected-error@-1 {{'annotate' attribute takes at least 1 argument}} } + +namespace test5 { + void bir [[clang::annotate("B", (void)1)]] (); +} diff --git a/clang/test/SemaCXX/attr-cxx0x.cpp b/clang/test/SemaCXX/attr-cxx0x.cpp index 4d64d2b0cd8c6..58180a21ca8e9 100644 --- a/clang/test/SemaCXX/attr-cxx0x.cpp +++ b/clang/test/SemaCXX/attr-cxx0x.cpp @@ -53,3 +53,26 @@ alignas(4) auto PR19252 = 0; // Check the diagnostic message class alignas(void) AlignasVoid {}; // expected-error {{invalid application of 'alignas' to an incomplete type 'void'}} + +namespace GH108819 { +void a([[maybe_unused]] void) {} // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}}\ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +void b([[deprecated, maybe_unused]] void) {} // expected-warning {{attribute 'deprecated' cannot be applied to a 'void' parameter}} \ + // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'deprecated' attribute is a C++14 extension}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +void c([[clang::lifetimebound]] void) {} // expected-warning {{attribute 'lifetimebound' cannot be applied to a 'void' parameter}} +void d([[clang::annotate("a", "b", 1)]] void) {} // expected-warning {{attribute 'annotate' cannot be applied to a 'void' parameter}} + +struct S { + void e([[maybe_unused]] void) {} // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +}; + +template +void f([[maybe_unused]] void) {} // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} + +auto g = []([[maybe_unused]] void) { }; // expected-warning {{attribute 'maybe_unused' cannot be applied to a 'void' parameter}} \ + // expected-warning {{use of the 'maybe_unused' attribute is a C++17 extension}} +} diff --git a/clang/test/SemaCXX/attr-no-sanitize.cpp b/clang/test/SemaCXX/attr-no-sanitize.cpp index 8951f616ce0f0..cd60e71963ac3 100644 --- a/clang/test/SemaCXX/attr-no-sanitize.cpp +++ b/clang/test/SemaCXX/attr-no-sanitize.cpp @@ -21,8 +21,8 @@ int f3() __attribute__((no_sanitize("address"))); // DUMP-LABEL: FunctionDecl {{.*}} f4 // DUMP: NoSanitizeAttr {{.*}} hwaddress -// PRINT: {{\[\[}}clang::no_sanitize("hwaddress")]] int f4() -[[clang::no_sanitize("hwaddress")]] int f4(); +// PRINT: {{\[\[}}gnu::no_sanitize("hwaddress")]] int f4() +[[gnu::no_sanitize("hwaddress")]] int f4(); // DUMP-LABEL: FunctionDecl {{.*}} f5 // DUMP: NoSanitizeAttr {{.*}} address thread hwaddress diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index a1234b67acd6d..76e2f81947051 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1462,7 +1462,7 @@ namespace InstantiateCaseStmt { namespace ConvertedConstantExpr { extern int &m; - extern int &n; // expected-note 2{{declared here}} + extern int &n; // pre-cxx23-note 2{{declared here}} constexpr int k = 4; int &m = const_cast(k); @@ -1471,9 +1471,9 @@ namespace ConvertedConstantExpr { // useless note and instead just point to the non-constant subexpression. enum class E { em = m, - en = n, // cxx23-note {{initializer of 'n' is not a constant expression}} expected-error {{enumerator value is not a constant expression}} cxx11_20-note {{initializer of 'n' is unknown}} - eo = (m + // expected-error {{not a constant expression}} - n // cxx23-note {{initializer of 'n' is not a constant expression}} cxx11_20-note {{initializer of 'n' is unknown}} + en = n, // expected-error {{enumerator value is not a constant expression}} cxx11_20-note {{initializer of 'n' is unknown}} + eo = (m + // pre-cxx23-error {{not a constant expression}} + n // cxx11_20-note {{initializer of 'n' is unknown}} cxx23-error {{not a constant expression}} ), eq = reinterpret_cast((int*)0) // expected-error {{not a constant expression}} expected-note {{reinterpret_cast}} }; diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp b/clang/test/SemaCXX/constant-expression-p2280r4.cpp index 0f85c60629eed..65e5e6b34b48f 100644 --- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp +++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++23 -verify %s +// RUN: %clang_cc1 -std=c++23 -verify %s -fexperimental-new-constant-interpreter using size_t = decltype(sizeof(0)); @@ -47,11 +48,10 @@ void splash(Swim& swam) { } extern Swim dc; -extern Swim& trident; // expected-note {{declared here}} +extern Swim& trident; constexpr auto& sandeno = typeid(dc); // ok: can only be typeid(Swim) constexpr auto& gallagher = typeid(trident); // expected-error {{constexpr variable 'gallagher' must be initialized by a constant expression}} - // expected-note@-1 {{initializer of 'trident' is not a constant expression}} namespace explicitThis { struct C { diff --git a/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp b/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp index 6a1f48bf7958f..0c20dd9dc58c6 100644 --- a/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp +++ b/clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp @@ -349,3 +349,27 @@ static_assert(OtherCaptures(), ""); } // namespace PR36054 #endif // ndef CPP14_AND_EARLIER + + +#if __cpp_constexpr >= 201907L +namespace GH114234 { +template +auto g() { return Arg; } + +template +auto f() { + []() { + g<[] { return 123; }()>(); + }.template operator()(); +} + +void test() { f(); } +} + +namespace GH97958 { +static_assert( + []() -> decltype([]{ return true; }) + { return {}; }()()); +} + +#endif diff --git a/clang/test/SemaCXX/cxx1z-decomposition.cpp b/clang/test/SemaCXX/cxx1z-decomposition.cpp index a8914fe4e9cd8..95c64bc3b8bff 100644 --- a/clang/test/SemaCXX/cxx1z-decomposition.cpp +++ b/clang/test/SemaCXX/cxx1z-decomposition.cpp @@ -200,38 +200,32 @@ namespace lambdas { namespace by_value_array_copy { struct explicit_copy { - explicit_copy() = default; // expected-note 2{{candidate constructor not viable: requires 0 arguments, but 1 was provided}} - explicit explicit_copy(const explicit_copy&) = default; // expected-note 2{{explicit constructor is not a candidate}} + explicit_copy() = default; // expected-note {{candidate constructor not viable: requires 0 arguments, but 1 was provided}} + explicit explicit_copy(const explicit_copy&) = default; // expected-note {{explicit constructor is not a candidate}} }; - constexpr int direct_initialization_for_elements() { - explicit_copy ec_arr[2]; - auto [a1, b1](ec_arr); + constexpr int simple_array_elements() { + int arr[2]{1, 2}; - int arr[3]{1, 2, 3}; - auto [a2, b2, c2](arr); - arr[0]--; - return a2 + b2 + c2 + arr[0]; - } - static_assert(direct_initialization_for_elements() == 6); + auto [a1, a2] = arr; + auto [b1, b2](arr); + auto [c1, c2]{arr}; // GH31813 - constexpr int copy_initialization_for_elements() { - int arr[2]{4, 5}; - auto [a1, b1] = arr; - auto [a2, b2]{arr}; // GH31813 arr[0] = 0; - return a1 + b1 + a2 + b2 + arr[0]; + return arr[0] + a1 + a2 + b1 + b2 + c1 + c2; } - static_assert(copy_initialization_for_elements() == 18); + static_assert(simple_array_elements() == 9); + + void explicit_copy_ctor_array_elements() { + explicit_copy ec_arr[1]; - void copy_initialization_for_elements_with_explicit_copy_ctor() { - explicit_copy ec_arr[2]; - auto [a1, b1] = ec_arr; // expected-error {{no matching constructor for initialization of 'explicit_copy[2]'}} - auto [a2, b2]{ec_arr}; // expected-error {{no matching constructor for initialization of 'explicit_copy[2]'}} + auto [a] = ec_arr; // expected-error {{no matching constructor for initialization of 'explicit_copy[1]'}} + auto [b](ec_arr); + auto [c]{ec_arr}; // Test prvalue - using T = explicit_copy[2]; - auto [a3, b3] = T{}; - auto [a4, b4]{T{}}; + using T = explicit_copy[1]; + auto [d] = T{}; } + } // namespace by_value_array_copy diff --git a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp index 2d43e46b9e3d7..37dca2215af6b 100644 --- a/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp +++ b/clang/test/SemaCXX/cxx20-ctad-type-alias.cpp @@ -234,11 +234,23 @@ int i = 0; AFoo s{i}; static_assert(__is_same(decltype(s.t), int)); +template +using BFoo = AFoo; + +// template explicit deduction guide. +template +Foo(T) -> Foo; +static_assert(__is_same(decltype(AFoo(i).t), float)); +static_assert(__is_same(decltype(BFoo(i).t), float)); + // explicit deduction guide. Foo(int) -> Foo; -AFoo s2{i}; -// FIXME: the type should be X because of the above explicit deduction guide. -static_assert(__is_same(decltype(s2.t), int)); +static_assert(__is_same(decltype(AFoo(i).t), X)); +static_assert(__is_same(decltype(BFoo(i).t), X)); + +Foo(double) -> Foo; +static_assert(__is_same(decltype(AFoo(1.0).t), int)); +static_assert(__is_same(decltype(BFoo(1.0).t), int)); } // namespace test16 namespace test17 { diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp index 3f3123eaee76b..dd5063cb29c5b 100644 --- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp +++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp @@ -528,3 +528,51 @@ D d(0); // expected-note {{in implicit initialization for inherited constructor // expected-error@-1 {{call to immediate function 'GH112677::D::SimpleCtor' is not a constant expression}} } + +namespace GH123405 { + +consteval void fn() {} + +template +constexpr auto tfn(int) { + auto p = &fn; // expected-note {{'tfn' is an immediate function because its body evaluates the address of a consteval function 'fn'}} + return p; +} + +void g() { + int a; // expected-note {{declared here}} + tfn(a); // expected-error {{call to immediate function 'GH123405::tfn' is not a constant expression}}\ + // expected-note {{read of non-const variable 'a' is not allowed in a constant expression}} +} +} // namespace GH123405 + +namespace GH118000 { +consteval int baz() { return 0;} +struct S { + int mSize = baz(); +}; + +consteval void bar() { + S s; +} + +void foo() { + S s; +} +} // namespace GH118000 + +namespace GH119046 { + +template constexpr auto tfn(int) { + return (unsigned long long)(&Cls::sfn); + //expected-note@-1 {{'tfn' is an immediate function because its body evaluates the address of a consteval function 'sfn'}} +}; +struct S { static consteval void sfn() {} }; + +int f() { + int a = 0; // expected-note{{declared here}} + return tfn(a); + //expected-error@-1 {{call to immediate function 'GH119046::tfn' is not a constant expression}} + //expected-note@-2 {{read of non-const variable 'a' is not allowed in a constant expression}} +} +} diff --git a/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp b/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp new file mode 100644 index 0000000000000..ea94757dc66b6 --- /dev/null +++ b/clang/test/SemaCXX/cxx2c-binding-pack-nontemplate.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -std=c++26 -fsyntax-only %s -verify=nontemplate +// RUN: %clang_cc1 -std=c++2c -verify=cxx26,nontemplate -fsyntax-only -Wpre-c++26-compat %s +// RUN: %clang_cc1 -std=c++23 -verify=cxx23,nontemplate -fsyntax-only -Wc++26-extensions %s + +void decompose_array() { + int arr[4] = {1, 2, 3, 6}; + // cxx26-warning@+3 {{structured binding packs are incompatible with C++ standards before C++2c}} + // cxx23-warning@+2 {{structured binding packs are a C++2c extension}} + // nontemplate-error@+1 {{pack declaration outside of template}} + auto [x, ...rest, y] = arr; +} diff --git a/clang/test/SemaCXX/cxx2c-binding-pack.cpp b/clang/test/SemaCXX/cxx2c-binding-pack.cpp new file mode 100644 index 0000000000000..5ca249f52b3d8 --- /dev/null +++ b/clang/test/SemaCXX/cxx2c-binding-pack.cpp @@ -0,0 +1,190 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++26 %s -verify + +template +struct type_ { }; + +template +auto sum(T... t) { return (t + ...); } + +struct my_struct { + int a; + int b; + int c; + int d; +}; + +struct fake_tuple { + int arr[4] = {1, 2, 3, 6}; + + template + int get() { + return arr[i]; + } +}; + +namespace std { + template + struct tuple_size; + template + struct tuple_element; + + template <> + struct tuple_size { + static constexpr unsigned value = 4; + }; + + template + struct tuple_element { + using type = int; + }; +} + + +template +void decompose_tuple() { + auto tup = T{{1, 2, 3, 6}}; + auto&& [x, ...rest, y] = tup; + + ((void)type_(type_{}), ...); + + T arrtup[2] = {T{{1, 2, 3, 6}}, + T{{7, 9, 10, 11}}}; + int sum = 0; + for (auto [...xs] : arrtup) { + sum += (xs + ...); + } +} + +template +void decompose_struct() { + T obj{1, 2, 3, 6}; + auto [x, ...rest, y] = obj; + + auto [...empty] = type_{}; + static_assert(sizeof...(empty) == 0); +} + +template +void decompose_array() { + int arr[4] = {1, 2, 3, 6}; + auto [x, ...rest, y] = arr; + + static_assert(sizeof...(rest) == 2); + int size = sizeof...(rest); + T arr2[sizeof...(rest)] = {rest...}; + auto [...pack] = arr2; + + // Array of size 1. + int arr1[1] = {1}; + auto [a, ...b] = arr1; + static_assert(sizeof...(b) == 0); + auto [...c] = arr1; + static_assert(sizeof...(c) == 1); + auto [a1, ...b1, c1] = arr1; // expected-error{{decomposes into 1 element, but 3 names were provided}} +} + +// Test case by Younan Zhang. +template +struct S { + template + struct N { + void foo() { + int arr[] = {P..., Q...}; + auto [x, y, ...rest] = arr; + [&]() { + static_assert(sizeof...(rest) + 2 == sizeof...(P) + sizeof...(Q)); + }(); + } + }; +}; + +struct bit_fields { + int a : 4 {1}; + int b : 4 {2}; + int c : 4 {3}; + int d : 4 {4}; +}; + +template +void decompose_bit_field() { + auto [...x] = T{}; + static_assert(sizeof...(x) == 4); + int a = x...[0]; + int b = x...[1]; + int c = x...[2]; + int d = x...[3]; +} + +template +void lambda_capture() { + auto [...x] = T{}; + [=] { (void)sum(x...); }(); + [&] { (void)sum(x...); }(); + [x...] { (void)sum(x...); }(); + [&x...] { (void)sum(x...); }(); +} + +int main() { + decompose_array(); + decompose_tuple(); + decompose_struct(); + S<1, 2, 3, 4>::N<5, 6>().foo(); + decompose_bit_field(); + lambda_capture(); + lambda_capture(); + lambda_capture(); +} + +// P1061R10 Stuff +namespace { +struct C { int x, y, z; }; + +template +void now_i_know_my() { + auto [a, b, c] = C(); // OK, SB0 is a, SB1 is b, and SB2 is c + auto [d, ...e] = C(); // OK, SB0 is d, the pack e (v1) contains two structured bindings: SB1 and SB2 + static_assert(sizeof...(e) == 2); + auto [...f, g] = C(); // OK, the pack f (v0) contains two structured bindings: SB0 and SB1, and SB2 is g + static_assert(sizeof...(e) == 2); + auto [h, i, j, ...k] = C(); // OK, the pack k is empty + static_assert(sizeof...(e) == 0); + auto [l, m, n, o, ...p] = C(); // expected-error{{{decomposes into 3 elements, but 5 names were provided}}} +} +} // namespace + +namespace { +auto g() -> int(&)[4]; + +template +void h(int (&arr)[N]) { + auto [a, ...b, c] = arr; // a names the first element of the array, + // b is a pack referring to the second and + // third elements, and c names the fourth element + static_assert(sizeof...(b) == 2); + auto& [...e] = arr; // e is a pack referring to the four elements of the array + static_assert(sizeof...(e) == 4); +} + +void call_h() { + h(g()); +} +} // namespace + +namespace { +struct D { }; + +int g(...) { return 1; } + +template +constexpr int f() { + D arr[1]; + auto [...e] = arr; + return g(e...); +} + +constexpr int g(D) { return 2; } + +void other_main() { + static_assert(f() == 2); +} +} // namespace diff --git a/clang/test/SemaCXX/diagnose_if-warning-group.cpp b/clang/test/SemaCXX/diagnose_if-warning-group.cpp new file mode 100644 index 0000000000000..a39c0c0c33c9e --- /dev/null +++ b/clang/test/SemaCXX/diagnose_if-warning-group.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 %s -verify=expected,wall -fno-builtin -Wno-pedantic -Werror=comment -Wno-error=abi -Wfatal-errors=assume -Wno-fatal-errors=assume -Wno-format +// RUN: %clang_cc1 %s -verify=expected,wno-all,pedantic,format -fno-builtin -Wno-all -Werror=comment -Wno-error=abi -Werror=assume -Wformat + +#define diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__))) + +#ifndef EMTY_WARNING_GROUP +void bougus_warning() diagnose_if(true, "oh no", "warning", "bogus warning") {} // expected-error {{unknown warning group 'bogus warning'}} + +void show_in_system_header() diagnose_if(true, "oh no", "warning", "assume", "Banane") {} // expected-error {{'diagnose_if' attribute takes no more than 4 arguments}} +#endif // EMTY_WARNING_GROUP + +template +void diagnose_if_wcomma() diagnose_if(b, "oh no", "warning", "comma") {} + +template +void diagnose_if_wcomment() diagnose_if(b, "oh no", "warning", "comment") {} + +void empty_warning_group() diagnose_if(true, "oh no", "warning", "") {} // expected-error {{unknown warning group ''}} +void empty_warning_group_error() diagnose_if(true, "oh no", "error", "") {} // expected-error {{unknown warning group ''}} + +void diagnose_if_wabi_default_error() diagnose_if(true, "ABI stuff", "error", "abi") {} +void diagnose_assume() diagnose_if(true, "Assume diagnostic", "warning", "assume") {} + +void Wall() diagnose_if(true, "oh no", "warning", "all") {} +void Wpedantic() diagnose_if(true, "oh no", "warning", "pedantic") {} +void Wformat_extra_args() diagnose_if(true, "oh no", "warning", "format-extra-args") {} + +void call() { + diagnose_if_wcomma(); // expected-warning {{oh no}} + diagnose_if_wcomma(); + diagnose_if_wcomment(); // expected-error {{oh no}} + diagnose_if_wcomment(); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcomma" + diagnose_if_wcomma(); + diagnose_if_wcomment(); // expected-error {{oh no}} +#pragma clang diagnostic pop + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcomment" + diagnose_if_wcomma(); // expected-warning {{oh no}} + diagnose_if_wcomment(); +#pragma clang diagnostic pop + + diagnose_if_wcomma(); // expected-warning {{oh no}} + diagnose_if_wcomment(); // expected-error {{oh no}} + + diagnose_if_wabi_default_error(); // expected-warning {{ABI stuff}} + diagnose_assume(); // expected-error {{Assume diagnostic}} + + // Make sure that the -Wassume diagnostic isn't fatal + diagnose_if_wabi_default_error(); // expected-warning {{ABI stuff}} + + Wall(); // wall-warning {{oh no}} + Wpedantic(); // pedantic-warning {{oh no}} + Wformat_extra_args(); // format-warning {{oh no}} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat" + Wformat_extra_args(); +#pragma clang diagnostic pop +} diff --git a/clang/test/SemaCXX/member-enum-declarations.cpp b/clang/test/SemaCXX/member-enum-declarations.cpp new file mode 100644 index 0000000000000..e08f6e7a3fcd6 --- /dev/null +++ b/clang/test/SemaCXX/member-enum-declarations.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s -verify +// RUN: %clang_cc1 -std=c++14 -fsyntax-only %s -verify +// RUN: %clang_cc1 -std=c++20 -fsyntax-only %s -verify + + +namespace ScopedEnumerations { + +template +struct S1 { + enum class E : T; +}; + +template +enum class S1::E : T { + S1_X = 0x123 +}; + +static_assert(static_cast(S1::E::S1_X) == 0x123, ""); + +template +struct S2 { + static constexpr T f(int) { return 0; }; + enum class E : T; + static constexpr T f(char) { return 1; }; + enum class E : T { X = f(T{}) }; +}; + +static_assert(static_cast(S2::E::X) == 1, ""); + +template +struct S3 { + enum class E : T; + enum class E : T { X = 0x7FFFFF00 }; // expected-error {{cannot be narrowed to type 'char'}} expected-warning {{implicit conversion from 'int' to 'char'}} +}; +template struct S3; // expected-note {{in instantiation}} + +template +struct S4 { + enum class E : T; + enum class E : T { S4_X = 5 }; +}; + +auto x4 = S4::E::S4_X; + +template +T f1() { + enum class E : T { X_F1, Y_F1, Z_F1 }; + return X_F1; // expected-error {{use of undeclared identifier 'X_F1'}} +} + +const int resf1 = f1(); + +} + + +namespace UnscopedEnumerations { + +template +struct S1 { + enum E : T; +}; + +template +enum S1::E : T { + S1_X = 0x123 +}; + +static_assert(static_cast(S1::S1_X) == 0x123, ""); + +template +struct S2 { + static constexpr T f(int) { return 0; }; + enum E : T; + static constexpr T f(char) { return 1; }; + enum E : T { S2_X = f(T{}) }; +}; + +static_assert(static_cast(S2::E::S2_X) == 1, ""); + +template +struct S3 { + enum E : T; + enum E : T { S3_X = 0x7FFFFF00 }; // expected-error {{cannot be narrowed to type 'char'}} expected-warning {{implicit conversion from 'int' to 'char'}} +}; +template struct S3; // expected-note {{in instantiation of template class}} + +template +struct S4 { + enum E : T; + enum E : T { S4_X = 5 }; +}; + +auto x4 = S4::S4_X; + +template +struct S5 { + enum E : T; + T S5_X = 5; // expected-note {{previous definition is here}} + enum E : T { S5_X = 5 }; // expected-error {{redefinition of 'S5_X'}} +}; + + +template +T f1() { + enum E : T { X_F2, Y_F2, Z_F2 }; + return X_F2; +} + +const int resf1 = f1(); + +} + diff --git a/clang/test/SemaCXX/remove_pointer.mm b/clang/test/SemaCXX/remove_pointer.mm deleted file mode 100644 index d1cf1fa9f4efc..0000000000000 --- a/clang/test/SemaCXX/remove_pointer.mm +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -// expected-no-diagnostics - -@class X; - -static_assert(__is_same(__remove_pointer(X *), X), ""); -static_assert(__is_same(__remove_pointer(id), id), ""); diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index 1b9e2ba6ff162..b130024503101 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -779,36 +779,6 @@ void is_unbounded_array(int n) { (void)__is_unbounded_array(decltype(t32)); // expected-error{{variable length arrays are not supported in '__is_unbounded_array'}} } -void is_referenceable() { - static_assert(__is_referenceable(int)); - static_assert(__is_referenceable(const int)); - static_assert(__is_referenceable(volatile int)); - static_assert(__is_referenceable(const volatile int)); - static_assert(__is_referenceable(int *)); - static_assert(__is_referenceable(int &)); - static_assert(__is_referenceable(int &&)); - static_assert(__is_referenceable(int (*)())); - static_assert(__is_referenceable(int (&)())); - static_assert(__is_referenceable(int(&&)())); - static_assert(__is_referenceable(IntAr)); - static_assert(__is_referenceable(IntArNB)); - static_assert(__is_referenceable(decltype(nullptr))); - static_assert(__is_referenceable(Empty)); - static_assert(__is_referenceable(Union)); - static_assert(__is_referenceable(Derives)); - static_assert(__is_referenceable(Enum)); - static_assert(__is_referenceable(EnumClass)); - static_assert(__is_referenceable(int Empty::*)); - static_assert(__is_referenceable(int(Empty::*)())); - static_assert(__is_referenceable(AnIncompleteType)); - static_assert(__is_referenceable(struct AnIncompleteType)); - - using function_type = void(int); - static_assert(__is_referenceable(function_type)); - - static_assert(!__is_referenceable(void)); -} - template void tmpl_func(T&) {} template struct type_wrapper { @@ -4739,8 +4709,6 @@ struct CheckAbominableFunction { static_assert(__is_same(remove_cvref_t, M)); static_assert(__is_same(remove_pointer_t, M)); static_assert(__is_same(remove_reference_t, M)); - - static_assert(!__is_referenceable(M)); } }; diff --git a/clang/test/SemaCXX/uninitialized.cpp b/clang/test/SemaCXX/uninitialized.cpp index 52d9897cf9be6..4af2c998f082e 100644 --- a/clang/test/SemaCXX/uninitialized.cpp +++ b/clang/test/SemaCXX/uninitialized.cpp @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -fsyntax-only -Wall -Wc++20-compat -Wuninitialized -Wno-unused-value -Wno-unused-lambda-capture -Wno-uninitialized-const-reference -std=c++1z -verify %s -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -fsyntax-only -Wall -Wc++20-compat -Wuninitialized -Wno-unused-value -Wno-unused-lambda-capture -Wno-uninitialized-const-reference -std=c++20 -verify %s +void* operator new(__SIZE_TYPE__, void*); + // definitions for std::move namespace std { inline namespace foo { @@ -1540,6 +1542,80 @@ void aggregate() { }; }; + struct CopyAndMove { + CopyAndMove() = default; + CopyAndMove(const CopyAndMove &) {} + CopyAndMove(CopyAndMove &&) {} + }; + struct Embed { + int embed1; // #FIELD_EMBED1 + int embed2 [[clang::require_explicit_initialization]]; // #FIELD_EMBED2 + CopyAndMove force_separate_move_ctor; + }; + struct EmbedDerived : Embed {}; + struct F { + Embed f1; + // expected-warning@+1 {{field in 'Embed' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + explicit F(const char(&)[1]) : f1() { + // expected-warning@+1 {{field in 'Embed' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + ::new(static_cast(&f1)) decltype(f1); + // expected-warning@+1 {{field in 'Embed' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + ::new(static_cast(&f1)) decltype(f1)(); +#if __cplusplus >= 202002L + // expected-warning@+1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + ::new(static_cast(&f1)) decltype(f1)(1); +#endif + // expected-warning@+1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + ::new(static_cast(&f1)) decltype(f1){1}; + } +#if __cplusplus >= 202002L + // expected-warning@+1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + explicit F(const char(&)[2]) : f1(1) {} +#else + explicit F(const char(&)[2]) : f1{1, 2} { } +#endif + // expected-warning@+1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + explicit F(const char(&)[3]) : f1{} {} + // expected-warning@+1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + explicit F(const char(&)[4]) : f1{1} {} + // expected-warning@+1 {{field 'embed2' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_EMBED2 {{'embed2' declared here}} + explicit F(const char(&)[5]) : f1{.embed1 = 1} {} + }; + F ctors[] = { + F(""), + F("_"), + F("__"), + F("___"), + F("____") + }; + + struct MoveOrCopy { + Embed e; + EmbedDerived ed; + F f; + // no-error + MoveOrCopy(const MoveOrCopy &c) : e(c.e), ed(c.ed), f(c.f) {} + // no-error + MoveOrCopy(MoveOrCopy &&c) + : e(std::move(c.e)), ed(std::move(c.ed)), f(std::move(c.f)) {} + }; + F copy1(ctors[0]); // no-error + (void)copy1; + F move1(std::move(ctors[0])); // no-error + (void)move1; + F copy2{ctors[0]}; // no-error + (void)copy2; + F move2{std::move(ctors[0])}; // no-error + (void)move2; + F copy3 = ctors[0]; // no-error + (void)copy3; + F move3 = std::move(ctors[0]); // no-error + (void)move3; + F copy4 = {ctors[0]}; // no-error + (void)copy4; + F move4 = {std::move(ctors[0])}; // no-error + (void)move4; + S::foo(S{1, 2, 3, 4}); S::foo(S{.s1 = 100, .s4 = 100}); S::foo(S{.s1 = 100}); // expected-warning {{field 's4' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_S4 {{'s4' declared here}} diff --git a/clang/test/SemaCXX/unique_object_duplication.cpp b/clang/test/SemaCXX/unique_object_duplication.cpp new file mode 100644 index 0000000000000..4b41bfbfdc2f7 --- /dev/null +++ b/clang/test/SemaCXX/unique_object_duplication.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=hidden -Wunique-object-duplication -fvisibility=hidden -Wno-unused-value %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wunique-object-duplication -Wno-unused-value %s +// The check is currently disabled on windows in MSVC-like environments. The test should fail because we're not getting the expected warnings. +// XFAIL: target={{.*}}-windows-msvc, {{.*}}-ps{{(4|5)(-.+)?}} + +#include "unique_object_duplication.h" + +// Everything in these namespaces here is defined in the cpp file, +// so won't get duplicated + +namespace GlobalTest { + float Test::allowedStaticMember1 = 2.3; +} + +bool disallowed4 = true; +constexpr inline bool disallowed5 = true; \ No newline at end of file diff --git a/clang/test/SemaCXX/unique_object_duplication.h b/clang/test/SemaCXX/unique_object_duplication.h new file mode 100644 index 0000000000000..5b2002c31be7c --- /dev/null +++ b/clang/test/SemaCXX/unique_object_duplication.h @@ -0,0 +1,157 @@ +/** + * This file contains tests for the -Wunique_object_duplication warning. + * See the warning's documentation for more information. + */ + +#define HIDDEN __attribute__((visibility("hidden"))) +#define DEFAULT __attribute__((visibility("default"))) + +// Helper functions +constexpr int init_constexpr(int x) { return x; }; +extern double init_dynamic(int); + +/****************************************************************************** + * Case one: Static local variables in an externally-visible function + ******************************************************************************/ +namespace StaticLocalTest { + +inline void has_static_locals_external() { + // Mutable + static int disallowedStatic1 = 0; // hidden-warning {{'disallowedStatic1' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + // Initialization might run more than once + static const double disallowedStatic2 = disallowedStatic1++; // hidden-warning {{initializeation of 'disallowedStatic2' may run twice when built into a shared library: it has hidden visibility and external linkage}} + + // OK, because immutable and compile-time-initialized + static constexpr int allowedStatic1 = 0; + static const float allowedStatic2 = 1; + static constexpr int allowedStatic3 = init_constexpr(2); + static const int allowedStatic4 = init_constexpr(3); +} + +// Don't warn for non-inline functions, since they can't (legally) appear +// in more than one TU in the first place. +void has_static_locals_non_inline() { + // Mutable + static int allowedStatic1 = 0; + // Initialization might run more than once + static const double allowedStatic2 = allowedStatic1++; +} + +// Everything in this function is OK because the function is TU-local +static void has_static_locals_internal() { + static int allowedStatic1 = 0; + static double allowedStatic2 = init_dynamic(2); + static char allowedStatic3 = []() { return allowedStatic1++; }(); + static constexpr int allowedStatic4 = 0; +} + +namespace { + +// Everything in this function is OK because the function is also TU-local +void has_static_locals_anon() { + static int allowedStatic1 = 0; + static double allowedStatic2 = init_dynamic(2); + static char allowedStatic3 = []() { return allowedStatic1++; }(); + static constexpr int allowedStatic4 = init_constexpr(3); +} + +} // Anonymous namespace + +HIDDEN inline void static_local_always_hidden() { + static int disallowedStatic1 = 3; // hidden-warning {{'disallowedStatic1' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + // expected-warning@-1 {{'disallowedStatic1' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + { + static int disallowedStatic2 = 3; // hidden-warning {{'disallowedStatic2' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + // expected-warning@-1 {{'disallowedStatic2' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + } + + auto lmb = []() { + static int disallowedStatic3 = 3; // hidden-warning {{'disallowedStatic3' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + // expected-warning@-1 {{'disallowedStatic3' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + }; +} + +DEFAULT void static_local_never_hidden() { + static int allowedStatic1 = 3; + + { + static int allowedStatic2 = 3; + } + + auto lmb = []() { + static int allowedStatic3 = 3; + }; +} + +// Don't warn on this because it's not in a function +const int setByLambda = ([]() { static int x = 3; return x++; })(); + +inline void has_extern_local() { + extern int allowedAddressExtern; // Not a definition +} + +inline void has_regular_local() { + int allowedAddressLocal = 0; +} + +inline void has_thread_local() { + // thread_local variables are static by default + thread_local int disallowedThreadLocal = 0; // hidden-warning {{'disallowedThreadLocal' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} +} + +} // namespace StaticLocalTest + +/****************************************************************************** + * Case two: Globals with external linkage + ******************************************************************************/ +namespace GlobalTest { + // Mutable + inline float disallowedGlobal1 = 3.14; // hidden-warning {{'disallowedGlobal1' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + + // Initialization might run more than once + inline const double disallowedGlobal5 = disallowedGlobal1++; // hidden-warning {{initializeation of 'disallowedGlobal5' may run twice when built into a shared library: it has hidden visibility and external linkage}} + + // OK because internal linkage, so duplication is intended + static float allowedGlobal1 = 3.14; + const double allowedGlobal2 = init_dynamic(2); + static const char allowedGlobal3 = []() { return disallowedGlobal1++; }(); + static inline double allowedGlobal4 = init_dynamic(2); + + // OK, because immutable and compile-time-initialized + constexpr int allowedGlobal5 = 0; + const float allowedGlobal6 = 1; + constexpr int allowedGlobal7 = init_constexpr(2); + const int allowedGlobal8 = init_constexpr(3); + + // We don't warn on this because non-inline variables can't (legally) appear + // in more than one TU. + float allowedGlobal9 = 3.14; + + // Pointers need to be double-const-qualified + inline float& nonConstReference = disallowedGlobal1; // hidden-warning {{'nonConstReference' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + const inline int& constReference = allowedGlobal5; + + inline int* nonConstPointerToNonConst = nullptr; // hidden-warning {{'nonConstPointerToNonConst' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + inline int const* nonConstPointerToConst = nullptr; // hidden-warning {{'nonConstPointerToConst' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + inline int* const constPointerToNonConst = nullptr; // hidden-warning {{'constPointerToNonConst' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + inline int const* const constPointerToConst = nullptr; + // Don't warn on new because it tends to generate false positives + inline int const* const constPointerToConstNew = new int(7); + + inline int const * const * const * const nestedConstPointer = nullptr; + inline int const * const ** const * const nestedNonConstPointer = nullptr; // hidden-warning {{'nestedNonConstPointer' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + + struct Test { + static inline float disallowedStaticMember1; // hidden-warning {{'disallowedStaticMember1' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} + // Defined below, in the header file + static float disallowedStaticMember2; + // Defined in the cpp file, so won't get duplicated + static float allowedStaticMember1; + + // Tests here are sparse because the AddrTest case below will define plenty + // more, which aren't problematic to define (because they're immutable), but + // may still cause problems if their address is taken. + }; + + inline float Test::disallowedStaticMember2 = 2.3; // hidden-warning {{'disallowedStaticMember2' may be duplicated when built into a shared library: it is mutable, has hidden visibility, and external linkage}} +} // namespace GlobalTest \ No newline at end of file diff --git a/clang/test/SemaCXX/warn-base-type-qualifiers.cpp b/clang/test/SemaCXX/warn-base-type-qualifiers.cpp index b9fd577c574b9..7c775a552dd88 100644 --- a/clang/test/SemaCXX/warn-base-type-qualifiers.cpp +++ b/clang/test/SemaCXX/warn-base-type-qualifiers.cpp @@ -8,7 +8,7 @@ template using add_const_t = typename add_const::type; class A { }; typedef const A A_Const; -class B : public A_Const { }; // expected-warning {{'const' qualifier on base class type 'A_Const' (aka 'const A') have no effect}} \ +class B : public A_Const { }; // expected-warning {{'const' qualifier on base class type 'A_Const' (aka 'const A') has no effect}} \ // expected-note {{base class 'A_Const' (aka 'const A') specified here}} typedef const volatile A A_Const_Volatile; @@ -19,7 +19,7 @@ struct D { D(int); }; -template struct E : T { // expected-warning {{'const' qualifier on base class type 'const D' have no effect}} \ +template struct E : T { // expected-warning {{'const' qualifier on base class type 'const D' has no effect}} \ // expected-note {{base class 'const D' specified here}} using T::T; E(int &) : E(0) {} @@ -27,7 +27,7 @@ template struct E : T { // expected-warning {{'const' qualifier on E e(1); // expected-note {{in instantiation of template class 'E' requested here}} template -struct G : add_const::type { // expected-warning {{'const' qualifier on base class type 'add_const::type' (aka 'const D') have no effect}} \ +struct G : add_const::type { // expected-warning {{'const' qualifier on base class type 'add_const::type' (aka 'const D') has no effect}} \ // expected-note {{base class 'add_const::type' (aka 'const D') specified here}} using T::T; G(int &) : G(0) {} diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp index e80b54b7c6967..9bfc31bd07b0e 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp @@ -124,3 +124,38 @@ void array_indexed_const_expr(unsigned idx) { k = arr[get_const(5)]; // expected-note {{used in buffer access here}} k = arr[get_const(4)]; } + +template +consteval bool isNullTerminated(const char (&literal)[length]) +{ + return literal[length - 1] == '\0'; +} + +template +T access2DArray(const T (&arr)[M][N]) { + return arr[M-1][N-1]; +} + +template +constexpr int access_elements() { + int arr[idx + 20]; + return arr[idx + 1]; +} + +// Test array accesses where const sized arrays are accessed safely with indices +// that evaluate to a const values and depend on template arguments. +void test_template_methods() +{ + constexpr char arr[] = "Good Morning!"; // = {'a', 'b', 'c', 'd', 'e'}; + isNullTerminated(arr); + isNullTerminated(""); + auto _ = isNullTerminated("hello world\n"); + access_elements<5>(); + + int arr1[3][4] = { + {1, 2, 3, 4}, + {5, 6, 7, 8}, + {9, 10, 11, 12} + }; + access2DArray(arr1); +} diff --git a/clang/test/SemaCXX/warn-unused-private-field.cpp b/clang/test/SemaCXX/warn-unused-private-field.cpp index 0cc6f687f1b35..0bcca6b82227f 100644 --- a/clang/test/SemaCXX/warn-unused-private-field.cpp +++ b/clang/test/SemaCXX/warn-unused-private-field.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s -// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++17 %s -// RUN: %clang_cc1 -fsyntax-only -Wunused-private-field -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++20 %s +// RUN: %clang_cc1 -fsyntax-only -Wunused -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -Wunused -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++17 %s +// RUN: %clang_cc1 -fsyntax-only -Wunused -Wused-but-marked-unused -Wno-uninitialized -verify -std=c++20 %s #if __cplusplus >= 202002L @@ -108,7 +108,7 @@ class ClassWithTemplateFriend { template class TemplateFriend { public: TemplateFriend(ClassWithTemplateFriend my_friend) { - int var = my_friend.used_by_friend_; + int var = my_friend.used_by_friend_; // expected-warning {{unused variable 'var'}} } }; @@ -181,10 +181,10 @@ class EverythingUsed { public: EverythingUsed() : as_array_index_(0), var_(by_initializer_) { var_ = sizeof(sizeof_); - int *use = &by_reference_; + int *use = &by_reference_; // expected-warning {{unused variable 'use'}} int test[2]; test[as_array_index_] = 42; - int EverythingUsed::*ptr = &EverythingUsed::by_pointer_to_member_; + int EverythingUsed::*ptr = &EverythingUsed::by_pointer_to_member_; // expected-warning {{unused variable 'ptr'}} } template @@ -329,3 +329,28 @@ class C { MaybeUnusedTypedef t; // no-warning }; } + +namespace GH62472 { +class [[gnu::warn_unused]] S { +public: + S(); +}; + +struct [[maybe_unused]] T {}; + +void f() { + int i = 0; // expected-warning {{unused variable 'i'}} + S s; // expected-warning {{unused variable 's'}} + T t; // ok +} + +class C { +private: + const int i = 0; // expected-warning {{private field 'i' is not used}} + int j = 0; // expected-warning {{private field 'j' is not used}} + const S s1; // expected-warning {{private field 's1' is not used}} + const T t1; // ok + S s2; // expected-warning {{private field 's2' is not used}} + T t2; // ok +}; +} diff --git a/clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl new file mode 100644 index 0000000000000..ec9d026bb6fe7 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/AddUint64-errors.hlsl @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm-only -disable-llvm-passes -verify + +uint2 test_too_few_arg() { + return __builtin_hlsl_adduint64(); + // expected-error@-1 {{too few arguments to function call, expected 2, have 0}} +} + +uint4 test_too_many_arg(uint4 a) { + return __builtin_hlsl_adduint64(a, a, a); + // expected-error@-1 {{too many arguments to function call, expected 2, have 3}} +} + +uint2 test_mismatched_arg_types(uint2 a, uint4 b) { + return __builtin_hlsl_adduint64(a, b); + // expected-error@-1 {{all arguments to '__builtin_hlsl_adduint64' must have the same type}} +} + +uint2 test_bad_num_arg_elements(uint3 a, uint3 b) { + return __builtin_hlsl_adduint64(a, b); + // expected-error@-1 {{invalid element count of 3 in vector operand (expected an even element count in the range of 2 and 4)}} +} + +uint2 test_scalar_arg_type(uint a) { + return __builtin_hlsl_adduint64(a, a); + // expected-error@-1 {{all arguments to AddUint64 must be vectors}} +} + +uint2 test_signed_integer_args(int2 a, int2 b) { + return __builtin_hlsl_adduint64(a, b); +// expected-error@-1 {{passing 'int2' (aka 'vector') to parameter of incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' (vector of 2 'unsigned int' values)}} +} + +struct S { + uint2 a; +}; + +uint2 test_incorrect_arg_type(S a) { + return __builtin_hlsl_adduint64(a, a); + // expected-error@-1 {{passing 'S' to parameter of incompatible type 'unsigned int'}} +} + diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveMax-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveMax-errors.hlsl new file mode 100644 index 0000000000000..e077a40ba5165 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveMax-errors.hlsl @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify + +int test_too_few_arg() { + return __builtin_hlsl_wave_active_max(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +float2 test_too_many_arg(float2 p0) { + return __builtin_hlsl_wave_active_max(p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +bool test_expr_bool_type_check(bool p0) { + return __builtin_hlsl_wave_active_max(p0); + // expected-error@-1 {{invalid operand of type 'bool'}} +} + +bool2 test_expr_bool_vec_type_check(bool2 p0) { + return __builtin_hlsl_wave_active_max(p0); + // expected-error@-1 {{invalid operand of type 'bool2' (aka 'vector')}} +} + +struct S { float f; }; + +S test_expr_struct_type_check(S p0) { + return __builtin_hlsl_wave_active_max(p0); + // expected-error@-1 {{invalid operand of type 'S' where a scalar or vector is required}} +} + diff --git a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl index ee4605528f410..b96761fb76cc0 100644 --- a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl @@ -84,3 +84,10 @@ float builtin_mad_int_to_float_promotion(float p0, int p1) { return __builtin_hlsl_mad(p0, p0, p1); // expected-error@-1 {{3rd argument must be a floating point type (was 'int')}} } + +int builtin_mad_mixed_enums() { + enum e { one, two }; + enum f { three }; + return __builtin_hlsl_mad(one, two, three); + // expected-error@-1 {{invalid arithmetic between different enumeration types ('e' and 'f')}} +} diff --git a/clang/test/SemaHLSL/BuiltIns/vector-constructors-erros.hlsl b/clang/test/SemaHLSL/BuiltIns/vector-constructors-erros.hlsl index 7f6bdc7e67836..b004acdc7c502 100644 --- a/clang/test/SemaHLSL/BuiltIns/vector-constructors-erros.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/vector-constructors-erros.hlsl @@ -17,6 +17,4 @@ void entry() { // These _should_ work in HLSL but aren't yet supported. S s; float2 GettingStrange = float2(s, s); // expected-error{{no viable conversion from 'S' to 'float'}} expected-error{{no viable conversion from 'S' to 'float'}} - S2 s2; - float2 EvenStranger = float2(s2); // expected-error{{cannot convert 'S2' to 'float2' (vector of 2 'float' values) without a conversion operator}} } diff --git a/clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl b/clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl new file mode 100644 index 0000000000000..c900c83a063a0 --- /dev/null +++ b/clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify + +export void cantCast() { + int A[3] = {1,2,3}; + int B[4] = {1,2,3,4}; + B = (int[4])A; + // expected-error@-1 {{C-style cast from 'int *' to 'int[4]' is not allowed}} +} + +struct S { +// expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int2' (aka 'vector') to 'const S' for 1st argument}} +// expected-note@-2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int2' (aka 'vector') to 'S' for 1st argument}} +// expected-note@-3 {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} + int A : 8; + int B; +}; + +// casting types which contain bitfields is not yet supported. +export void cantCast2() { + S s = {1,2}; + int2 C = (int2)s; + // expected-error@-1 {{cannot convert 'S' to 'int2' (aka 'vector') without a conversion operator}} +} + +export void cantCast3() { + int2 C = {1,2}; + S s = (S)C; + // expected-error@-1 {{no matching conversion for C-style cast from 'int2' (aka 'vector') to 'S'}} +} diff --git a/clang/test/SemaHLSL/Language/ElementwiseCasts.hlsl b/clang/test/SemaHLSL/Language/ElementwiseCasts.hlsl new file mode 100644 index 0000000000000..563d3f02a1485 --- /dev/null +++ b/clang/test/SemaHLSL/Language/ElementwiseCasts.hlsl @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -finclude-default-header -fnative-half-type %s -ast-dump | FileCheck %s + +// truncation +// CHECK-LABEL: call1 +// CHECK: CStyleCastExpr {{.*}} 'int[1]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int[2]' part_of_explicit_cast +// CHECK-NEXT: DeclRefExpr {{.*}} 'int[2]' lvalue Var {{.*}} 'A' 'int[2]' +export void call1() { + int A[2] = {0,1}; + int B[1] = {4}; + B = (int[1])A; +} + +// flat cast of equal size +// CHECK-LABEL: call2 +// CHECK: CStyleCastExpr {{.*}} 'float[1]' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int[1]' part_of_explicit_cast +// CHECK-NEXT: DeclRefExpr {{.*}} 'int[1]' lvalue Var {{.*}} 'A' 'int[1]' +export void call2() { + int A[1] = {0}; + float B[1] = {1.0}; + B = (float[1])A; +} diff --git a/clang/test/SemaObjCXX/noescape.mm b/clang/test/SemaObjCXX/noescape.mm index 999a91b87300b..4484e3b955ac0 100644 --- a/clang/test/SemaObjCXX/noescape.mm +++ b/clang/test/SemaObjCXX/noescape.mm @@ -77,12 +77,11 @@ -(void) m0:(int*) p {} void (*fnptr0)(int *); void (*fnptr1)(__attribute__((noescape)) int *); template struct S4 {}; -template struct S5 {}; - #if __cplusplus < 201406 - // expected-note@-4 {{template parameter is declared here}} - // expected-note@-4 {{template parameter is declared here}} +// expected-note@-2 {{template parameter is declared here}} #endif +template struct S5 {}; +// expected-note@-1 {{template parameter is declared here}} void test0() { fnptr0 = &func0; diff --git a/clang/test/SemaObjCXX/type-traits.mm b/clang/test/SemaObjCXX/type-traits.mm new file mode 100644 index 0000000000000..81b9573b52192 --- /dev/null +++ b/clang/test/SemaObjCXX/type-traits.mm @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=c++17 %s + +// expected-no-diagnostics + +@interface I; +@end + +@class C; + +static_assert(__is_same(__add_pointer(id), id*)); +static_assert(__is_same(__add_pointer(I), I*)); + +static_assert(__is_same(__remove_pointer(C*), C)); +static_assert(!__is_same(__remove_pointer(id), id)); +static_assert(__is_same(__remove_pointer(id*), id)); +static_assert(__is_same(__remove_pointer(__add_pointer(id)), id)); +static_assert(__is_same(__add_pointer(__remove_pointer(id)), id)); diff --git a/clang/test/SemaOpenACC/atomic-construct-ast.cpp b/clang/test/SemaOpenACC/atomic-construct-ast.cpp new file mode 100644 index 0000000000000..6579b87941e5a --- /dev/null +++ b/clang/test/SemaOpenACC/atomic-construct-ast.cpp @@ -0,0 +1,170 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +void foo(int v, int x) { + // CHECK: FunctionDecl{{.*}} foo 'void (int, int)' + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic read +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +#pragma acc atomic read + v = x; + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic write +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: BinaryOperator{{.*}}'int' '+' +// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 +#pragma acc atomic write + v = x + 1; + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic update +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '++' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +#pragma acc atomic update + x++; +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '--' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +#pragma acc atomic + x--; +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic capture +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '++' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +#pragma acc atomic capture + v = x++; + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic capture +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '--' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +#pragma acc atomic capture + { x--; v = x; } + +} + +template +void templ_foo(T v, T x) { + // CHECK-NEXT: FunctionTemplateDecl{{.*}}templ_foo + // CHECK-NEXT: TemplateTypeParmDecl{{.*}} T + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} I + // CHECK-NEXT: FunctionDecl{{.*}} templ_foo 'void (T, T)' + // CHECK-NEXT: ParmVarDecl{{.*}} v 'T' + // CHECK-NEXT: ParmVarDecl{{.*}} x 'T' + // CHECK-NEXT: CompoundStmt + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic read +// CHECK-NEXT: BinaryOperator{{.*}} '' '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'T' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'T' +#pragma acc atomic read + v = x; + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic write +// CHECK-NEXT: BinaryOperator{{.*}} '' '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'T' +// CHECK-NEXT: BinaryOperator{{.*}}'' '+' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'T' +// CHECK-NEXT: DeclRefExpr{{.*}} 'I' 'int' +#pragma acc atomic write + v = x + I; + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic update +// CHECK-NEXT: UnaryOperator{{.*}} '' postfix '++' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'T' +#pragma acc atomic update + x++; +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic +// CHECK-NEXT: UnaryOperator{{.*}} '' postfix '--' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'T' +#pragma acc atomic + x--; +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic capture +// CHECK-NEXT: BinaryOperator{{.*}} '' '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'T' +// CHECK-NEXT: UnaryOperator{{.*}} '' postfix '++' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'T' +#pragma acc atomic capture + v = x++; + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic capture +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: UnaryOperator{{.*}} '' postfix '--' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'T' +// CHECK-NEXT: BinaryOperator{{.*}} '' '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'T' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'T' +#pragma acc atomic capture + { x--; v = x; } + + // CHECK-NEXT: FunctionDecl{{.*}} templ_foo 'void (int, int)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument integral '5' + // CHECK-NEXT: ParmVarDecl{{.*}} v 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} x 'int' + // CHECK-NEXT: CompoundStmt + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic read +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic write +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: BinaryOperator{{.*}}'int' '+' +// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +// CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}} 'int' +// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int'{{.*}}I +// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 5 + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic update +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '++' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '--' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic capture +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '++' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' + +// CHECK-NEXT: OpenACCAtomicConstruct{{.*}} atomic capture +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: UnaryOperator{{.*}} 'int' postfix '--' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +// CHECK-NEXT: BinaryOperator{{.*}} 'int' lvalue '=' +// CHECK-NEXT: DeclRefExpr{{.*}}'v' 'int' +// CHECK-NEXT: ImplicitCastExpr{{.*}}'int' +// CHECK-NEXT: DeclRefExpr{{.*}}'x' 'int' +} + +void use() { + templ_foo(1, 2); +} +#endif diff --git a/clang/test/SemaOpenACC/atomic-construct.cpp b/clang/test/SemaOpenACC/atomic-construct.cpp new file mode 100644 index 0000000000000..7357d91d704fd --- /dev/null +++ b/clang/test/SemaOpenACC/atomic-construct.cpp @@ -0,0 +1,1846 @@ +// RUN: %clang_cc1 %s -fopenacc -Wno-unused-value -verify + +void NormalFunc(int I) { + // No clauses are valid, but we parse them anyway, just mark them as not valid + // on this construct. + + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'atomic' directive}} +#pragma acc atomic copy(I) + I = I + 1; + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'atomic' directive}} +#pragma acc atomic read copy(I) + I = I; +} + +struct Struct{ + Struct *getPtr(); + Struct &operator++(); + Struct &operator--(); + Struct &operator++(int); + Struct &operator--(int); + + Struct &operator+=(int); + Struct &operator*=(int); + Struct &operator-=(int); + Struct &operator/=(int); + Struct &operator&=(int); + Struct &operator|=(int); + Struct &operator<<=(int); + Struct &operator>>=(int); + Struct &operator^=(int); + Struct &operator%=(int); + Struct &operator!=(int); + Struct &operator+(); + Struct &operator-(); + + operator int(); + void operator()(); + Struct &operator*(); + Struct &operator=(int); +}; + +int operator+(Struct&, int); +int operator+(int, Struct&); +Struct &operator+(Struct&, Struct&); +Struct &operator*(Struct&, Struct&); +Struct &operator-(Struct&, Struct&); + +Struct S1, S2; + +template +T &getRValue(); + +template +void AtomicReadTemplate(T LHS, T RHS) { +#pragma acc atomic read + LHS = RHS; + + T *LHSPtr, *RHSPtr; + +#pragma acc atomic read + LHSPtr = RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{right operand to assignment expression must be an l-value}} +#pragma acc atomic read + LHS = RHS + 1; + +#pragma acc atomic read + *LHSPtr = RHS; + +#pragma acc atomic read + LHS = *RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{right operand to assignment expression must be an l-value}} +#pragma acc atomic read + LHS = getRValue(); +} + +template +void AtomicReadTemplate2(T LHS, T RHS) { + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic read + LHS = RHS; + + T *LHSPtr, *RHSPtr; + // Fine, now a pointer. +#pragma acc atomic read + LHSPtr = RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{right operand to assignment expression must be an l-value}} +#pragma acc atomic read + LHS = *RHS.getPtr(); + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic read + *LHSPtr = RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic read + LHS = *RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be an l-value}} +#pragma acc atomic read + getRValue() = getRValue(); + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{right operand to assignment expression must be an l-value}} +#pragma acc atomic read + LHS = getRValue(); +} + +void AtomicRead(int LHS, int RHS) { + AtomicReadTemplate(LHS, RHS); + AtomicReadTemplate2(S1, S2); // expected-note{{in instantiation of function template specialization}} + +#pragma acc atomic read + LHS = RHS; + + int *LHSPtr, *RHSPtr; + +#pragma acc atomic read + LHSPtr = RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic read + S1 = S2; + + // expected-error@+2{{statement associated with OpenACC 'atomic read' directive is invalid}} + // expected-note@+2{{right operand to assignment expression must be an l-value}} +#pragma acc atomic read + LHS = RHS + 1; + +#pragma acc atomic read + *LHSPtr = RHS; + +#pragma acc atomic read + LHS = *RHSPtr; + + // There is no way to test that = is an overloaded operator, since there + // really isn't a way to create an operator= without a class type on one side + // or the other. +} + +template +void AtomicWriteTemplate(T LHS, T RHS) { +#pragma acc atomic write + LHS = RHS; + + T *LHSPtr, *RHSPtr; +#pragma acc atomic write + LHSPtr = RHSPtr; + +#pragma acc atomic write + *LHSPtr = *RHSPtr; + + // allowed, expr is ok. +#pragma acc atomic write + LHS = *RHSPtr; + +#pragma acc atomic write + LHS = RHS * 2; + + // expected-error@+2{{statement associated with OpenACC 'atomic write' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be an l-value}} +#pragma acc atomic write + getRValue() = getRValue(); + +#pragma acc atomic write + LHS = getRValue(); +} + +template +void AtomicWriteTemplate2(T LHS, T RHS) { + // expected-error@+2{{statement associated with OpenACC 'atomic write' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic write + LHS = RHS; + + T *LHSPtr, *RHSPtr; +#pragma acc atomic write + LHSPtr = RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic write' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic write + LHS = *RHSPtr; + +#pragma acc atomic write + LHSPtr = RHS.getPtr(); + + // expected-error@+2{{statement associated with OpenACC 'atomic write' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be an l-value}} +#pragma acc atomic write + getRValue() = getRValue(); + + // expected-error@+2{{statement associated with OpenACC 'atomic write' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic write + LHS = getRValue(); +} + +void AtomicWrite(int LHS, int RHS) { + AtomicWriteTemplate(LHS, RHS); + AtomicWriteTemplate2(S1, S2); // expected-note{{in instantiation of function template specialization}} + +#pragma acc atomic write + LHS = RHS; + + int *LHSPtr, *RHSPtr; +#pragma acc atomic write + LHSPtr = RHSPtr; + +#pragma acc atomic write + *LHSPtr = *RHSPtr; + + // allowed, expr is ok. +#pragma acc atomic write + LHS = *RHSPtr; + +#pragma acc atomic write + LHS = RHS * 2; +} + +template +void AtomicUpdateTemplate(T LHS, T RHS) { +#pragma acc atomic + LHS++; + +#pragma acc atomic update + LHS--; + +#pragma acc atomic + ++LHS; + +#pragma acc atomic update + --LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic + +LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic update + -LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{expected binary operation on right hand side of assignment operator}} +#pragma acc atomic update + LHS = RHS; + + T *LHSPtr, *RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{expected binary operation on right hand side of assignment operator}} +#pragma acc atomic + *LHSPtr = *RHSPtr; + + // x binop= expr; +#pragma acc atomic + LHS += 1 + RHS; +#pragma acc atomic update + LHS *= 1 + RHS; +#pragma acc atomic + LHS -= 1 + RHS; +#pragma acc atomic update + LHS /= 1 + RHS; +#pragma acc atomic + LHS &= 1 + RHS; +#pragma acc atomic update + LHS ^= 1 + RHS; +#pragma acc atomic + LHS |= 1 + RHS; +#pragma acc atomic update + LHS <<= 1 + RHS; +#pragma acc atomic + LHS >>= 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + LHS != 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + LHS <= 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + LHS >= 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + LHS %= 1 + RHS; + + // x = x binop expr. +#pragma acc atomic + LHS = LHS + getRValue(); +#pragma acc atomic update + LHS = LHS * getRValue(); +#pragma acc atomic update + LHS = LHS - getRValue(); +#pragma acc atomic update + LHS = LHS / getRValue(); +#pragma acc atomic update + LHS = LHS & getRValue(); +#pragma acc atomic update + LHS = LHS ^ getRValue(); +#pragma acc atomic update + LHS = LHS | getRValue(); +#pragma acc atomic update + LHS = LHS << getRValue(); +#pragma acc atomic update + LHS = LHS >> getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = LHS < getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = LHS > getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = LHS <= getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = LHS >= getRValue(); +#pragma acc atomic update + LHS = LHS ^ getRValue(); + + + // x = expr binop x. +#pragma acc atomic + LHS = getRValue() + LHS; +#pragma acc atomic update + LHS = getRValue() * LHS; +#pragma acc atomic update + LHS = getRValue() - LHS; +#pragma acc atomic update + LHS = getRValue() / LHS; +#pragma acc atomic update + LHS = getRValue() & LHS; +#pragma acc atomic update + LHS = getRValue() ^ LHS; +#pragma acc atomic update + LHS = getRValue() | LHS; +#pragma acc atomic update + LHS = getRValue() << LHS; +#pragma acc atomic update + LHS = getRValue() >> LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = getRValue() < LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = getRValue() > LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = getRValue() <= LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic update + LHS = getRValue() >= LHS; +#pragma acc atomic update + LHS = getRValue() ^ LHS; + +#pragma acc atomic update + LHS = LHS + getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and 'getRValue()')}} +#pragma acc atomic update + LHS = RHS + getRValue(); + +#pragma acc atomic update + LHS = getRValue() - LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('getRValue()' and 'RHS')}} +#pragma acc atomic update + LHS = getRValue() + RHS; +} + +template +void AtomicUpdateTemplate2(T LHS, T RHS) { + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{operand to increment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS++; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{operand to decrement expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS--; + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{operand to increment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + ++LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{operand to decrement expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + --LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic + +LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic update + -LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic + LHS(); + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic + *LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{expected binary operation on right hand side of assignment operator}} +#pragma acc atomic update + LHS = RHS; + + T *LHSPtr, *RHSPtr; + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{expected binary operation on right hand side of assignment operator}} +#pragma acc atomic + *LHSPtr = *RHSPtr; + + // x binop= expr; + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS += 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS *= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS -= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS /= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS &= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS ^= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS |= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS <<= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS >>= 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + LHS != 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + LHS %= 1 + RHS; + + // x = x binop expr. + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS = LHS + getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS = LHS * getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS = LHS - getRValue(); + + // x = expr binop x. + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + LHS = getRValue() + LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS = getRValue() * LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS = getRValue() - LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS = LHS + getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and 'getRValue()')}} +#pragma acc atomic update + LHS = RHS + getRValue(); + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + LHS = getRValue() - LHS; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('getRValue()' and 'RHS')}} +#pragma acc atomic update + LHS = getRValue() + RHS; +} + +void AtomicUpdate() { + AtomicUpdateTemplate(1, 2); + AtomicUpdateTemplate2(S1, S2); //expected-note{{in instantiation of function template specialization}} + + int I, J; + +#pragma acc atomic + I++; +#pragma acc atomic update + --I; + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{operand to increment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic + S1++; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{operand to decrement expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + --S2; + + // expected-error@+2{{statement associated with OpenACC 'atomic' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic + +I; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic update + -J; + +#pragma acc atomic update + I ^= 1 + J; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + I%= 1 + J; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic update + S1 ^= 1 + J; + + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic update + S2 %= 1 + J; + +#pragma acc atomic update + I = I + getRValue(); + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('I') must match one side of the sub-operation on the right hand side('J' and 'getRValue()')}} +#pragma acc atomic update + I = J + getRValue(); + +#pragma acc atomic update + I = getRValue() - I; + // expected-error@+2{{statement associated with OpenACC 'atomic update' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('I') must match one side of the sub-operation on the right hand side('getRValue()' and 'J')}} +#pragma acc atomic update + I = getRValue() + J; +} + +template +void AtomicCaptureTemplateSimple(T LHS, T RHS) { + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture + LHS++; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture +--LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture + LHS += 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + LHS = RHS; + +#pragma acc atomic capture + LHS = RHS++; + +#pragma acc atomic capture + LHS = RHS--; + +#pragma acc atomic capture + LHS = ++RHS; + +#pragma acc atomic capture + LHS = --RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic capture + LHS = +RHS; + +#pragma acc atomic capture + LHS = RHS += 1 + RHS; +#pragma acc atomic capture + LHS = RHS *= 1 + RHS; +#pragma acc atomic capture + LHS = RHS -= 1 + RHS; +#pragma acc atomic capture + LHS = RHS /= 1 + RHS; +#pragma acc atomic capture + LHS = RHS &= 1 + RHS; +#pragma acc atomic capture + LHS = RHS ^= 1 + RHS; +#pragma acc atomic capture + LHS = RHS >>= 1 + RHS; +#pragma acc atomic capture + LHS = RHS |= 1 + RHS; +#pragma acc atomic capture + LHS = RHS <<= 1 + RHS; +#pragma acc atomic capture + LHS = RHS >>= 1 + RHS; + +#pragma acc atomic capture + LHS = RHS ^= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS <= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS >= 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS + 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS < 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS > 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS ^ 1 + RHS; + +#pragma acc atomic capture + LHS = RHS = RHS + 1; +#pragma acc atomic capture + LHS = RHS = 1 + RHS; +#pragma acc atomic capture + LHS = RHS = RHS * 1; +#pragma acc atomic capture + LHS = RHS = 1 * RHS; +#pragma acc atomic capture + LHS = RHS = RHS / 1; +#pragma acc atomic capture + LHS = RHS = 1 / RHS; +#pragma acc atomic capture + LHS = RHS = RHS ^ 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = 1 % RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = RHS < 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = 1 > RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and 'getRValue()')}} +#pragma acc atomic capture + LHS = LHS = RHS + getRValue(); + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('getRValue()' and 'RHS')}} +#pragma acc atomic capture + LHS = LHS = getRValue() + RHS; +} +template +void AtomicCaptureTemplateSimple2(T LHS, T RHS) { + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture + LHS++; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture +--LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture + LHS += 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + LHS = RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS++; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS--; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = ++RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = --RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic capture + LHS = +RHS; + + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS += 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS *= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS -= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS /= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS &= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS ^= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS >>= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS |= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS <<= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS >>= 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS ^= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS <= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS >= 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS + 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS < 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS > 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS ^ 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS = RHS + 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS = 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS = RHS * 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS = 1 * RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS = RHS / 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS = 1 / RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + LHS = RHS = RHS ^ 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = 1 % RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = RHS < 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = 1 > RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and 'getRValue()')}} +#pragma acc atomic capture + LHS = LHS = RHS + getRValue(); + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('getRValue()' and 'RHS')}} +#pragma acc atomic capture + LHS = LHS = getRValue() + RHS; +} + +void AtomicCaptureSimple(int LHS, int RHS) { + AtomicCaptureTemplateSimple(1, 2); + AtomicCaptureTemplateSimple2(S1, S2); //expected-note{{in instantiation of function template specialization}} + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture + LHS++; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture +--LHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment expression}} +#pragma acc atomic capture + LHS += 1 + RHS; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + LHS = RHS; + +#pragma acc atomic capture + LHS = RHS++; + +#pragma acc atomic capture + LHS = RHS--; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + S1 = ++S2; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + S1 = --S2 ; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{unary operator not supported, only increment and decrement operations permitted}} +#pragma acc atomic capture + LHS = +RHS; + +#pragma acc atomic capture + LHS = RHS += 1 + RHS; +#pragma acc atomic capture + LHS = RHS *= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + S1 = RHS -= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + LHS = S1 /= 1 + RHS; +#pragma acc atomic capture + LHS = RHS &= 1 + S2; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + LHS = S1^= 1 + S2; + +#pragma acc atomic capture + LHS = RHS ^= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS <= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + S1 = RHS ^= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = S1 <= 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{compound binary operator not supported, only +=, *=, -=, /=, &=, ^=, |=, <<=, or >>= are permitted}} +#pragma acc atomic capture + LHS = RHS <= 1 + S2; + +#pragma acc atomic capture + LHS = RHS = RHS + 1; +#pragma acc atomic capture + LHS = RHS = 1 + RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + S1 = RHS = RHS * 1; + // A little weird, because this contains a 'operator int' call here rather + // than a conversion, so the diagnostic could be better. + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + LHS = S2 = 1 * S2; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = RHS < 1; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{binary operator not supported, only +, *, -, /, &, ^, |, <<, or >> are permitted}} +#pragma acc atomic capture + LHS = RHS = 1 > RHS; + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left operand to assignment expression must be of scalar type (was 'Struct')}} +#pragma acc atomic capture + S1 = RHS = RHS < 1; + + // A little weird, because this contains a 'operator int' call here rather + // than a conversion, so the diagnostic could be better. + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + LHS = S1 = 1 > S1; + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and 'getRValue()')}} +#pragma acc atomic capture + LHS = LHS = RHS + getRValue(); + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('getRValue()' and 'RHS')}} +#pragma acc atomic capture + LHS = LHS = getRValue() + RHS; +} + +template +void AtomicCaptureTemplateCompound(T LHS, T RHS) { + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + { + } + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+4{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + { + LHS = RHS; + } + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+3{{'atomic capture' with a compound statement only supports two statements}} +#pragma acc atomic capture + { + LHS = RHS; RHS += 1; LHS=RHS; + } + + +#pragma acc atomic capture + { + LHS++; + RHS = LHS; + } + +#pragma acc atomic capture + { + ++LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + --LHS; + RHS = LHS; + } + + +#pragma acc atomic capture + { + LHS--; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used in unary expression('LHS') from the first statement}} + LHS = RHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{unary operator not supported, only increment and decrement operations permitted}} + -LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + --LHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x binop = expr; v = x; } +#pragma acc atomic capture + { + LHS += 1; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS *= 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of compound assignment('LHS') from the first statement}} + LHS = RHS; + } +#pragma acc atomic capture + { + LHS /= 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x = x binop expr; v = x; } +#pragma acc atomic capture + { + LHS = LHS + 1; + RHS = LHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and '1')}} + LHS = RHS - 1; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS = LHS * 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of assignment('LHS') from the first statement}} + RHS = RHS; + } +#pragma acc atomic capture + { + LHS = LHS / 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x = expr binop x; v = x; } +#pragma acc atomic capture + { + LHS = 1 ^ LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('1' and 'RHS')}} + LHS = 1 & RHS; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS = LHS | 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of assignment('LHS') from the first statement}} + RHS = RHS; + } +#pragma acc atomic capture + { + LHS = LHS << 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { v = x; x binop = expr; } +#pragma acc atomic capture + { + LHS = RHS; + RHS += 1; + } + + // { v = x; x = x binop expr; } +#pragma acc atomic capture + { + LHS = RHS; + RHS = RHS / 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('RHS') must match one side of the sub-operation on the right hand side('LHS' and '1')}} + RHS = LHS ^ 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and '1')}} + LHS = RHS << 1; + } + // { v = x; x = expr binop x; } +#pragma acc atomic capture + { + LHS = RHS; + RHS = 1 / RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('RHS') must match one side of the sub-operation on the right hand side('1' and 'LHS')}} + RHS = 1 ^ LHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('1' and 'RHS')}} + LHS = 1 << RHS; + } + + // { v = x; x = expr; } +#pragma acc atomic capture + { + LHS = RHS; + RHS = 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on left hand side of assignment('LHS') must match variable used on right hand side of assignment('RHS') from the first statement}} + LHS = 1; + } + + // { v = x; x++; } + // { v = x; ++x; } + // { v = x; x--; } + // { v = x; --x; } +#pragma acc atomic capture + { + LHS = RHS; + RHS++; + } +#pragma acc atomic capture + { + LHS = RHS; + RHS--; + } +#pragma acc atomic capture + { + LHS = RHS; + ++RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + --RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{unary operator not supported, only increment and decrement operations permitted}} + -RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable in unary expression('LHS') must match variable used on right hand side of assignment('RHS') from the first statement}} + LHS++; + } +} + +template +void AtomicCaptureTemplateCompound2(T LHS, T RHS) { + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + { + } + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+4{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + { + LHS = RHS; + } + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+3{{'atomic capture' with a compound statement only supports two statements}} +#pragma acc atomic capture + { + LHS = RHS; RHS += 1; LHS=RHS; + } + + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{operand to increment expression must be of scalar type (was 'Struct')}} + LHS++; + RHS = LHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{operand to increment expression must be of scalar type (was 'Struct')}} + ++LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{operand to decrement expression must be of scalar type (was 'Struct')}} + --LHS; + RHS = LHS; + } + + +#pragma acc atomic capture + { + LHS--; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used in unary expression('LHS') from the first statement}} + LHS = RHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{unary operator not supported, only increment and decrement operations permitted}} + -LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + --LHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x binop = expr; v = x; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} + LHS += 1; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS *= 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of compound assignment('LHS') from the first statement}} + LHS = RHS; + } +#pragma acc atomic capture + { + LHS /= 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x = x binop expr; v = x; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = LHS + 1; + RHS = LHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and '1')}} + LHS = RHS - 1; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS = LHS * 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of assignment('LHS') from the first statement}} + RHS = RHS; + } +#pragma acc atomic capture + { + LHS = LHS / 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x = expr binop x; v = x; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = 1 ^ LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('1' and 'RHS')}} + LHS = 1 & RHS; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS = LHS | 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of assignment('LHS') from the first statement}} + RHS = RHS; + } +#pragma acc atomic capture + { + LHS = LHS << 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { v = x; x binop = expr; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + RHS += 1; + } + + // { v = x; x = x binop expr; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + RHS = RHS / 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('RHS') must match one side of the sub-operation on the right hand side('LHS' and '1')}} + RHS = LHS ^ 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and '1')}} + LHS = RHS << 1; + } + // { v = x; x = expr binop x; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + RHS = 1 / RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('RHS') must match one side of the sub-operation on the right hand side('1' and 'LHS')}} + RHS = 1 ^ LHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('1' and 'RHS')}} + LHS = 1 << RHS; + } + + // { v = x; x = expr; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + RHS = 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on left hand side of assignment('LHS') must match variable used on right hand side of assignment('RHS') from the first statement}} + LHS = 1; + } + + // { v = x; x++; } + // { v = x; ++x; } + // { v = x; x--; } + // { v = x; --x; } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + RHS++; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + RHS--; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + ++RHS; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + LHS = RHS; + --RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{unary operator not supported, only increment and decrement operations permitted}} + -RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable in unary expression('LHS') must match variable used on right hand side of assignment('RHS') from the first statement}} + LHS++; + } +} +void AtomicCaptureCompound(int LHS, int RHS) { + AtomicCaptureTemplateCompound(1, 2); + AtomicCaptureTemplateCompound2(S1, S2); //expected-note{{in instantiation of function template specialization}} + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+2{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + { + } + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+4{{expected assignment, compound assignment, increment, or decrement expression}} +#pragma acc atomic capture + { + LHS = RHS; + } + + // expected-error@+2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+3{{'atomic capture' with a compound statement only supports two statements}} +#pragma acc atomic capture + { + LHS = RHS; RHS += 1; LHS=RHS; + } + + +#pragma acc atomic capture + { + LHS++; + RHS = LHS; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{operand to increment expression must be of scalar type (was 'Struct')}} + S1++; + S2= S1; + } + +#pragma acc atomic capture + { + ++LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + --LHS; + RHS = LHS; + } + + +#pragma acc atomic capture + { + LHS--; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used in unary expression('LHS') from the first statement}} + LHS = RHS; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{unary operator not supported, only increment and decrement operations permitted}} + -LHS; + RHS = LHS; + } + +#pragma acc atomic capture + { + --LHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x binop = expr; v = x; } +#pragma acc atomic capture + { + LHS += 1; + RHS = LHS; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to compound assignment expression must be of scalar type (was 'Struct')}} + S1 += 1; + S2= S1; + } +#pragma acc atomic capture + { + LHS *= 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of compound assignment('LHS') from the first statement}} + LHS = RHS; + } +#pragma acc atomic capture + { + LHS /= 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x = x binop expr; v = x; } +#pragma acc atomic capture + { + LHS = LHS + 1; + RHS = LHS; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + S1 = S1 + 1; + S2= S1; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and '1')}} + LHS = RHS - 1; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS = LHS * 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of assignment('LHS') from the first statement}} + RHS = RHS; + } +#pragma acc atomic capture + { + LHS = LHS / 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { x = expr binop x; v = x; } +#pragma acc atomic capture + { + LHS = 1 ^ LHS; + RHS = LHS; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + S1 = 1 ^ S1; + S2 = S1; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('1' and 'RHS')}} + LHS = 1 & RHS; + RHS = LHS; + } +#pragma acc atomic capture + { + LHS = LHS | 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on right hand side of assignment('RHS') must match variable used on left hand side of assignment('LHS') from the first statement}} + RHS = RHS; + } +#pragma acc atomic capture + { + LHS = LHS << 1; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{expected assignment expression}} + RHS += LHS; + } + + // { v = x; x binop = expr; } +#pragma acc atomic capture + { + LHS = RHS; + RHS += 1; + } + +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + S1 = S2; + S2 += 1; + } + + // { v = x; x = x binop expr; } +#pragma acc atomic capture + { + LHS = RHS; + RHS = RHS / 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('RHS') must match one side of the sub-operation on the right hand side('LHS' and '1')}} + RHS = LHS ^ 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('RHS' and '1')}} + LHS = RHS << 1; + } + // { v = x; x = expr binop x; } +#pragma acc atomic capture + { + LHS = RHS; + RHS = 1 / RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('RHS') must match one side of the sub-operation on the right hand side('1' and 'LHS')}} + RHS = 1 ^ LHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left hand side of assignment operation('LHS') must match one side of the sub-operation on the right hand side('1' and 'RHS')}} + LHS = 1 << RHS; + } + + // { v = x; x = expr; } +#pragma acc atomic capture + { + LHS = RHS; + RHS = 1; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable on left hand side of assignment('LHS') must match variable used on right hand side of assignment('RHS') from the first statement}} + LHS = 1; + } + + // { v = x; x++; } + // { v = x; ++x; } + // { v = x; x--; } + // { v = x; --x; } +#pragma acc atomic capture + { + LHS = RHS; + RHS++; + } +#pragma acc atomic capture + { + LHS = RHS; + RHS--; + } +#pragma acc atomic capture + { + LHS = RHS; + ++RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + --RHS; + } +#pragma acc atomic capture + { + // expected-error@-2{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{left operand to assignment expression must be of scalar type (was 'Struct')}} + S1= S2; + --S2; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{unary operator not supported, only increment and decrement operations permitted}} + -RHS; + } +#pragma acc atomic capture + { + LHS = RHS; + // expected-error@-3{{statement associated with OpenACC 'atomic capture' directive is invalid}} + // expected-note@+1{{variable in unary expression('LHS') must match variable used on right hand side of assignment('RHS') from the first statement}} + LHS++; + } +} diff --git a/clang/test/SemaTemplate/GH55509.cpp b/clang/test/SemaTemplate/GH55509.cpp new file mode 100644 index 0000000000000..773a84305a0cd --- /dev/null +++ b/clang/test/SemaTemplate/GH55509.cpp @@ -0,0 +1,112 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++26 %s + +namespace t1 { + template struct A { + template friend auto cica(const A&, C) { + return N; + } + }; + + template<> struct A<0> { + template friend auto cica(const A<0>&, C); + // expected-note@-1 {{declared here}} + }; + + void test() { + cica(A<0>{}, 0); + // expected-error@-1 {{function 'cica' with deduced return type cannot be used before it is defined}} + + (void)A<1>{}; + cica(A<0>{}, 0); + } +} // namespace t1 +namespace t2 { + template struct A { + template friend auto cica(const A&, C) { + return N; + } + }; + + template<> struct A<0> { + template friend auto cica(const A<0>&, C); + }; + + template {}, nullptr))> + void MakeCica(); + // expected-note@-1 {{candidate function}} + + template void MakeCica(A = {}); + // expected-note@-1 {{candidate function}} + + void test() { + MakeCica<0>(); + + MakeCica<0>(); + // expected-error@-1 {{call to 'MakeCica' is ambiguous}} + } +} // namespace t2 +namespace t3 { + template struct A { + template friend auto cica(const A&, C) { + return N-1; + } + }; + + template<> struct A<0> { + template friend auto cica(const A<0>&, C); + }; + + template + static constexpr bool MakeCica(int); + + template + static constexpr bool MakeCica(short, A = {}); + + template , class Val = decltype(MakeCica(0))> + static constexpr bool has_cica = Val{}; + + constexpr bool cica2 = has_cica<0> || has_cica<0>; +} // namespace t3 +namespace t4 { + template struct A { + template friend auto cica(const A&, C); + }; + + template<> struct A<0> { + template friend auto cica(const A<0>&, C) { + C a; + } + }; + + template struct A<1>; + + void test() { + cica(A<0>{}, 0); + } +} // namespace t4 +namespace regression1 { + template class A; + + template [[gnu::abi_tag("TAG")]] void foo(A); + + template struct A { + friend void foo <>(A); + }; + + template struct A; + + template [[gnu::abi_tag("TAG")]] void foo(A) {} + + template void foo(A); +} // namespace regression1 +namespace regression2 { + template struct A { + template static void f() { + A::f(); + } + }; + template <> template void A::f() { + static_assert(__is_same(T, long)); + } + template void A::f(); +} // namespace regression2 diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp index 2ca9b8007ab41..eb8dbc69a945e 100644 --- a/clang/test/SemaTemplate/address_space-dependent.cpp +++ b/clang/test/SemaTemplate/address_space-dependent.cpp @@ -43,7 +43,7 @@ void neg() { template void tooBig() { - __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388586)}} + __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388585)}} } template diff --git a/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp b/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp index 49afb6b860620..0854ac9178b4f 100644 --- a/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp +++ b/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp @@ -274,10 +274,10 @@ namespace TrailingPack { // CHECK: |-TemplateArgument pack // CHECK: | |-TemplateArgument type 'TrailingPack::(lambda at {{.*}})' // CHECK: | | `-RecordType {{.*}} 'TrailingPack::(lambda at {{.*}})' - // CHECK: | | `-CXXRecord {{.*}} '' + // CHECK: | | `-CXXRecord {{.*}} // CHECK: | `-TemplateArgument type 'TrailingPack::(lambda at {{.*}})' // CHECK: | `-RecordType {{.*}} 'TrailingPack::(lambda at {{.*}})' - // CHECK: | `-CXXRecord {{.*}} '' + // CHECK: | `-CXXRecord {{.*}} // CHECK: |-ParmVarDecl {{.*}} 'TrailingPack::(lambda at {{.*}})' // CHECK: `-ParmVarDecl {{.*}} 'TrailingPack::(lambda at {{.*}})' // CHECK: FunctionProtoType {{.*}} 'auto (T...) -> A' dependent trailing_return cdecl diff --git a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp index 6c1a229a9fdda..5af4ec75cae90 100644 --- a/clang/test/SemaTemplate/concepts-out-of-line-def.cpp +++ b/clang/test/SemaTemplate/concepts-out-of-line-def.cpp @@ -722,6 +722,34 @@ template struct d; } // namespace GH115098 +namespace GH123441 { + +struct buf { + constexpr buf(auto&&... initList) requires (sizeof...(initList) <= 8); +}; + +constexpr buf::buf(auto&&... initList) requires (sizeof...(initList) <= 8) {} + +template +struct buffer { + constexpr buffer(auto&&... initList) requires (sizeof...(initList) <= 8); +}; + +template +constexpr buffer::buffer(auto&&... initList) requires (sizeof...(initList) <= 8) {} + +template +struct foo { // expected-note {{foo defined here}} + constexpr foo(auto&&... initList) + requires (sizeof...(initList) <= 8); +}; + +template +constexpr foo::foo(auto&&... initList) // expected-error {{does not match any declaration}} + requires (sizeof...(T) <= 8) {} + +} // namespace GH123441 + namespace GH114685 { template struct ptr { diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp index 21a1b89ce79b4..51d98d4b3b202 100644 --- a/clang/test/SemaTemplate/cwg2398.cpp +++ b/clang/test/SemaTemplate/cwg2398.cpp @@ -1,14 +1,12 @@ -// RUN: %clang_cc1 %s -fsyntax-only -std=c++23 -verify=expected,new -// RUN: %clang_cc1 %s -fsyntax-only -std=c++23 -fno-relaxed-template-template-args -verify=expected,old +// RUN: %clang_cc1 %s -fsyntax-only -std=c++23 -verify namespace issue1 { template class B {}; template class P, class T> void f(P); - // new-note@-1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = B, T = int]}} - // old-note@-2 2{{template template argument has different template parameters}} + // expected-note@-1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = B, T = int]}} void g() { - f(B()); // old-error {{no matching function for call}} + f(B()); f(B()); // expected-error {{no matching function for call}} } } // namespace issue1 @@ -116,41 +114,32 @@ namespace gcc_issue { template struct A; template class TT1, class T2> struct A, typename TT1::type>; - // new-note@-1 {{partial specialization matches}} + // expected-note@-1 {{partial specialization matches}} template class TT2, class T5, class T6> struct A, typename TT2::type>; - // new-note@-1 {{partial specialization matches}} - // old-note@-2 {{template is declared here}} + // expected-note@-1 {{partial specialization matches}} template struct B { using type = int; }; template struct A, int>; - // new-error@-1 {{ambiguous partial specializations}} - // old-error@-2 {{explicit instantiation of undefined template}} + // expected-error@-1 {{ambiguous partial specializations}} } // namespace gcc_issue namespace ttp_defaults { template