diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index aa4dedbc926..47643370ff7 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -51,6 +51,483 @@ # xargs -n1 | sort | uniq -d; # done +# 20241023: new clang import which bumps version from 18 to 19 +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_builtin_vars.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_cmath.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_complex_builtins.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_device_functions.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_intrinsics.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_libdevice_declares.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_math.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_math_forward_declares.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_runtime_wrapper.h +OLD_FILES+=usr/lib/clang/18/include/__clang_cuda_texture_intrinsics.h +OLD_FILES+=usr/lib/clang/18/include/__clang_hip_cmath.h +OLD_FILES+=usr/lib/clang/18/include/__clang_hip_libdevice_declares.h +OLD_FILES+=usr/lib/clang/18/include/__clang_hip_math.h +OLD_FILES+=usr/lib/clang/18/include/__clang_hip_runtime_wrapper.h +OLD_FILES+=usr/lib/clang/18/include/__clang_hip_stdlib.h +OLD_FILES+=usr/lib/clang/18/include/__stdarg___gnuc_va_list.h +OLD_FILES+=usr/lib/clang/18/include/__stdarg___va_copy.h +OLD_FILES+=usr/lib/clang/18/include/__stdarg_va_arg.h +OLD_FILES+=usr/lib/clang/18/include/__stdarg_va_copy.h +OLD_FILES+=usr/lib/clang/18/include/__stdarg_va_list.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_max_align_t.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_null.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_nullptr_t.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_offsetof.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_ptrdiff_t.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_rsize_t.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_size_t.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_unreachable.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_wchar_t.h +OLD_FILES+=usr/lib/clang/18/include/__stddef_wint_t.h +OLD_FILES+=usr/lib/clang/18/include/__wmmintrin_aes.h +OLD_FILES+=usr/lib/clang/18/include/__wmmintrin_pclmul.h +OLD_FILES+=usr/lib/clang/18/include/adcintrin.h +OLD_FILES+=usr/lib/clang/18/include/adxintrin.h +OLD_FILES+=usr/lib/clang/18/include/altivec.h +OLD_FILES+=usr/lib/clang/18/include/ammintrin.h +OLD_FILES+=usr/lib/clang/18/include/amxcomplexintrin.h +OLD_FILES+=usr/lib/clang/18/include/amxfp16intrin.h +OLD_FILES+=usr/lib/clang/18/include/amxintrin.h +OLD_FILES+=usr/lib/clang/18/include/arm64intr.h +OLD_FILES+=usr/lib/clang/18/include/arm_acle.h +OLD_FILES+=usr/lib/clang/18/include/arm_bf16.h +OLD_FILES+=usr/lib/clang/18/include/arm_cde.h +OLD_FILES+=usr/lib/clang/18/include/arm_cmse.h +OLD_FILES+=usr/lib/clang/18/include/arm_fp16.h +OLD_FILES+=usr/lib/clang/18/include/arm_mve.h +OLD_FILES+=usr/lib/clang/18/include/arm_neon.h +OLD_FILES+=usr/lib/clang/18/include/arm_neon_sve_bridge.h +OLD_FILES+=usr/lib/clang/18/include/arm_sme_draft_spec_subject_to_change.h +OLD_FILES+=usr/lib/clang/18/include/arm_sve.h +OLD_FILES+=usr/lib/clang/18/include/arm_vector_types.h +OLD_FILES+=usr/lib/clang/18/include/armintr.h +OLD_FILES+=usr/lib/clang/18/include/avx2intrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512bf16intrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512bitalgintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512bwintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512cdintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512dqintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512erintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512fintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512fp16intrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512ifmaintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512ifmavlintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512pfintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vbmi2intrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vbmiintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vbmivlintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlbf16intrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlbitalgintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlbwintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlcdintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vldqintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlfp16intrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlvbmi2intrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlvnniintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vlvp2intersectintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vnniintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vp2intersectintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vpopcntdqintrin.h +OLD_FILES+=usr/lib/clang/18/include/avx512vpopcntdqvlintrin.h +OLD_FILES+=usr/lib/clang/18/include/avxifmaintrin.h +OLD_FILES+=usr/lib/clang/18/include/avxintrin.h +OLD_FILES+=usr/lib/clang/18/include/avxneconvertintrin.h +OLD_FILES+=usr/lib/clang/18/include/avxvnniint16intrin.h +OLD_FILES+=usr/lib/clang/18/include/avxvnniint8intrin.h +OLD_FILES+=usr/lib/clang/18/include/avxvnniintrin.h +OLD_FILES+=usr/lib/clang/18/include/bmi2intrin.h +OLD_FILES+=usr/lib/clang/18/include/bmiintrin.h +OLD_FILES+=usr/lib/clang/18/include/builtins.h +OLD_FILES+=usr/lib/clang/18/include/cet.h +OLD_FILES+=usr/lib/clang/18/include/cetintrin.h +OLD_FILES+=usr/lib/clang/18/include/cldemoteintrin.h +OLD_FILES+=usr/lib/clang/18/include/clflushoptintrin.h +OLD_FILES+=usr/lib/clang/18/include/clwbintrin.h +OLD_FILES+=usr/lib/clang/18/include/clzerointrin.h +OLD_FILES+=usr/lib/clang/18/include/cmpccxaddintrin.h +OLD_FILES+=usr/lib/clang/18/include/cpuid.h +OLD_FILES+=usr/lib/clang/18/include/crc32intrin.h +OLD_FILES+=usr/lib/clang/18/include/cuda_wrappers/algorithm +OLD_FILES+=usr/lib/clang/18/include/cuda_wrappers/bits/basic_string.h +OLD_FILES+=usr/lib/clang/18/include/cuda_wrappers/bits/basic_string.tcc +OLD_FILES+=usr/lib/clang/18/include/cuda_wrappers/bits/shared_ptr_base.h +OLD_DIRS+=usr/lib/clang/18/include/cuda_wrappers/bits +OLD_FILES+=usr/lib/clang/18/include/cuda_wrappers/cmath +OLD_FILES+=usr/lib/clang/18/include/cuda_wrappers/complex +OLD_FILES+=usr/lib/clang/18/include/cuda_wrappers/new +OLD_DIRS+=usr/lib/clang/18/include/cuda_wrappers +OLD_FILES+=usr/lib/clang/18/include/emmintrin.h +OLD_FILES+=usr/lib/clang/18/include/enqcmdintrin.h +OLD_FILES+=usr/lib/clang/18/include/f16cintrin.h +OLD_FILES+=usr/lib/clang/18/include/float.h +OLD_FILES+=usr/lib/clang/18/include/fma4intrin.h +OLD_FILES+=usr/lib/clang/18/include/fmaintrin.h +OLD_FILES+=usr/lib/clang/18/include/fuzzer/FuzzedDataProvider.h +OLD_DIRS+=usr/lib/clang/18/include/fuzzer +OLD_FILES+=usr/lib/clang/18/include/fxsrintrin.h +OLD_FILES+=usr/lib/clang/18/include/gfniintrin.h +OLD_FILES+=usr/lib/clang/18/include/hexagon_circ_brev_intrinsics.h +OLD_FILES+=usr/lib/clang/18/include/hexagon_protos.h +OLD_FILES+=usr/lib/clang/18/include/hexagon_types.h +OLD_FILES+=usr/lib/clang/18/include/hlsl/hlsl_basic_types.h +OLD_FILES+=usr/lib/clang/18/include/hlsl/hlsl_intrinsics.h +OLD_DIRS+=usr/lib/clang/18/include/hlsl +OLD_FILES+=usr/lib/clang/18/include/hlsl.h +OLD_FILES+=usr/lib/clang/18/include/hresetintrin.h +OLD_FILES+=usr/lib/clang/18/include/htmintrin.h +OLD_FILES+=usr/lib/clang/18/include/htmxlintrin.h +OLD_FILES+=usr/lib/clang/18/include/hvx_hexagon_protos.h +OLD_FILES+=usr/lib/clang/18/include/ia32intrin.h +OLD_FILES+=usr/lib/clang/18/include/immintrin.h +OLD_FILES+=usr/lib/clang/18/include/intrin.h +OLD_FILES+=usr/lib/clang/18/include/inttypes.h +OLD_FILES+=usr/lib/clang/18/include/invpcidintrin.h +OLD_FILES+=usr/lib/clang/18/include/iso646.h +OLD_FILES+=usr/lib/clang/18/include/keylockerintrin.h +OLD_FILES+=usr/lib/clang/18/include/larchintrin.h +OLD_FILES+=usr/lib/clang/18/include/lasxintrin.h +OLD_FILES+=usr/lib/clang/18/include/limits.h +OLD_FILES+=usr/lib/clang/18/include/lsxintrin.h +OLD_FILES+=usr/lib/clang/18/include/lwpintrin.h +OLD_FILES+=usr/lib/clang/18/include/lzcntintrin.h +OLD_FILES+=usr/lib/clang/18/include/mm3dnow.h +OLD_FILES+=usr/lib/clang/18/include/mm_malloc.h +OLD_FILES+=usr/lib/clang/18/include/mmintrin.h +OLD_FILES+=usr/lib/clang/18/include/module.modulemap +OLD_FILES+=usr/lib/clang/18/include/movdirintrin.h +OLD_FILES+=usr/lib/clang/18/include/msa.h +OLD_FILES+=usr/lib/clang/18/include/mwaitxintrin.h +OLD_FILES+=usr/lib/clang/18/include/nmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/omp-tools.h +OLD_FILES+=usr/lib/clang/18/include/omp.h +OLD_FILES+=usr/lib/clang/18/include/ompt.h +OLD_FILES+=usr/lib/clang/18/include/opencl-c-base.h +OLD_FILES+=usr/lib/clang/18/include/opencl-c.h +OLD_FILES+=usr/lib/clang/18/include/openmp_wrappers/__clang_openmp_device_functions.h +OLD_FILES+=usr/lib/clang/18/include/openmp_wrappers/cmath +OLD_FILES+=usr/lib/clang/18/include/openmp_wrappers/complex +OLD_FILES+=usr/lib/clang/18/include/openmp_wrappers/complex.h +OLD_FILES+=usr/lib/clang/18/include/openmp_wrappers/complex_cmath.h +OLD_FILES+=usr/lib/clang/18/include/openmp_wrappers/math.h +OLD_FILES+=usr/lib/clang/18/include/openmp_wrappers/new +OLD_DIRS+=usr/lib/clang/18/include/openmp_wrappers +OLD_FILES+=usr/lib/clang/18/include/orc_rt/c_api.h +OLD_DIRS+=usr/lib/clang/18/include/orc_rt +OLD_FILES+=usr/lib/clang/18/include/pconfigintrin.h +OLD_FILES+=usr/lib/clang/18/include/pkuintrin.h +OLD_FILES+=usr/lib/clang/18/include/pmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/popcntintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/bmi2intrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/bmiintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/emmintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/immintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/mm_malloc.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/mmintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/nmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/pmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/smmintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/tmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/x86gprintrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/x86intrin.h +OLD_FILES+=usr/lib/clang/18/include/ppc_wrappers/xmmintrin.h +OLD_DIRS+=usr/lib/clang/18/include/ppc_wrappers +OLD_FILES+=usr/lib/clang/18/include/prfchiintrin.h +OLD_FILES+=usr/lib/clang/18/include/prfchwintrin.h +OLD_FILES+=usr/lib/clang/18/include/profile/InstrProfData.inc +OLD_FILES+=usr/lib/clang/18/include/profile/MemProfData.inc +OLD_DIRS+=usr/lib/clang/18/include/profile +OLD_FILES+=usr/lib/clang/18/include/ptwriteintrin.h +OLD_FILES+=usr/lib/clang/18/include/raointintrin.h +OLD_FILES+=usr/lib/clang/18/include/rdpruintrin.h +OLD_FILES+=usr/lib/clang/18/include/rdseedintrin.h +OLD_FILES+=usr/lib/clang/18/include/riscv_bitmanip.h +OLD_FILES+=usr/lib/clang/18/include/riscv_crypto.h +OLD_FILES+=usr/lib/clang/18/include/riscv_ntlh.h +OLD_FILES+=usr/lib/clang/18/include/riscv_vector.h +OLD_FILES+=usr/lib/clang/18/include/rtmintrin.h +OLD_FILES+=usr/lib/clang/18/include/s390intrin.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/allocator_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/asan_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/common_interface_defs.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/coverage_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/dfsan_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/hwasan_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/linux_syscall_hooks.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/lsan_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/memprof_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/msan_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/netbsd_syscall_hooks.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/scudo_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/tsan_interface.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/tsan_interface_atomic.h +OLD_FILES+=usr/lib/clang/18/include/sanitizer/ubsan_interface.h +OLD_DIRS+=usr/lib/clang/18/include/sanitizer +OLD_FILES+=usr/lib/clang/18/include/serializeintrin.h +OLD_FILES+=usr/lib/clang/18/include/sgxintrin.h +OLD_FILES+=usr/lib/clang/18/include/sha512intrin.h +OLD_FILES+=usr/lib/clang/18/include/shaintrin.h +OLD_FILES+=usr/lib/clang/18/include/sifive_vector.h +OLD_FILES+=usr/lib/clang/18/include/sm3intrin.h +OLD_FILES+=usr/lib/clang/18/include/sm4intrin.h +OLD_FILES+=usr/lib/clang/18/include/smmintrin.h +OLD_FILES+=usr/lib/clang/18/include/stdalign.h +OLD_FILES+=usr/lib/clang/18/include/stdarg.h +OLD_FILES+=usr/lib/clang/18/include/stdatomic.h +OLD_FILES+=usr/lib/clang/18/include/stdbool.h +OLD_FILES+=usr/lib/clang/18/include/stdckdint.h +OLD_FILES+=usr/lib/clang/18/include/stddef.h +OLD_FILES+=usr/lib/clang/18/include/stdint.h +OLD_FILES+=usr/lib/clang/18/include/stdnoreturn.h +OLD_FILES+=usr/lib/clang/18/include/tbmintrin.h +OLD_FILES+=usr/lib/clang/18/include/tgmath.h +OLD_FILES+=usr/lib/clang/18/include/tmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/tsxldtrkintrin.h +OLD_FILES+=usr/lib/clang/18/include/uintrintrin.h +OLD_FILES+=usr/lib/clang/18/include/unwind.h +OLD_FILES+=usr/lib/clang/18/include/usermsrintrin.h +OLD_FILES+=usr/lib/clang/18/include/vadefs.h +OLD_FILES+=usr/lib/clang/18/include/vaesintrin.h +OLD_FILES+=usr/lib/clang/18/include/varargs.h +OLD_FILES+=usr/lib/clang/18/include/vecintrin.h +OLD_FILES+=usr/lib/clang/18/include/velintrin.h +OLD_FILES+=usr/lib/clang/18/include/velintrin_approx.h +OLD_FILES+=usr/lib/clang/18/include/velintrin_gen.h +OLD_FILES+=usr/lib/clang/18/include/vpclmulqdqintrin.h +OLD_FILES+=usr/lib/clang/18/include/waitpkgintrin.h +OLD_FILES+=usr/lib/clang/18/include/wasm_simd128.h +OLD_FILES+=usr/lib/clang/18/include/wbnoinvdintrin.h +OLD_FILES+=usr/lib/clang/18/include/wmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/x86gprintrin.h +OLD_FILES+=usr/lib/clang/18/include/x86intrin.h +OLD_FILES+=usr/lib/clang/18/include/xmmintrin.h +OLD_FILES+=usr/lib/clang/18/include/xopintrin.h +OLD_FILES+=usr/lib/clang/18/include/xray/xray_interface.h +OLD_FILES+=usr/lib/clang/18/include/xray/xray_log_interface.h +OLD_FILES+=usr/lib/clang/18/include/xray/xray_records.h +OLD_DIRS+=usr/lib/clang/18/include/xray +OLD_FILES+=usr/lib/clang/18/include/xsavecintrin.h +OLD_FILES+=usr/lib/clang/18/include/xsaveintrin.h +OLD_FILES+=usr/lib/clang/18/include/xsaveoptintrin.h +OLD_FILES+=usr/lib/clang/18/include/xsavesintrin.h +OLD_FILES+=usr/lib/clang/18/include/xtestintrin.h +OLD_DIRS+=usr/lib/clang/18/include +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-aarch64.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-arm.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-armhf.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-i386.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-powerpc64.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-powerpc64le.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-preinit-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-riscv64.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan-x86_64.so +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_cxx-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_static-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_static-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_static-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.asan_static-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi_diag-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi_diag-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi_diag-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi_diag-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.cfi_diag-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.dd-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.dd-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.fuzzer-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.fuzzer-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.fuzzer_interceptors-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan_cxx-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan_cxx-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan_cxx-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.msan_cxx-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-powerpc.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.profile-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.safestack-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.safestack-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.safestack-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.stats_client-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan_cxx-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan_cxx-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-powerpc64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-riscv64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-basic-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-basic-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-basic-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-basic-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-basic-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-fdr-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-fdr-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-fdr-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-fdr-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-fdr-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-profiling-aarch64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-profiling-arm.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-profiling-armhf.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-profiling-powerpc64le.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-profiling-x86_64.a +OLD_FILES+=usr/lib/clang/18/lib/freebsd/libclang_rt.xray-x86_64.a +OLD_DIRS+=usr/lib/clang/18/lib/freebsd +OLD_DIRS+=usr/lib/clang/18/lib +OLD_FILES+=usr/lib/clang/18/share/asan_ignorelist.txt +OLD_FILES+=usr/lib/clang/18/share/cfi_ignorelist.txt +OLD_FILES+=usr/lib/clang/18/share/msan_ignorelist.txt +OLD_DIRS+=usr/lib/clang/18/share +OLD_DIRS+=usr/lib/clang/18 + +# 20241023: new libc++ import which bumps version from 18 to 19 +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_any_all_none_of.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backend.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backend.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/any_of.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/backend.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/fill.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/find_if.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/for_each.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/libdispatch.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/merge.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/serial.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/stable_sort.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/thread.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/transform.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends/transform_reduce.h +OLD_DIRS+=usr/include/c++/v1/__algorithm/pstl_backends/cpu_backends +OLD_DIRS+=usr/include/c++/v1/__algorithm/pstl_backends +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_copy.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_count.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_equal.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_fill.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_find.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_for_each.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_frontend_dispatch.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_generate.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_is_partitioned.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_merge.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_move.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_replace.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_rotate_copy.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_sort.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_stable_sort.h +OLD_FILES+=usr/include/c++/v1/__algorithm/pstl_transform.h +OLD_FILES+=usr/include/c++/v1/__availability +OLD_FILES+=usr/include/c++/v1/__format/format_fwd.h +OLD_FILES+=usr/include/c++/v1/__fwd/get.h +OLD_FILES+=usr/include/c++/v1/__fwd/hash.h +OLD_FILES+=usr/include/c++/v1/__numeric/pstl_reduce.h +OLD_FILES+=usr/include/c++/v1/__numeric/pstl_transform_reduce.h +OLD_FILES+=usr/include/c++/v1/__threading_support +OLD_FILES+=usr/include/c++/v1/__tuple/pair_like.h +OLD_FILES+=usr/include/c++/v1/__type_traits/apply_cv.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_copy_assignable.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_copy_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_default_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_member_function_pointer.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_member_object_pointer.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_move_assignable.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_move_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_nothrow_copy_assignable.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_nothrow_copy_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_nothrow_default_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_nothrow_move_assignable.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_nothrow_move_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_scoped_enum.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_trivially_copy_assignable.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_trivially_copy_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_trivially_default_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_trivially_move_assignable.h +OLD_FILES+=usr/include/c++/v1/__type_traits/is_trivially_move_constructible.h +OLD_FILES+=usr/include/c++/v1/__type_traits/operation_traits.h +OLD_FILES+=usr/include/c++/v1/experimental/__memory + # 20241014: move divapp to netpfil/common/ OLD_FILES+=usr/tests/sys/netpfil/pf/divapp diff --git a/contrib/llvm-project/FREEBSD-Xlist b/contrib/llvm-project/FREEBSD-Xlist index 8b7bc5a40a4..45cd2c1d6f4 100644 --- a/contrib/llvm-project/FREEBSD-Xlist +++ b/contrib/llvm-project/FREEBSD-Xlist @@ -1,5 +1,3 @@ -.arcconfig -.arclint .ci/ .clang-format .clang-tidy @@ -29,7 +27,11 @@ clang/examples/ clang/include/CMakeLists.txt clang/include/clang/AST/CMakeLists.txt clang/include/clang/Basic/CMakeLists.txt +clang/include/clang/Basic/Target/ clang/include/clang/Basic/Version.inc.in +clang/include/clang/CIR/CMakeLists.txt +clang/include/clang/CIR/Dialect/CMakeLists.txt +clang/include/clang/CIR/Dialect/IR/CMakeLists.txt clang/include/clang/CMakeLists.txt clang/include/clang/Config/ clang/include/clang/Driver/CMakeLists.txt @@ -52,6 +54,9 @@ clang/lib/Analysis/plugins/CheckerDependencyHandling/CMakeLists.txt clang/lib/Analysis/plugins/CheckerOptionHandling/CMakeLists.txt clang/lib/Analysis/plugins/SampleAnalyzer/CMakeLists.txt clang/lib/Basic/CMakeLists.txt +clang/lib/CIR/CMakeLists.txt +clang/lib/CIR/Dialect/CMakeLists.txt +clang/lib/CIR/Dialect/IR/CMakeLists.txt clang/lib/CMakeLists.txt clang/lib/CodeGen/CMakeLists.txt clang/lib/CodeGen/README.txt @@ -68,6 +73,7 @@ clang/lib/FrontendTool/CMakeLists.txt clang/lib/Headers/CMakeLists.txt clang/lib/Index/CMakeLists.txt clang/lib/IndexSerialization/CMakeLists.txt +clang/lib/InstallAPI/CMakeLists.txt clang/lib/Interpreter/CMakeLists.txt clang/lib/Lex/CMakeLists.txt clang/lib/Parse/CMakeLists.txt @@ -85,8 +91,6 @@ clang/lib/Tooling/ASTDiff/CMakeLists.txt clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/Core/CMakeLists.txt clang/lib/Tooling/DependencyScanning/CMakeLists.txt -clang/lib/Tooling/DumpTool/CMakeLists.txt -clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py clang/lib/Tooling/Inclusions/CMakeLists.txt clang/lib/Tooling/Inclusions/Stdlib/CMakeLists.txt clang/lib/Tooling/Refactoring/CMakeLists.txt @@ -95,7 +99,7 @@ clang/lib/Tooling/Transformer/CMakeLists.txt clang/runtime/ clang/test/ clang/tools/CMakeLists.txt -clang/tools/amdgpu-arch/CMakeLists.txt +clang/tools/amdgpu-arch/ clang/tools/apinotes-test/ clang/tools/arcmt-test/ clang/tools/c-arcmt-test/ @@ -117,12 +121,14 @@ clang/tools/clang-format/git-clang-format.bat clang/tools/clang-format-vs/ clang/tools/clang-fuzzer/ clang/tools/clang-import-test/ +clang/tools/clang-installapi/ clang/tools/clang-linker-wrapper/ +clang/tools/clang-nvlink-wrapper/ clang/tools/clang-offload-bundler/ clang/tools/clang-offload-packager/ clang/tools/clang-refactor/ clang/tools/clang-rename/ -clang/tools/clang-repl/CMakeLists.txt +clang/tools/clang-repl/ clang/tools/clang-scan-deps/ clang/tools/clang-shlib/ clang/tools/diag-build/ @@ -131,7 +137,7 @@ clang/tools/driver/CMakeLists.txt clang/tools/driver/Info.plist.in clang/tools/include-mapping/ clang/tools/libclang/ -clang/tools/nvptx-arch/CMakeLists.txt +clang/tools/nvptx-arch/ clang/tools/scan-build/ clang/tools/scan-build-py/ clang/tools/scan-view/ @@ -139,7 +145,6 @@ clang/unittests/ clang/utils/ABITest/ clang/utils/CIndex/ clang/utils/CaptureCmd -clang/utils/ClangDataFormat.py clang/utils/ClangVisualizers/ clang/utils/CmpDriver clang/utils/FindSpecRefs @@ -153,7 +158,6 @@ clang/utils/bash-autocomplete.sh clang/utils/builtin-defines.c clang/utils/bundle_resources.py clang/utils/check_cfc/ -clang/utils/ci/ clang/utils/clangdiag.py clang/utils/convert_arm_neon.py clang/utils/creduce-clang-crash.py @@ -164,7 +168,6 @@ clang/utils/modfuzz.py clang/utils/module-deps-to-rsp.py clang/utils/perf-training/ clang/utils/token-delta.py -clang/utils/update_options_td_flags.py clang/utils/valgrind/ clang/www/ clang-tools-extra/ @@ -185,6 +188,8 @@ compiler-rt/lib/builtins/CMakeLists.txt compiler-rt/lib/builtins/Darwin-excludes/ compiler-rt/lib/builtins/macho_embedded/ compiler-rt/lib/cfi/CMakeLists.txt +compiler-rt/lib/ctx_profile/CMakeLists.txt +compiler-rt/lib/ctx_profile/tests/CMakeLists.txt compiler-rt/lib/dfsan/.clang-format compiler-rt/lib/dfsan/CMakeLists.txt compiler-rt/lib/dfsan/scripts/ @@ -211,11 +216,15 @@ compiler-rt/lib/memprof/tests/CMakeLists.txt compiler-rt/lib/msan/.clang-format compiler-rt/lib/msan/CMakeLists.txt compiler-rt/lib/msan/tests/ +compiler-rt/lib/nsan/CMakeLists.txt +compiler-rt/lib/nsan/tests/CMakeLists.txt compiler-rt/lib/orc/CMakeLists.txt compiler-rt/lib/orc/tests/CMakeLists.txt compiler-rt/lib/orc/tests/tools/CMakeLists.txt compiler-rt/lib/orc/tests/unit/CMakeLists.txt compiler-rt/lib/profile/CMakeLists.txt +compiler-rt/lib/rtsan/CMakeLists.txt +compiler-rt/lib/rtsan/tests/CMakeLists.txt compiler-rt/lib/safestack/.clang-format compiler-rt/lib/safestack/CMakeLists.txt compiler-rt/lib/sanitizer_common/.clang-format @@ -267,6 +276,7 @@ libcxx/include/__config_site.in libcxx/include/__support/ libcxx/lib/ libcxx/modules/CMakeLists.txt +libcxx/modules/CMakeLists.txt.in libcxx/modules/README.md libcxx/src/CMakeLists.txt libcxx/src/support/win32/ @@ -309,9 +319,6 @@ lldb/docs/conf.py lldb/docs/doxygen-mainpage.dox lldb/docs/doxygen.cfg.in lldb/docs/index.rst -lldb/docs/lldb-for-gdb-users.txt -lldb/docs/lldb-gdb-remote.txt -lldb/docs/lldb-platform-packets.txt lldb/docs/resources/ lldb/docs/testsuite/ lldb/docs/use/ @@ -483,7 +490,6 @@ lldb/source/Target/CMakeLists.txt lldb/source/Utility/CMakeLists.txt lldb/source/Version/CMakeLists.txt lldb/test/ -lldb/third_party/ lldb/tools/CMakeLists.txt lldb/tools/argdumper/CMakeLists.txt lldb/tools/darwin-debug/ @@ -548,6 +554,8 @@ llvm/lib/CodeGen/GlobalISel/CMakeLists.txt llvm/lib/CodeGen/MIRParser/CMakeLists.txt llvm/lib/CodeGen/README.txt llvm/lib/CodeGen/SelectionDAG/CMakeLists.txt +llvm/lib/CodeGenData/CMakeLists.txt +llvm/lib/CodeGenTypes/CMakeLists.txt llvm/lib/DWARFLinker/CMakeLists.txt llvm/lib/DWARFLinker/Classic/CMakeLists.txt llvm/lib/DWARFLinker/Parallel/CMakeLists.txt @@ -565,6 +573,7 @@ llvm/lib/Debuginfod/CMakeLists.txt llvm/lib/Demangle/CMakeLists.txt llvm/lib/ExecutionEngine/CMakeLists.txt llvm/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt +llvm/lib/ExecutionEngine/IntelJITProfiling/CMakeLists.txt llvm/lib/ExecutionEngine/Interpreter/CMakeLists.txt llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt llvm/lib/ExecutionEngine/MCJIT/CMakeLists.txt @@ -604,9 +613,11 @@ llvm/lib/Passes/CMakeLists.txt llvm/lib/ProfileData/CMakeLists.txt llvm/lib/ProfileData/Coverage/CMakeLists.txt llvm/lib/Remarks/CMakeLists.txt +llvm/lib/SandboxIR/CMakeLists.txt llvm/lib/Support/BLAKE3/.clang-format llvm/lib/Support/BLAKE3/CMakeLists.txt llvm/lib/Support/CMakeLists.txt +llvm/lib/Support/rpmalloc/ llvm/lib/TableGen/CMakeLists.txt llvm/lib/Target/AArch64/AsmParser/CMakeLists.txt llvm/lib/Target/AArch64/CMakeLists.txt @@ -614,6 +625,7 @@ llvm/lib/Target/AArch64/Disassembler/CMakeLists.txt llvm/lib/Target/AArch64/MCTargetDesc/CMakeLists.txt llvm/lib/Target/AArch64/TargetInfo/CMakeLists.txt llvm/lib/Target/AArch64/Utils/CMakeLists.txt +llvm/lib/Target/AArch64/peephole-sxtw.mir llvm/lib/Target/AMDGPU/AsmParser/CMakeLists.txt llvm/lib/Target/AMDGPU/CMakeLists.txt llvm/lib/Target/AMDGPU/Disassembler/CMakeLists.txt @@ -703,6 +715,7 @@ llvm/lib/Target/RISCV/Disassembler/CMakeLists.txt llvm/lib/Target/RISCV/MCA/CMakeLists.txt llvm/lib/Target/RISCV/MCTargetDesc/CMakeLists.txt llvm/lib/Target/RISCV/TargetInfo/CMakeLists.txt +llvm/lib/Target/SPIRV/Analysis/CMakeLists.txt llvm/lib/Target/SPIRV/CMakeLists.txt llvm/lib/Target/SPIRV/MCTargetDesc/CMakeLists.txt llvm/lib/Target/SPIRV/TargetInfo/CMakeLists.txt @@ -761,7 +774,6 @@ llvm/lib/Transforms/AggressiveInstCombine/CMakeLists.txt llvm/lib/Transforms/CFGuard/CMakeLists.txt llvm/lib/Transforms/CMakeLists.txt llvm/lib/Transforms/Coroutines/CMakeLists.txt -llvm/lib/Transforms/Hello/ llvm/lib/Transforms/HipStdPar/CMakeLists.txt llvm/lib/Transforms/IPO/CMakeLists.txt llvm/lib/Transforms/InstCombine/CMakeLists.txt @@ -773,7 +785,6 @@ llvm/lib/Transforms/Vectorize/CMakeLists.txt llvm/lib/WindowsDriver/CMakeLists.txt llvm/lib/WindowsManifest/CMakeLists.txt llvm/lib/XRay/CMakeLists.txt -llvm/llvm.spec.in llvm/projects/ llvm/resources/ llvm/runtimes/ @@ -794,6 +805,7 @@ llvm/tools/llvm-bcanalyzer/CMakeLists.txt llvm/tools/llvm-c-test/ llvm/tools/llvm-cat/ llvm/tools/llvm-cfi-verify/ +llvm/tools/llvm-cgdata/ llvm/tools/llvm-config/ llvm/tools/llvm-cov/CMakeLists.txt llvm/tools/llvm-cvtres/ @@ -866,6 +878,7 @@ llvm/tools/lto/ llvm/tools/obj2yaml/ llvm/tools/opt/CMakeLists.txt llvm/tools/opt-viewer/ +llvm/tools/reduce-chunk-list/ llvm/tools/remarks-shlib/ llvm/tools/sancov/ llvm/tools/sanstats/ @@ -885,8 +898,9 @@ llvm/utils/LLVMVisualizers/ llvm/utils/Misc/ llvm/utils/PerfectShuffle/ llvm/utils/Reviewing/ +llvm/utils/TableGen/Basic/CMakeLists.txt llvm/utils/TableGen/CMakeLists.txt -llvm/utils/TableGen/GlobalISel/CMakeLists.txt +llvm/utils/TableGen/Common/CMakeLists.txt llvm/utils/TableGen/README.md llvm/utils/TableGen/jupyter/ llvm/utils/TableGen/tdtags @@ -908,6 +922,7 @@ llvm/utils/codegen-diff llvm/utils/collect_and_build_with_pgo.py llvm/utils/convert-constraint-log-to-z3.py llvm/utils/count/ +llvm/utils/count_running_jobs.py llvm/utils/create_ladder_graph.py llvm/utils/crosstool/ llvm/utils/demangle_tree.py @@ -956,8 +971,7 @@ llvm/utils/schedcover.py llvm/utils/shuffle_fuzz.py llvm/utils/shuffle_select_fuzz_tester.py llvm/utils/sort_includes.py -llvm/utils/split-file/.clang-tidy -llvm/utils/split-file/CMakeLists.txt +llvm/utils/split-file/ llvm/utils/sysroot.py llvm/utils/testgen/ llvm/utils/textmate/ @@ -968,6 +982,7 @@ llvm/utils/update_cc_test_checks.py llvm/utils/update_llc_test_checks.py llvm/utils/update_mca_test_checks.py llvm/utils/update_mir_test_checks.py +llvm/utils/update_test_body.py llvm/utils/update_test_checks.py llvm/utils/update_test_prefix.py llvm/utils/valgrind/ @@ -977,13 +992,13 @@ llvm/utils/wciia.py llvm/utils/yaml-bench/ llvm-libgcc/ mlir/ +offload/ openmp/.gitignore openmp/CMakeLists.txt openmp/README.rst openmp/cmake/ openmp/docs/ openmp/libompd/ -openmp/libomptarget/ openmp/runtime/.clang-format openmp/runtime/.clang-tidy openmp/runtime/CMakeLists.txt @@ -997,6 +1012,7 @@ openmp/runtime/tools/ openmp/tools/ polly/ pstl/ +pyproject.toml runtimes/ third-party/ utils/ diff --git a/contrib/llvm-project/clang/include/clang-c/Index.h b/contrib/llvm-project/clang/include/clang-c/Index.h index 64ab3378957..115f5ab090f 100644 --- a/contrib/llvm-project/clang/include/clang-c/Index.h +++ b/contrib/llvm-project/clang/include/clang-c/Index.h @@ -1644,8 +1644,9 @@ enum CXCursorKind { CXCursor_ObjCSelfExpr = 146, /** OpenMP 5.0 [2.1.5, Array Section]. + * OpenACC 3.3 [2.7.1, Data Specification for Data Clauses (Sub Arrays)] */ - CXCursor_OMPArraySectionExpr = 147, + CXCursor_ArraySectionExpr = 147, /** Represents an @available(...) check. */ @@ -1675,7 +1676,7 @@ enum CXCursorKind { CXCursor_ConceptSpecializationExpr = 153, /** - * Expression that references a C++20 concept. + * Expression that references a C++20 requires expression. */ CXCursor_RequiresExpr = 154, @@ -1685,7 +1686,12 @@ enum CXCursorKind { */ CXCursor_CXXParenListInitExpr = 155, - CXCursor_LastExpr = CXCursor_CXXParenListInitExpr, + /** + * Represents a C++26 pack indexing expression. + */ + CXCursor_PackIndexingExpr = 156, + + CXCursor_LastExpr = CXCursor_PackIndexingExpr, /* Statements */ CXCursor_FirstStmt = 200, @@ -2140,7 +2146,23 @@ enum CXCursorKind { */ CXCursor_OMPScopeDirective = 306, - CXCursor_LastStmt = CXCursor_OMPScopeDirective, + /** OpenMP reverse directive. + */ + CXCursor_OMPReverseDirective = 307, + + /** OpenMP interchange directive. + */ + CXCursor_OMPInterchangeDirective = 308, + + /** OpenACC Compute Construct. + */ + CXCursor_OpenACCComputeConstruct = 320, + + /** OpenACC Loop Construct. + */ + CXCursor_OpenACCLoopConstruct = 321, + + CXCursor_LastStmt = CXCursor_OpenACCLoopConstruct, /** * Cursor that represents the translation unit itself. @@ -2981,6 +3003,8 @@ enum CXCallingConv { CXCallingConv_SwiftAsync = 17, CXCallingConv_AArch64SVEPCS = 18, CXCallingConv_M68kRTD = 19, + CXCallingConv_PreserveNone = 20, + CXCallingConv_RISCVVectorCall = 21, CXCallingConv_Invalid = 100, CXCallingConv_Unexposed = 200 @@ -3734,6 +3758,59 @@ enum CX_StorageClass { CX_SC_Register }; +/** + * Represents a specific kind of binary operator which can appear at a cursor. + */ +enum CX_BinaryOperatorKind { + CX_BO_Invalid = 0, + CX_BO_PtrMemD = 1, + CX_BO_PtrMemI = 2, + CX_BO_Mul = 3, + CX_BO_Div = 4, + CX_BO_Rem = 5, + CX_BO_Add = 6, + CX_BO_Sub = 7, + CX_BO_Shl = 8, + CX_BO_Shr = 9, + CX_BO_Cmp = 10, + CX_BO_LT = 11, + CX_BO_GT = 12, + CX_BO_LE = 13, + CX_BO_GE = 14, + CX_BO_EQ = 15, + CX_BO_NE = 16, + CX_BO_And = 17, + CX_BO_Xor = 18, + CX_BO_Or = 19, + CX_BO_LAnd = 20, + CX_BO_LOr = 21, + CX_BO_Assign = 22, + CX_BO_MulAssign = 23, + CX_BO_DivAssign = 24, + CX_BO_RemAssign = 25, + CX_BO_AddAssign = 26, + CX_BO_SubAssign = 27, + CX_BO_ShlAssign = 28, + CX_BO_ShrAssign = 29, + CX_BO_AndAssign = 30, + CX_BO_XorAssign = 31, + CX_BO_OrAssign = 32, + CX_BO_Comma = 33, + CX_BO_LAST = CX_BO_Comma +}; + +/** + * \brief Returns the operator code for the binary operator. + */ +CINDEX_LINKAGE enum CX_BinaryOperatorKind +clang_Cursor_getBinaryOpcode(CXCursor C); + +/** + * \brief Returns a string containing the spelling of the binary operator. + */ +CINDEX_LINKAGE CXString +clang_Cursor_getBinaryOpcodeStr(enum CX_BinaryOperatorKind Op); + /** * Returns the storage class for a function or variable declaration. * diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h index 18375c9e51a..98592438e90 100644 --- a/contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h +++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesManager.h @@ -9,7 +9,6 @@ #ifndef LLVM_CLANG_APINOTES_APINOTESMANAGER_H #define LLVM_CLANG_APINOTES_APINOTESMANAGER_H -#include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -24,6 +23,7 @@ namespace clang { class DirectoryEntry; class FileEntry; class LangOptions; +class Module; class SourceManager; namespace api_notes { diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h index 1c5aab09595..03657352c49 100644 --- a/contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h +++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesReader.h @@ -101,7 +101,7 @@ public: /// \param Name The name of the class we're looking for. /// /// \returns The information about the class, if known. - VersionedInfo lookupObjCClassInfo(llvm::StringRef Name); + VersionedInfo lookupObjCClassInfo(llvm::StringRef Name); /// Look for the context ID of the given Objective-C protocol. /// @@ -115,7 +115,7 @@ public: /// \param Name The name of the protocol we're looking for. /// /// \returns The information about the protocol, if known. - VersionedInfo lookupObjCProtocolInfo(llvm::StringRef Name); + VersionedInfo lookupObjCProtocolInfo(llvm::StringRef Name); /// Look for information regarding the given Objective-C property in /// the given context. @@ -141,6 +141,16 @@ public: ObjCSelectorRef Selector, bool IsInstanceMethod); + /// Look for information regarding the given C++ method in the given C++ tag + /// context. + /// + /// \param CtxID The ID that references the parent context, i.e. a C++ tag. + /// \param Name The name of the C++ method we're looking for. + /// + /// \returns Information about the method, if known. + VersionedInfo lookupCXXMethod(ContextID CtxID, + llvm::StringRef Name); + /// Look for information regarding the given global variable. /// /// \param Name The name of the global variable. @@ -166,6 +176,17 @@ public: /// \returns information about the enumerator, if known. VersionedInfo lookupEnumConstant(llvm::StringRef Name); + /// Look for the context ID of the given C++ tag. + /// + /// \param Name The name of the tag we're looking for. + /// \param ParentCtx The context in which this tag is declared, e.g. a C++ + /// namespace. + /// + /// \returns The ID, if known. + std::optional + lookupTagID(llvm::StringRef Name, + std::optional ParentCtx = std::nullopt); + /// Look for information regarding the given tag /// (struct/union/enum/C++ class). /// diff --git a/contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h b/contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h index dad44623e16..e0fe5eacef7 100644 --- a/contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h +++ b/contrib/llvm-project/clang/include/clang/APINotes/APINotesWriter.h @@ -5,7 +5,13 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// - +// +// This file defines the \c APINotesWriter class that writes out source +// API notes data providing additional information about source code as +// a separate input, such as the non-nil/nilable annotations for +// method parameters. +// +//===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_APINOTES_WRITER_H #define LLVM_CLANG_APINOTES_WRITER_H @@ -20,11 +26,16 @@ namespace clang { class FileEntry; namespace api_notes { + +/// A class that writes API notes data to a binary representation that can be +/// read by the \c APINotesReader. class APINotesWriter { class Implementation; std::unique_ptr Implementation; public: + /// Create a new API notes writer with the given module name and + /// (optional) source file. APINotesWriter(llvm::StringRef ModuleName, const FileEntry *SF); ~APINotesWriter(); @@ -42,10 +53,10 @@ public: /// /// \returns the ID of the class, protocol, or namespace, which can be used to /// add properties and methods to the class/protocol/namespace. - ContextID addObjCContext(std::optional ParentCtxID, - llvm::StringRef Name, ContextKind Kind, - const ObjCContextInfo &Info, - llvm::VersionTuple SwiftVersion); + ContextID addContext(std::optional ParentCtxID, + llvm::StringRef Name, ContextKind Kind, + const ContextInfo &Info, + llvm::VersionTuple SwiftVersion); /// Add information about a specific Objective-C property. /// @@ -67,6 +78,14 @@ public: bool IsInstanceMethod, const ObjCMethodInfo &Info, llvm::VersionTuple SwiftVersion); + /// Add information about a specific C++ method. + /// + /// \param CtxID The context in which this method resides, i.e. a C++ tag. + /// \param Name The name of the method. + /// \param Info Information about this method. + void addCXXMethod(ContextID CtxID, llvm::StringRef Name, + const CXXMethodInfo &Info, llvm::VersionTuple SwiftVersion); + /// Add information about a global variable. /// /// \param Name The name of this global variable. diff --git a/contrib/llvm-project/clang/include/clang/APINotes/Types.h b/contrib/llvm-project/clang/include/clang/APINotes/Types.h index 1d116becf06..c8e5e4df25d 100644 --- a/contrib/llvm-project/clang/include/clang/APINotes/Types.h +++ b/contrib/llvm-project/clang/include/clang/APINotes/Types.h @@ -55,16 +55,20 @@ public: std::string UnavailableMsg; /// Whether this entity is marked unavailable. + LLVM_PREFERRED_TYPE(bool) unsigned Unavailable : 1; /// Whether this entity is marked unavailable in Swift. + LLVM_PREFERRED_TYPE(bool) unsigned UnavailableInSwift : 1; private: /// Whether SwiftPrivate was specified. + LLVM_PREFERRED_TYPE(bool) unsigned SwiftPrivateSpecified : 1; /// Whether this entity is considered "private" to a Swift overlay. + LLVM_PREFERRED_TYPE(bool) unsigned SwiftPrivate : 1; public: @@ -188,25 +192,33 @@ inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) { return !(LHS == RHS); } -/// Describes API notes data for an Objective-C class or protocol. -class ObjCContextInfo : public CommonTypeInfo { +/// Describes API notes data for an Objective-C class or protocol or a C++ +/// namespace. +class ContextInfo : public CommonTypeInfo { /// Whether this class has a default nullability. + LLVM_PREFERRED_TYPE(bool) unsigned HasDefaultNullability : 1; /// The default nullability. + LLVM_PREFERRED_TYPE(NullabilityKind) unsigned DefaultNullability : 2; /// Whether this class has designated initializers recorded. + LLVM_PREFERRED_TYPE(bool) unsigned HasDesignatedInits : 1; + LLVM_PREFERRED_TYPE(bool) unsigned SwiftImportAsNonGenericSpecified : 1; + LLVM_PREFERRED_TYPE(bool) unsigned SwiftImportAsNonGeneric : 1; + LLVM_PREFERRED_TYPE(bool) unsigned SwiftObjCMembersSpecified : 1; + LLVM_PREFERRED_TYPE(bool) unsigned SwiftObjCMembers : 1; public: - ObjCContextInfo() + ContextInfo() : HasDefaultNullability(0), DefaultNullability(0), HasDesignatedInits(0), SwiftImportAsNonGenericSpecified(false), SwiftImportAsNonGeneric(false), SwiftObjCMembersSpecified(false), SwiftObjCMembers(false) {} @@ -251,16 +263,9 @@ public: SwiftObjCMembers = Value.value_or(false); } - /// Strip off any information within the class information structure that is - /// module-local, such as 'audited' flags. - void stripModuleLocalInfo() { - HasDefaultNullability = false; - DefaultNullability = 0; - } + friend bool operator==(const ContextInfo &, const ContextInfo &); - friend bool operator==(const ObjCContextInfo &, const ObjCContextInfo &); - - ObjCContextInfo &operator|=(const ObjCContextInfo &RHS) { + ContextInfo &operator|=(const ContextInfo &RHS) { // Merge inherited info. static_cast(*this) |= RHS; @@ -283,7 +288,7 @@ public: LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS); }; -inline bool operator==(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) { +inline bool operator==(const ContextInfo &LHS, const ContextInfo &RHS) { return static_cast(LHS) == RHS && LHS.getDefaultNullability() == RHS.getDefaultNullability() && LHS.HasDesignatedInits == RHS.HasDesignatedInits && @@ -291,17 +296,19 @@ inline bool operator==(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) { LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers(); } -inline bool operator!=(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) { +inline bool operator!=(const ContextInfo &LHS, const ContextInfo &RHS) { return !(LHS == RHS); } /// API notes for a variable/property. class VariableInfo : public CommonEntityInfo { /// Whether this property has been audited for nullability. + LLVM_PREFERRED_TYPE(bool) unsigned NullabilityAudited : 1; /// The kind of nullability for this property. Only valid if the nullability /// has been audited. + LLVM_PREFERRED_TYPE(NullabilityKind) unsigned Nullable : 2; /// The C type of the variable, as a string. @@ -352,7 +359,9 @@ inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) { /// Describes API notes data for an Objective-C property. class ObjCPropertyInfo : public VariableInfo { + LLVM_PREFERRED_TYPE(bool) unsigned SwiftImportAsAccessorsSpecified : 1; + LLVM_PREFERRED_TYPE(bool) unsigned SwiftImportAsAccessors : 1; public: @@ -372,7 +381,7 @@ public: friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &); /// Merge class-wide information into the given property. - ObjCPropertyInfo &operator|=(const ObjCContextInfo &RHS) { + ObjCPropertyInfo &operator|=(const ContextInfo &RHS) { static_cast(*this) |= RHS; // Merge nullability. @@ -409,9 +418,11 @@ inline bool operator!=(const ObjCPropertyInfo &LHS, /// Describes a function or method parameter. class ParamInfo : public VariableInfo { /// Whether noescape was specified. + LLVM_PREFERRED_TYPE(bool) unsigned NoEscapeSpecified : 1; /// Whether the this parameter has the 'noescape' attribute. + LLVM_PREFERRED_TYPE(bool) unsigned NoEscape : 1; /// A biased RetainCountConventionKind, where 0 means "unspecified". @@ -488,6 +499,7 @@ public: // unknown nullability. /// Whether the signature has been audited with respect to nullability. + LLVM_PREFERRED_TYPE(bool) unsigned NullabilityAudited : 1; /// Number of types whose nullability is encoded with the NullabilityPayload. @@ -597,16 +609,18 @@ inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { class ObjCMethodInfo : public FunctionInfo { public: /// Whether this is a designated initializer of its class. + LLVM_PREFERRED_TYPE(bool) unsigned DesignatedInit : 1; /// Whether this is a required initializer. + LLVM_PREFERRED_TYPE(bool) unsigned RequiredInit : 1; ObjCMethodInfo() : DesignatedInit(false), RequiredInit(false) {} friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &); - ObjCMethodInfo &operator|=(const ObjCContextInfo &RHS) { + ObjCMethodInfo &operator|=(const ContextInfo &RHS) { // Merge Nullability. if (!NullabilityAudited) { if (auto Nullable = RHS.getDefaultNullability()) { @@ -642,6 +656,12 @@ public: GlobalFunctionInfo() {} }; +/// Describes API notes data for a C++ method. +class CXXMethodInfo : public FunctionInfo { +public: + CXXMethodInfo() {} +}; + /// Describes API notes data for an enumerator. class EnumConstantInfo : public CommonEntityInfo { public: @@ -650,9 +670,16 @@ public: /// Describes API notes data for a tag. class TagInfo : public CommonTypeInfo { + LLVM_PREFERRED_TYPE(bool) unsigned HasFlagEnum : 1; + LLVM_PREFERRED_TYPE(bool) unsigned IsFlagEnum : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned SwiftCopyableSpecified : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned SwiftCopyable : 1; + public: std::optional SwiftImportAs; std::optional SwiftRetainOp; @@ -660,7 +687,9 @@ public: std::optional EnumExtensibility; - TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {} + TagInfo() + : HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false), + SwiftCopyable(false) {} std::optional isFlagEnum() const { if (HasFlagEnum) @@ -672,6 +701,15 @@ public: IsFlagEnum = Value.value_or(false); } + std::optional isSwiftCopyable() const { + return SwiftCopyableSpecified ? std::optional(SwiftCopyable) + : std::nullopt; + } + void setSwiftCopyable(std::optional Value) { + SwiftCopyableSpecified = Value.has_value(); + SwiftCopyable = Value.value_or(false); + } + TagInfo &operator|=(const TagInfo &RHS) { static_cast(*this) |= RHS; @@ -688,6 +726,9 @@ public: if (!EnumExtensibility) EnumExtensibility = RHS.EnumExtensibility; + if (!SwiftCopyableSpecified) + setSwiftCopyable(RHS.isSwiftCopyable()); + return *this; } @@ -702,6 +743,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) { LHS.SwiftRetainOp == RHS.SwiftRetainOp && LHS.SwiftReleaseOp == RHS.SwiftReleaseOp && LHS.isFlagEnum() == RHS.isFlagEnum() && + LHS.isSwiftCopyable() == RHS.isSwiftCopyable() && LHS.EnumExtensibility == RHS.EnumExtensibility; } @@ -753,6 +795,7 @@ enum class ContextKind : uint8_t { ObjCClass = 0, ObjCProtocol = 1, Namespace = 2, + Tag = 3, }; struct Context { diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h b/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h index 5f9aa41d3e6..3c5fdf81d4b 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h +++ b/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h @@ -53,11 +53,10 @@ public: bool IsSatisfied = false; bool ContainsErrors = false; - /// \brief Pairs of unsatisfied atomic constraint expressions along with the - /// substituted constraint expr, if the template arguments could be + /// \brief The substituted constraint expr, if the template arguments could be /// substituted into them, or a diagnostic if substitution resulted in an /// invalid expression. - llvm::SmallVector, 4> Details; + llvm::SmallVector Details; void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) { Profile(ID, C, ConstraintOwner, TemplateArgs); @@ -69,7 +68,7 @@ public: bool HasSubstitutionFailure() { for (const auto &Detail : Details) - if (Detail.second.dyn_cast()) + if (Detail.dyn_cast()) return true; return false; } @@ -80,9 +79,7 @@ public: /// substituted into them, or a diagnostic if substitution resulted in /// an invalid expression. using UnsatisfiedConstraintRecord = - std::pair *>>; + llvm::PointerUnion *>; /// \brief The result of a constraint satisfaction check, containing the /// necessary information to diagnose an unsatisfied constraint. diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h b/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h index ebcd8059284..447f2592d23 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h +++ b/contrib/llvm-project/clang/include/clang/AST/ASTConsumer.h @@ -23,6 +23,7 @@ namespace clang { class ASTDeserializationListener; // layering violation because void* is ugly class SemaConsumer; // layering violation required for safe SemaConsumer class TagDecl; + class DeclaratorDecl; class VarDecl; class FunctionDecl; class ImportDecl; @@ -105,7 +106,7 @@ public: /// CompleteExternalDeclaration - Callback invoked at the end of a translation /// unit to notify the consumer that the given external declaration should be /// completed. - virtual void CompleteExternalDeclaration(VarDecl *D) {} + virtual void CompleteExternalDeclaration(DeclaratorDecl *D) {} /// Callback invoked when an MSInheritanceAttr has been attached to a /// CXXRecordDecl. diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h b/contrib/llvm-project/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc..6d1c8ca8a2f 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTContext.h +++ b/contrib/llvm-project/clang/include/clang/AST/ASTContext.h @@ -37,6 +37,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/TypeSize.h" #include @@ -110,6 +111,9 @@ class VarTemplateDecl; class VTableContextBase; class XRayFunctionFilter; +/// A simple array of base specifiers. +typedef SmallVector CXXCastPath; + namespace Builtin { class Context; @@ -214,6 +218,9 @@ class ASTContext : public RefCountedBase { DependentTypeOfExprTypes; mutable llvm::ContextualFoldingSet DependentDecltypeTypes; + + mutable llvm::FoldingSet DependentPackIndexingTypes; + mutable llvm::FoldingSet TemplateTypeParmTypes; mutable llvm::FoldingSet ObjCTypeParamTypes; mutable llvm::FoldingSet @@ -247,6 +254,8 @@ class ASTContext : public RefCountedBase { DependentBitIntTypes; llvm::FoldingSet BTFTagAttributedTypes; + mutable llvm::FoldingSet CountAttributedTypes; + mutable llvm::FoldingSet QualifiedTemplateNames; mutable llvm::FoldingSet DependentTemplateNames; mutable llvm::FoldingSet @@ -255,6 +264,9 @@ class ASTContext : public RefCountedBase { ASTContext&> SubstTemplateTemplateParmPacks; + mutable llvm::ContextualFoldingSet + ArrayParameterTypes; + /// The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. @@ -447,7 +459,7 @@ class ASTContext : public RefCountedBase { /// initialization of another module). struct PerModuleInitializers { llvm::SmallVector Initializers; - llvm::SmallVector LazyInitializers; + llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); }; @@ -456,6 +468,14 @@ class ASTContext : public RefCountedBase { /// This is the top-level (C++20) Named module we are building. Module *CurrentCXXNamedModule = nullptr; + /// Help structures to decide whether two `const Module *` belongs + /// to the same conceptual module to avoid the expensive to string comparison + /// if possible. + /// + /// Not serialized intentionally. + llvm::StringMap PrimaryModuleNameMap; + llvm::DenseMap SameModuleLookupSet; + static constexpr unsigned ConstantArrayTypesLog2InitSize = 8; static constexpr unsigned GeneralTypesLog2InitSize = 9; static constexpr unsigned FunctionProtoTypesLog2InitSize = 12; @@ -623,6 +643,9 @@ private: /// address spaces (e.g. OpenCL/CUDA) bool AddrSpaceMapMangling; + /// For performance, track whether any function effects are in use. + mutable bool AnyFunctionEffects = false; + const TargetInfo *Target = nullptr; const TargetInfo *AuxTarget = nullptr; clang::PrintingPolicy PrintingPolicy; @@ -715,6 +738,12 @@ public: } void Deallocate(void *Ptr) const {} + llvm::StringRef backupStr(llvm::StringRef S) const { + char *Buf = new (*this) char[S.size()]; + std::copy(S.begin(), S.end(), Buf); + return llvm::StringRef(Buf, S.size()); + } + /// Allocates a \c DeclListNode or returns one from the \c ListNodeFreeList /// pool. DeclListNode *AllocateDeclListNode(clang::NamedDecl *ND) { @@ -1051,7 +1080,7 @@ public: /// or an ImportDecl nominating another module that has initializers. void addModuleInitializer(Module *M, Decl *Init); - void addLazyModuleInitializers(Module *M, ArrayRef IDs); + void addLazyModuleInitializers(Module *M, ArrayRef IDs); /// Get the initializations to perform when importing a module, if any. ArrayRef getModuleInitializers(Module *M); @@ -1062,6 +1091,12 @@ public: /// Get module under construction, nullptr if this is not a C++20 module. Module *getCurrentNamedModule() const { return CurrentCXXNamedModule; } + /// If the two module \p M1 and \p M2 are in the same module. + /// + /// FIXME: The signature may be confusing since `clang::Module` means to + /// a module fragment or a module unit but not a C++20 module. + bool isInSameModule(const Module *M1, const Module *M2); + TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl->getMostRecentDecl(); } @@ -1108,7 +1143,8 @@ public: CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; - CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; + CanQualType DependentTy, OverloadTy, BoundMemberTy, UnresolvedTemplateTy, + UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; @@ -1119,7 +1155,8 @@ public: CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; CanQualType IncompleteMatrixIdxTy; - CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy; + CanQualType ArraySectionTy; + CanQualType OMPArrayShapingTy, OMPIteratorTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" @@ -1134,6 +1171,8 @@ public: #include "clang/Basic/RISCVVTypes.def" #define WASM_TYPE(Name, Id, SingletonId) CanQualType SingletonId; #include "clang/Basic/WebAssemblyReferenceTypes.def" +#define AMDGPU_TYPE(Name, Id, SingletonId) CanQualType SingletonId; +#include "clang/Basic/AMDGPUTypes.def" // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. mutable QualType AutoDeductTy; // Deduction against 'auto'. @@ -1160,6 +1199,12 @@ public: /// in device compilation. llvm::DenseSet CUDAImplicitHostDeviceFunUsedByDevice; + /// For capturing lambdas with an explicit object parameter whose type is + /// derived from the lambda type, we need to perform derived-to-base + /// conversion so we can access the captures; the cast paths for that + /// are stored here. + llvm::DenseMap LambdaCastPaths; + ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins, TranslationUnitKind TUKind); @@ -1242,6 +1287,14 @@ public: /// space. QualType removeAddrSpaceQualType(QualType T) const; + /// Return the "other" discriminator used for the pointer auth schema used for + /// vtable pointers in instances of the requested type. + uint16_t + getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD); + + /// Return the "other" type-specific discriminator for the given type. + uint16_t getPointerAuthTypeDiscriminator(QualType T); + /// Apply Objective-C protocol qualifiers to the given type. /// \param allowOnPointerType specifies if we can apply protocol /// qualifiers on ObjCObjectPointerType. It can be set to true when @@ -1338,6 +1391,11 @@ public: return CanQualType::CreateUnsafe(getPointerType((QualType) T)); } + QualType + getCountAttributedType(QualType T, Expr *CountExpr, bool CountInBytes, + bool OrNull, + ArrayRef DependentDecls) const; + /// Return the uniqued reference to a type adjusted from the original /// type to a new type. QualType getAdjustedType(QualType Orig, QualType New) const; @@ -1357,6 +1415,10 @@ public: /// type to the decayed type. QualType getDecayedType(QualType Orig, QualType Decayed) const; + /// Return the uniqued reference to a specified array parameter type from the + /// original array type. + QualType getArrayParameterType(QualType Ty) const; + /// Return the uniqued reference to the atomic type for the specified /// type. QualType getAtomicType(QualType T) const; @@ -1713,6 +1775,11 @@ public: /// C++11 decltype. QualType getDecltypeType(Expr *e, QualType UnderlyingType) const; + QualType getPackIndexingType(QualType Pattern, Expr *IndexExpr, + bool FullySubstituted = false, + ArrayRef Expansions = {}, + int Index = -1) const; + /// Unary type transforms QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType, UnaryTransformType::UTTKind UKind) const; @@ -1738,6 +1805,13 @@ public: QualType DeducedType, bool IsDependent) const; +private: + QualType getDeducedTemplateSpecializationTypeInternal(TemplateName Template, + QualType DeducedType, + bool IsDependent, + QualType Canon) const; + +public: /// Return the unique reference to the type for the specified TagDecl /// (struct/union/class/enum) decl. QualType getTagDeclType(const TagDecl *Decl) const; @@ -2174,6 +2248,16 @@ public: return getQualifiedType(type.getUnqualifiedType(), Qs); } + /// \brief Return a type with the given __ptrauth qualifier. + QualType getPointerAuthType(QualType Ty, PointerAuthQualifier PointerAuth) { + assert(!Ty.getPointerAuth()); + assert(PointerAuth); + + Qualifiers Qs; + Qs.setPointerAuth(PointerAuth); + return getQualifiedType(Ty, Qs); + } + unsigned char getFixedPointScale(QualType Ty) const; unsigned char getFixedPointIBits(QualType Ty) const; llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const; @@ -2405,12 +2489,18 @@ public: unsigned getTargetDefaultAlignForAttributeAligned() const; /// Return the alignment in bits that should be given to a - /// global variable with type \p T. - unsigned getAlignOfGlobalVar(QualType T) const; + /// global variable with type \p T. If \p VD is non-null it will be + /// considered specifically for the query. + unsigned getAlignOfGlobalVar(QualType T, const VarDecl *VD) const; /// Return the alignment in characters that should be given to a - /// global variable with type \p T. - CharUnits getAlignOfGlobalVarInChars(QualType T) const; + /// global variable with type \p T. If \p VD is non-null it will be + /// considered specifically for the query. + CharUnits getAlignOfGlobalVarInChars(QualType T, const VarDecl *VD) const; + + /// Return the minimum alignement as specified by the target. If \p VD is + /// non-null it may be used to identify external or weak variables. + unsigned getMinGlobalAlignOfVar(uint64_t Size, const VarDecl *VD) const; /// Return a conservative estimate of the alignment of the specified /// decl \p D. @@ -2571,7 +2661,11 @@ public: /// /// \returns if this is an array type, the completely unqualified array type /// that corresponds to it. Otherwise, returns T.getUnqualifiedType(). - QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals); + QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const; + QualType getUnqualifiedArrayType(QualType T) const { + Qualifiers Quals; + return getUnqualifiedArrayType(T, Quals); + } /// Determine whether the given types are equivalent after /// cvr-qualifiers have been removed. @@ -2824,6 +2918,8 @@ public: return AddrSpaceMapMangling || isTargetAddressSpace(AS); } + bool hasAnyFunctionEffects() const { return AnyFunctionEffects; } + // Merges two exception specifications, such that the resulting // exception spec is the union of both. For example, if either // of them can throw something, the result can throw it as well. @@ -2967,6 +3063,10 @@ public: // corresponding saturated type for a given fixed point type. QualType getCorrespondingSaturatedType(QualType Ty) const; + // Per ISO N1169, this method accepts fixed point types and returns the + // corresponding non-saturated type for a given fixed point type. + QualType getCorrespondingUnsaturatedType(QualType Ty) const; + // This method accepts fixed point types and returns the corresponding signed // type. Unlike getCorrespondingUnsignedType(), this only accepts unsigned // fixed point types because there are unsigned integer types like bool and @@ -3150,9 +3250,6 @@ public: /// valid feature names. ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const; - std::vector - filterFunctionTargetVersionAttrs(const TargetVersionAttr *TV) const; - void getFunctionFeatureMap(llvm::StringMap &FeatureMap, const FunctionDecl *) const; void getFunctionFeatureMap(llvm::StringMap &FeatureMap, @@ -3365,12 +3462,21 @@ public: /// Whether a C++ static variable or CUDA/HIP kernel should be externalized. bool shouldExternalize(const Decl *D) const; + /// Resolve the root record to be used to derive the vtable pointer + /// authentication policy for the specified record. + const CXXRecordDecl * + baseForVTableAuthentication(const CXXRecordDecl *ThisClass); + bool useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl, + StringRef MangledName); + StringRef getCUIDHash() const; private: /// All OMPTraitInfo objects live in this collection, one per /// `pragma omp [begin] declare variant` directive. SmallVector, 4> OMPTraitInfoVector; + + llvm::DenseMap> ThunksToBeAbbreviated; }; /// Insertion operator for diagnostics. @@ -3379,13 +3485,13 @@ const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, /// Utility function for constructing a nullary selector. inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) { - IdentifierInfo* II = &Ctx.Idents.get(name); + const IdentifierInfo *II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(0, &II); } /// Utility function for constructing an unary selector. inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) { - IdentifierInfo* II = &Ctx.Idents.get(name); + const IdentifierInfo *II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(1, &II); } diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTMutationListener.h b/contrib/llvm-project/clang/include/clang/AST/ASTMutationListener.h index 8879f9f3229..2c4ec2ce67f 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTMutationListener.h +++ b/contrib/llvm-project/clang/include/clang/AST/ASTMutationListener.h @@ -27,6 +27,7 @@ namespace clang { class FunctionTemplateDecl; class Module; class NamedDecl; + class NamespaceDecl; class ObjCCategoryDecl; class ObjCContainerDecl; class ObjCInterfaceDecl; @@ -35,6 +36,7 @@ namespace clang { class QualType; class RecordDecl; class TagDecl; + class TranslationUnitDecl; class ValueDecl; class VarDecl; class VarTemplateDecl; @@ -147,6 +149,31 @@ public: virtual void AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) {} + /// The parser find the named module declaration. + virtual void EnteringModulePurview() {} + + /// An mangling number was added to a Decl + /// + /// \param D The decl that got a mangling number + /// + /// \param Number The mangling number that was added to the Decl + virtual void AddedManglingNumber(const Decl *D, unsigned Number) {} + + /// An static local number was added to a Decl + /// + /// \param D The decl that got a static local number + /// + /// \param Number The static local number that was added to the Decl + virtual void AddedStaticLocalNumbers(const Decl *D, unsigned Number) {} + + /// An anonymous namespace was added the translation unit decl + /// + /// \param TU The translation unit decl that got a new anonymous namespace + /// + /// \param AnonNamespace The anonymous namespace that was added + virtual void AddedAnonymousNamespace(const TranslationUnitDecl *TU, + NamespaceDecl *AnonNamespace) {} + // NOTE: If new methods are added they should also be added to // MultiplexASTMutationListener. }; diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h b/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h index cc8dab97f8b..616f92691ec 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h +++ b/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h @@ -23,7 +23,9 @@ #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" #include "clang/AST/Type.h" +#include "clang/AST/TypeLocVisitor.h" #include "clang/AST/TypeVisitor.h" +#include "llvm/Support/SaveAndRestore.h" namespace clang { @@ -48,8 +50,10 @@ struct { void Visit(const Stmt *Node); void Visit(const Type *T); void Visit(QualType T); + void Visit(TypeLoc); void Visit(const Decl *D); void Visit(const CXXCtorInitializer *Init); + void Visit(const OpenACCClause *C); void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); @@ -64,6 +68,7 @@ class ASTNodeTraverser public comments::ConstCommentVisitor, public TypeVisitor, + public TypeLocVisitor, public ConstAttrVisitor, public ConstTemplateArgumentVisitor { @@ -71,6 +76,14 @@ class ASTNodeTraverser /// not already been loaded. bool Deserialize = false; + /// Tracks whether we should dump TypeLocs etc. + /// + /// Detailed location information such as TypeLoc nodes is not usually + /// included in the dump (too verbose). + /// But when explicitly asked to dump a Loc node, we do so recursively, + /// including e.g. FunctionTypeLoc => ParmVarDecl => TypeLoc. + bool VisitLocs = false; + TraversalKind Traversal = TraversalKind::TK_AsIs; NodeDelegateType &getNodeDelegate() { @@ -85,7 +98,7 @@ public: void SetTraversalKind(TraversalKind TK) { Traversal = TK; } TraversalKind GetTraversalKind() const { return Traversal; } - void Visit(const Decl *D) { + void Visit(const Decl *D, bool VisitLocs = false) { if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isImplicit()) return; @@ -94,7 +107,10 @@ public: if (!D) return; - ConstDeclVisitor::Visit(D); + { + llvm::SaveAndRestore RestoreVisitLocs(this->VisitLocs, VisitLocs); + ConstDeclVisitor::Visit(D); + } for (const auto &A : D->attrs()) Visit(A); @@ -181,6 +197,17 @@ public: }); } + void Visit(TypeLoc T) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(T); + if (T.isNull()) + return; + TypeLocVisitor::Visit(T); + if (auto Inner = T.getNextTypeLoc()) + Visit(Inner); + }); + } + void Visit(const Attr *A) { getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(A); @@ -213,6 +240,14 @@ public: }); } + void Visit(const OpenACCClause *C) { + getNodeDelegate().AddChild([=] { + getNodeDelegate().Visit(C); + for (const auto *S : C->children()) + Visit(S); + }); + } + void Visit(const OMPClause *C) { getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(C); @@ -286,6 +321,8 @@ public: Visit(*QT); else if (const auto *T = N.get()) Visit(T); + else if (const auto *TL = N.get()) + Visit(*TL); else if (const auto *C = N.get()) Visit(C); else if (const auto *C = N.get()) @@ -346,7 +383,7 @@ public: void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); } void VisitLocInfoType(const LocInfoType *T) { - Visit(T->getTypeSourceInfo()->getType()); + Visit(T->getTypeSourceInfo()->getTypeLoc()); } void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); } void VisitBlockPointerType(const BlockPointerType *T) { @@ -385,6 +422,12 @@ public: void VisitDecltypeType(const DecltypeType *T) { Visit(T->getUnderlyingExpr()); } + + void VisitPackIndexingType(const PackIndexingType *T) { + Visit(T->getPattern()); + Visit(T->getIndexExpr()); + } + void VisitUnaryTransformType(const UnaryTransformType *T) { Visit(T->getBaseType()); } @@ -415,9 +458,55 @@ public: if (!T->isSugared()) Visit(T->getPattern()); } + void VisitAutoType(const AutoType *T) { + for (const auto &Arg : T->getTypeConstraintArguments()) + Visit(Arg); + } // FIXME: ElaboratedType, DependentNameType, // DependentTemplateSpecializationType, ObjCObjectType + // For TypeLocs, we automatically visit the inner type loc (pointee type etc). + // We must explicitly visit other lexically-nested nodes. + void VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { + TypeLocVisitor::VisitFunctionTypeLoc(TL); + for (const auto *Param : TL.getParams()) + Visit(Param, /*VisitTypeLocs=*/true); + } + void VisitAutoTypeLoc(AutoTypeLoc TL) { + if (const auto *CR = TL.getConceptReference()) { + if (auto *Args = CR->getTemplateArgsAsWritten()) + for (const auto &Arg : Args->arguments()) + dumpTemplateArgumentLoc(Arg); + } + } + void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { + Visit(TL.getClassTInfo()->getTypeLoc()); + } + void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { + Visit(TL.getSizeExpr()); + } + void VisitDependentSizedArrayTypeLoc(DependentSizedArrayTypeLoc TL) { + Visit(TL.getSizeExpr()); + } + void VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) { + Visit(cast(TL.getType())->getSizeExpr()); + } + void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { + Visit(TL.getUnderlyingExpr()); + } + void VisitDecltypeType(DecltypeType TL) { + Visit(TL.getUnderlyingExpr()); + } + void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) { + for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I) + dumpTemplateArgumentLoc(TL.getArgLoc(I)); + } + void VisitDependentTemplateSpecializationTypeLoc( + DependentTemplateSpecializationTypeLoc TL) { + for (unsigned I=0, N=TL.getNumArgs(); I < N; ++I) + dumpTemplateArgumentLoc(TL.getArgLoc(I)); + } + void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); } void VisitEnumConstantDecl(const EnumConstantDecl *D) { @@ -462,6 +551,8 @@ public: if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isCXXForRangeDecl()) return; + if (const auto *TSI = D->getTypeSourceInfo(); VisitLocs && TSI) + Visit(TSI->getTypeLoc()); if (D->hasInit()) Visit(D->getInit()); } @@ -604,7 +695,7 @@ public: if (const auto *TC = D->getTypeConstraint()) Visit(TC->getImmediatelyDeclaredConstraint()); if (D->hasDefaultArgument()) - Visit(D->getDefaultArgument(), SourceRange(), + Visit(D->getDefaultArgument().getArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), D->defaultArgumentWasInherited() ? "inherited from" : "previous"); } @@ -613,9 +704,9 @@ public: if (const auto *E = D->getPlaceholderTypeConstraint()) Visit(E); if (D->hasDefaultArgument()) - Visit(D->getDefaultArgument(), SourceRange(), - D->getDefaultArgStorage().getInheritedFrom(), - D->defaultArgumentWasInherited() ? "inherited from" : "previous"); + dumpTemplateArgumentLoc( + D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); } void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) { @@ -717,6 +808,11 @@ public: Visit(C); } + void VisitOpenACCConstructStmt(const OpenACCConstructStmt *Node) { + for (const auto *C : Node->clauses()) + Visit(C); + } + void VisitInitListExpr(const InitListExpr *ILE) { if (auto *Filler = ILE->getArrayFiller()) { Visit(Filler, "array_filler"); @@ -748,6 +844,12 @@ public: } } + void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *E) { + if (E->hasExplicitTemplateArgs()) + for (auto Arg : E->template_arguments()) + Visit(Arg.getArgument()); + } + void VisitRequiresExpr(const RequiresExpr *E) { for (auto *D : E->getLocalParameters()) Visit(D); @@ -755,6 +857,12 @@ public: Visit(R); } + void VisitTypeTraitExpr(const TypeTraitExpr *E) { + // Argument types are not children of the TypeTraitExpr. + for (auto *A : E->getArgs()) + Visit(A->getType()); + } + void VisitLambdaExpr(const LambdaExpr *Node) { if (Traversal == TK_IgnoreUnlessSpelledInSource) { for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { @@ -837,6 +945,14 @@ public: Visit(TArg); } + void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) { + Visit(Node->getExpr()); + } + + void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) { + Visit(Node->getExpr()); + } + // Implements Visit methods for Attrs. #include "clang/AST/AttrNodeTraverse.inc" }; diff --git a/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h b/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h index 398ffb188c9..3838dcb61ee 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h +++ b/contrib/llvm-project/clang/include/clang/AST/ASTUnresolvedSet.h @@ -16,6 +16,7 @@ #include "clang/AST/ASTVector.h" #include "clang/AST/DeclAccessPair.h" +#include "clang/AST/DeclID.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Basic/Specifiers.h" #include @@ -56,6 +57,10 @@ public: Decls.push_back(DeclAccessPair::make(D, AS), C); } + void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) { + Decls.push_back(DeclAccessPair::makeLazy(ID.getRawValue(), AS), C); + } + /// Replaces the given declaration with the new one, once. /// /// \return true if the set changed @@ -109,10 +114,10 @@ public: void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } - void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) { + void addLazyDecl(ASTContext &C, GlobalDeclID ID, AccessSpecifier AS) { assert(Impl.empty() || Impl.Decls.isLazy()); Impl.Decls.setLazy(true); - Impl.addDecl(C, reinterpret_cast(ID << 2), AS); + Impl.addLazyDecl(C, ID, AS); } }; diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h index 1f2797cc701..4b627c65e27 100644 --- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h +++ b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicReader.h @@ -213,9 +213,9 @@ public: } Qualifiers readQualifiers() { - static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t), + static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint64_t), "update this if the value size changes"); - uint32_t value = asImpl().readUInt32(); + uint64_t value = asImpl().readUInt64(); return Qualifiers::fromOpaqueValue(value); } @@ -244,6 +244,15 @@ public: return FunctionProtoType::ExtParameterInfo::getFromOpaqueValue(value); } + FunctionEffect readFunctionEffect() { + uint32_t value = asImpl().readUInt32(); + return FunctionEffect::fromOpaqueInt32(value); + } + + EffectConditionExpr readEffectConditionExpr() { + return EffectConditionExpr{asImpl().readExprRef()}; + } + NestedNameSpecifier *readNestedNameSpecifier() { auto &ctx = getASTContext(); diff --git a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h index 07afa388de2..b941add8bde 100644 --- a/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h +++ b/contrib/llvm-project/clang/include/clang/AST/AbstractBasicWriter.h @@ -196,9 +196,9 @@ public: } void writeQualifiers(Qualifiers value) { - static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t), + static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint64_t), "update this if the value size changes"); - asImpl().writeUInt32(value.getAsOpaqueValue()); + asImpl().writeUInt64(value.getAsOpaqueValue()); } void writeExceptionSpecInfo( @@ -222,6 +222,14 @@ public: asImpl().writeUInt32(epi.getOpaqueValue()); } + void writeFunctionEffect(FunctionEffect E) { + asImpl().writeUInt32(E.toOpaqueInt32()); + } + + void writeEffectConditionExpr(EffectConditionExpr CE) { + asImpl().writeExprRef(CE.getCondition()); + } + void writeNestedNameSpecifier(NestedNameSpecifier *NNS) { // Nested name specifiers usually aren't too long. I think that 8 would // typically accommodate the vast majority. diff --git a/contrib/llvm-project/clang/include/clang/AST/Availability.h b/contrib/llvm-project/clang/include/clang/AST/Availability.h index 527fc4b59a5..26ae622e5b4 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Availability.h +++ b/contrib/llvm-project/clang/include/clang/AST/Availability.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_AVAILABILITY_H #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/VersionTuple.h" @@ -57,6 +58,68 @@ public: bool isOtherPlatformSpec() const { return Version.empty(); } }; +class Decl; + +/// Storage of availability attributes for a declaration. +struct AvailabilityInfo { + /// The domain is the platform for which this availability info applies to. + llvm::SmallString<32> Domain; + VersionTuple Introduced; + VersionTuple Deprecated; + VersionTuple Obsoleted; + bool Unavailable = false; + bool UnconditionallyDeprecated = false; + bool UnconditionallyUnavailable = false; + + AvailabilityInfo() = default; + + /// Determine if this AvailabilityInfo represents the default availability. + bool isDefault() const { return *this == AvailabilityInfo(); } + + /// Check if the symbol has been obsoleted. + bool isObsoleted() const { return !Obsoleted.empty(); } + + /// Check if the symbol is unavailable unconditionally or + /// on the active platform and os version. + bool isUnavailable() const { + return Unavailable || isUnconditionallyUnavailable(); + } + + /// Check if the symbol is unconditionally deprecated. + /// + /// i.e. \code __attribute__((deprecated)) \endcode + bool isUnconditionallyDeprecated() const { return UnconditionallyDeprecated; } + + /// Check if the symbol is unconditionally unavailable. + /// + /// i.e. \code __attribute__((unavailable)) \endcode + bool isUnconditionallyUnavailable() const { + return UnconditionallyUnavailable; + } + + AvailabilityInfo(StringRef Domain, VersionTuple I, VersionTuple D, + VersionTuple O, bool U, bool UD, bool UU) + : Domain(Domain), Introduced(I), Deprecated(D), Obsoleted(O), + Unavailable(U), UnconditionallyDeprecated(UD), + UnconditionallyUnavailable(UU) {} + + friend bool operator==(const AvailabilityInfo &Lhs, + const AvailabilityInfo &Rhs); + +public: + static AvailabilityInfo createFromDecl(const Decl *Decl); +}; + +inline bool operator==(const AvailabilityInfo &Lhs, + const AvailabilityInfo &Rhs) { + return std::tie(Lhs.Introduced, Lhs.Deprecated, Lhs.Obsoleted, + Lhs.Unavailable, Lhs.UnconditionallyDeprecated, + Lhs.UnconditionallyUnavailable) == + std::tie(Rhs.Introduced, Rhs.Deprecated, Rhs.Obsoleted, + Rhs.Unavailable, Rhs.UnconditionallyDeprecated, + Rhs.UnconditionallyUnavailable); +} + } // end namespace clang #endif diff --git a/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def b/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f127..444be4311a7 100644 --- a/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def +++ b/contrib/llvm-project/clang/include/clang/AST/BuiltinTypes.def @@ -285,6 +285,9 @@ PLACEHOLDER_TYPE(Overload, OverloadTy) // x->foo # if only contains non-static members PLACEHOLDER_TYPE(BoundMember, BoundMemberTy) +// The type of an unresolved template. Used in UnresolvedLookupExpr. +PLACEHOLDER_TYPE(UnresolvedTemplate, UnresolvedTemplateTy) + // The type of an expression which refers to a pseudo-object, // such as those introduced by Objective C's @property or // VS.NET's __property declarations. A placeholder type. The @@ -320,7 +323,7 @@ PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) PLACEHOLDER_TYPE(IncompleteMatrixIdx, IncompleteMatrixIdxTy) // A placeholder type for OpenMP array sections. -PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) +PLACEHOLDER_TYPE(ArraySection, ArraySectionTy) // A placeholder type for OpenMP array shaping operation. PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentCommandTraits.h b/contrib/llvm-project/clang/include/clang/AST/CommentCommandTraits.h index 83a29a540d4..78c484fff3a 100644 --- a/contrib/llvm-project/clang/include/clang/AST/CommentCommandTraits.h +++ b/contrib/llvm-project/clang/include/clang/AST/CommentCommandTraits.h @@ -50,52 +50,69 @@ struct CommandInfo { unsigned NumArgs : 4; /// True if this command is a inline command (of any kind). + LLVM_PREFERRED_TYPE(bool) unsigned IsInlineCommand : 1; /// True if this command is a block command (of any kind). + LLVM_PREFERRED_TYPE(bool) unsigned IsBlockCommand : 1; /// True if this command is introducing a brief documentation /// paragraph (\or an alias). + LLVM_PREFERRED_TYPE(bool) unsigned IsBriefCommand : 1; /// True if this command is \\returns or an alias. + LLVM_PREFERRED_TYPE(bool) unsigned IsReturnsCommand : 1; /// True if this command is introducing documentation for a function /// parameter (\\param or an alias). + LLVM_PREFERRED_TYPE(bool) unsigned IsParamCommand : 1; /// True if this command is introducing documentation for /// a template parameter (\\tparam or an alias). + LLVM_PREFERRED_TYPE(bool) unsigned IsTParamCommand : 1; /// True if this command is \\throws or an alias. + LLVM_PREFERRED_TYPE(bool) unsigned IsThrowsCommand : 1; /// True if this command is \\deprecated or an alias. + LLVM_PREFERRED_TYPE(bool) unsigned IsDeprecatedCommand : 1; /// True if this is a \\headerfile-like command. + LLVM_PREFERRED_TYPE(bool) unsigned IsHeaderfileCommand : 1; + /// True if this is a \\par command. + LLVM_PREFERRED_TYPE(bool) + unsigned IsParCommand : 1; + /// True if we don't want to warn about this command being passed an empty /// paragraph. Meaningful only for block commands. + LLVM_PREFERRED_TYPE(bool) unsigned IsEmptyParagraphAllowed : 1; /// True if this command is a verbatim-like block command. /// /// A verbatim-like block command eats every character (except line starting /// decorations) until matching end command is seen or comment end is hit. + LLVM_PREFERRED_TYPE(bool) unsigned IsVerbatimBlockCommand : 1; /// True if this command is an end command for a verbatim-like block. + LLVM_PREFERRED_TYPE(bool) unsigned IsVerbatimBlockEndCommand : 1; /// True if this command is a verbatim line command. /// /// A verbatim-like line command eats everything until a newline is seen or /// comment end is hit. + LLVM_PREFERRED_TYPE(bool) unsigned IsVerbatimLineCommand : 1; /// True if this command contains a declaration for the entity being @@ -105,20 +122,25 @@ struct CommandInfo { /// \code /// \fn void f(int a); /// \endcode + LLVM_PREFERRED_TYPE(bool) unsigned IsDeclarationCommand : 1; /// True if verbatim-like line command is a function declaration. + LLVM_PREFERRED_TYPE(bool) unsigned IsFunctionDeclarationCommand : 1; /// True if block command is further describing a container API; such /// as \@coclass, \@classdesign, etc. + LLVM_PREFERRED_TYPE(bool) unsigned IsRecordLikeDetailCommand : 1; /// True if block command is a container API; such as \@interface. + LLVM_PREFERRED_TYPE(bool) unsigned IsRecordLikeDeclarationCommand : 1; /// True if this command is unknown. This \c CommandInfo object was /// created during parsing. + LLVM_PREFERRED_TYPE(bool) unsigned IsUnknownCommand : 1; }; diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td b/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td index e839031752c..a410cd4039b 100644 --- a/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td +++ b/contrib/llvm-project/clang/include/clang/AST/CommentCommands.td @@ -18,6 +18,7 @@ class Command { bit IsThrowsCommand = 0; bit IsDeprecatedCommand = 0; bit IsHeaderfileCommand = 0; + bit IsParCommand = 0; bit IsEmptyParagraphAllowed = 0; @@ -132,9 +133,9 @@ def Tparam : BlockCommand<"tparam"> { let IsTParamCommand = 1; } // HeaderDoc command for template parameter documentation. def Templatefield : BlockCommand<"templatefield"> { let IsTParamCommand = 1; } -def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; } -def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; } -def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; } +def Throws : BlockCommand<"throws"> { let IsThrowsCommand = 1; let NumArgs = 1; } +def Throw : BlockCommand<"throw"> { let IsThrowsCommand = 1; let NumArgs = 1; } +def Exception : BlockCommand<"exception"> { let IsThrowsCommand = 1; let NumArgs = 1;} def Deprecated : BlockCommand<"deprecated"> { let IsEmptyParagraphAllowed = 1; @@ -156,7 +157,7 @@ def Date : BlockCommand<"date">; def Invariant : BlockCommand<"invariant">; def Li : BlockCommand<"li">; def Note : BlockCommand<"note">; -def Par : BlockCommand<"par">; +def Par : BlockCommand<"par"> { let IsParCommand = 1; let NumArgs = 1; } def Post : BlockCommand<"post">; def Pre : BlockCommand<"pre">; def Remark : BlockCommand<"remark">; diff --git a/contrib/llvm-project/clang/include/clang/AST/CommentParser.h b/contrib/llvm-project/clang/include/clang/AST/CommentParser.h index e11e818b1af..289f0b2c066 100644 --- a/contrib/llvm-project/clang/include/clang/AST/CommentParser.h +++ b/contrib/llvm-project/clang/include/clang/AST/CommentParser.h @@ -100,6 +100,14 @@ public: ArrayRef parseCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + /// Parse arguments for \throws command supported args are in form of class + /// or template. + ArrayRef + parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + + ArrayRef + parseParCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + BlockCommandComment *parseBlockCommand(); InlineCommandComment *parseInlineCommand(); @@ -118,4 +126,3 @@ public: } // end namespace clang #endif - diff --git a/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h b/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h index b4ad37e394c..5a6aef80843 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h +++ b/contrib/llvm-project/clang/include/clang/AST/ComparisonCategories.h @@ -78,7 +78,7 @@ class ComparisonCategoryInfo { friend class Sema; public: - ComparisonCategoryInfo(const ASTContext &Ctx, CXXRecordDecl *RD, + ComparisonCategoryInfo(const ASTContext &Ctx, const CXXRecordDecl *RD, ComparisonCategoryType Kind) : Ctx(Ctx), Record(RD), Kind(Kind) {} diff --git a/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h b/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h index f62611cb4c3..6d3a51c379f 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h +++ b/contrib/llvm-project/clang/include/clang/AST/ComputeDependence.h @@ -63,6 +63,7 @@ class ArrayTypeTraitExpr; class ExpressionTraitExpr; class CXXNoexceptExpr; class PackExpansionExpr; +class PackIndexingExpr; class SubstNonTypeTemplateParmExpr; class CoroutineSuspendExpr; class DependentCoawaitExpr; @@ -93,7 +94,7 @@ class DesignatedInitExpr; class ParenListExpr; class PseudoObjectExpr; class AtomicExpr; -class OMPArraySectionExpr; +class ArraySectionExpr; class OMPArrayShapingExpr; class OMPIteratorExpr; class ObjCArrayLiteral; @@ -150,6 +151,7 @@ ExprDependence computeDependence(ArrayTypeTraitExpr *E); ExprDependence computeDependence(ExpressionTraitExpr *E); ExprDependence computeDependence(CXXNoexceptExpr *E, CanThrowResult CT); ExprDependence computeDependence(PackExpansionExpr *E); +ExprDependence computeDependence(PackIndexingExpr *E); ExprDependence computeDependence(SubstNonTypeTemplateParmExpr *E); ExprDependence computeDependence(CoroutineSuspendExpr *E); ExprDependence computeDependence(DependentCoawaitExpr *E); @@ -187,7 +189,7 @@ ExprDependence computeDependence(ParenListExpr *E); ExprDependence computeDependence(PseudoObjectExpr *E); ExprDependence computeDependence(AtomicExpr *E); -ExprDependence computeDependence(OMPArraySectionExpr *E); +ExprDependence computeDependence(ArraySectionExpr *E); ExprDependence computeDependence(OMPArrayShapingExpr *E); ExprDependence computeDependence(OMPIteratorExpr *E); diff --git a/contrib/llvm-project/clang/include/clang/AST/Decl.h b/contrib/llvm-project/clang/include/clang/AST/Decl.h index f26fb5ad5f1..561a9d872ac 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Decl.h +++ b/contrib/llvm-project/clang/include/clang/AST/Decl.h @@ -120,7 +120,7 @@ public: ASTContext &getASTContext() const { return Ctx; } NamespaceDecl *getAnonymousNamespace() const { return AnonymousNamespace; } - void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; } + void setAnonymousNamespace(NamespaceDecl *D); static TranslationUnitDecl *Create(ASTContext &C); @@ -157,7 +157,7 @@ public: SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg); - static PragmaCommentDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned ArgSize); PragmaMSCommentKind getCommentKind() const { return CommentKind; } @@ -192,7 +192,7 @@ public: SourceLocation Loc, StringRef Name, StringRef Value); static PragmaDetectMismatchDecl * - CreateDeserialized(ASTContext &C, unsigned ID, unsigned NameValueSize); + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize); StringRef getName() const { return getTrailingObjects(); } StringRef getValue() const { return getTrailingObjects() + ValueStart; } @@ -518,7 +518,7 @@ public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, SourceLocation GnuLabelL); - static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static LabelDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); LabelStmt *getStmt() const { return TheStmt; } void setStmt(LabelStmt *T) { TheStmt = T; } @@ -542,12 +542,9 @@ public: }; /// Represent a C++ namespace. -class NamespaceDecl : public NamedDecl, public DeclContext, - public Redeclarable -{ - - enum Flags : unsigned { F_Inline = 1 << 0, F_Nested = 1 << 1 }; - +class NamespaceDecl : public NamedDecl, + public DeclContext, + public Redeclarable { /// The starting location of the source range, pointing /// to either the namespace or the inline keyword. SourceLocation LocStart; @@ -555,12 +552,8 @@ class NamespaceDecl : public NamedDecl, public DeclContext, /// The ending location of the source range. SourceLocation RBraceLoc; - /// A pointer to either the anonymous namespace that lives just inside - /// this namespace or to the first namespace in the chain (the latter case - /// only when this is not the first in the chain), along with a - /// boolean value indicating whether this is an inline namespace. - llvm::PointerIntPair - AnonOrFirstNamespaceAndFlags; + /// The unnamed namespace that inhabits this namespace, if any. + NamespaceDecl *AnonymousNamespace = nullptr; NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, @@ -581,7 +574,7 @@ public: IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested); - static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static NamespaceDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -607,35 +600,19 @@ public: } /// Returns true if this is an inline namespace declaration. - bool isInline() const { - return AnonOrFirstNamespaceAndFlags.getInt() & F_Inline; - } + bool isInline() const { return NamespaceDeclBits.IsInline; } /// Set whether this is an inline namespace declaration. - void setInline(bool Inline) { - unsigned F = AnonOrFirstNamespaceAndFlags.getInt(); - if (Inline) - AnonOrFirstNamespaceAndFlags.setInt(F | F_Inline); - else - AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Inline); - } + void setInline(bool Inline) { NamespaceDeclBits.IsInline = Inline; } /// Returns true if this is a nested namespace declaration. /// \code /// namespace outer::nested { } /// \endcode - bool isNested() const { - return AnonOrFirstNamespaceAndFlags.getInt() & F_Nested; - } + bool isNested() const { return NamespaceDeclBits.IsNested; } /// Set whether this is a nested namespace declaration. - void setNested(bool Nested) { - unsigned F = AnonOrFirstNamespaceAndFlags.getInt(); - if (Nested) - AnonOrFirstNamespaceAndFlags.setInt(F | F_Nested); - else - AnonOrFirstNamespaceAndFlags.setInt(F & ~F_Nested); - } + void setNested(bool Nested) { NamespaceDeclBits.IsNested = Nested; } /// Returns true if the inline qualifier for \c Name is redundant. bool isRedundantInlineQualifierFor(DeclarationName Name) const { @@ -649,34 +626,18 @@ public: std::distance(Y.begin(), Y.end()); } - /// Get the original (first) namespace declaration. - NamespaceDecl *getOriginalNamespace(); - - /// Get the original (first) namespace declaration. - const NamespaceDecl *getOriginalNamespace() const; - - /// Return true if this declaration is an original (first) declaration - /// of the namespace. This is false for non-original (subsequent) namespace - /// declarations and anonymous namespaces. - bool isOriginalNamespace() const; - - /// Retrieve the anonymous namespace nested inside this namespace, - /// if any. + /// Retrieve the anonymous namespace that inhabits this namespace, if any. NamespaceDecl *getAnonymousNamespace() const { - return getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.getPointer(); + return getFirstDecl()->AnonymousNamespace; } void setAnonymousNamespace(NamespaceDecl *D) { - getOriginalNamespace()->AnonOrFirstNamespaceAndFlags.setPointer(D); + getFirstDecl()->AnonymousNamespace = D; } /// Retrieves the canonical declaration of this namespace. - NamespaceDecl *getCanonicalDecl() override { - return getOriginalNamespace(); - } - const NamespaceDecl *getCanonicalDecl() const { - return getOriginalNamespace(); - } + NamespaceDecl *getCanonicalDecl() override { return getFirstDecl(); } + const NamespaceDecl *getCanonicalDecl() const { return getFirstDecl(); } SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(LocStart, RBraceLoc); @@ -1100,6 +1061,9 @@ protected: LLVM_PREFERRED_TYPE(bool) unsigned EscapingByref : 1; + + LLVM_PREFERRED_TYPE(bool) + unsigned IsCXXCondDecl : 1; }; union { @@ -1143,7 +1107,7 @@ public: const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S); - static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static VarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -1589,6 +1553,15 @@ public: NonParmVarDeclBits.EscapingByref = true; } + bool isCXXCondDecl() const { + return isa(this) ? false : NonParmVarDeclBits.IsCXXCondDecl; + } + + void setCXXCondDecl() { + assert(!isa(this)); + NonParmVarDeclBits.IsCXXCondDecl = true; + } + /// Determines if this variable's alignment is dependent. bool hasDependentAlignment() const; @@ -1716,10 +1689,10 @@ public: static ImplicitParamDecl *Create(ASTContext &C, QualType T, ImplicitParamKind ParamKind); - static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ImplicitParamDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, - IdentifierInfo *Id, QualType Type, + const IdentifierInfo *Id, QualType Type, ImplicitParamKind ParamKind) : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type, /*TInfo=*/nullptr, SC_None) { @@ -1753,7 +1726,7 @@ public: protected: ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, QualType T, + SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); @@ -1765,12 +1738,12 @@ protected: public: static ParmVarDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, - StorageClass S, Expr *DefArg); + SourceLocation StartLoc, SourceLocation IdLoc, + const IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, StorageClass S, + Expr *DefArg); - static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ParmVarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -1981,21 +1954,35 @@ public: }; - /// Stashed information about a defaulted function definition whose body has - /// not yet been lazily generated. - class DefaultedFunctionInfo final - : llvm::TrailingObjects { + /// Stashed information about a defaulted/deleted function body. + class DefaultedOrDeletedFunctionInfo final + : llvm::TrailingObjects { friend TrailingObjects; unsigned NumLookups; + bool HasDeletedMessage; + + size_t numTrailingObjects(OverloadToken) const { + return NumLookups; + } public: - static DefaultedFunctionInfo *Create(ASTContext &Context, - ArrayRef Lookups); + static DefaultedOrDeletedFunctionInfo * + Create(ASTContext &Context, ArrayRef Lookups, + StringLiteral *DeletedMessage = nullptr); + /// Get the unqualified lookup results that should be used in this /// defaulted function definition. ArrayRef getUnqualifiedLookups() const { return {getTrailingObjects(), NumLookups}; } + + StringLiteral *getDeletedMessage() const { + return HasDeletedMessage ? *getTrailingObjects() + : nullptr; + } + + void setDeletedMessage(StringLiteral *Message); }; private: @@ -2005,12 +1992,12 @@ private: ParmVarDecl **ParamInfo = nullptr; /// The active member of this union is determined by - /// FunctionDeclBits.HasDefaultedFunctionInfo. + /// FunctionDeclBits.HasDefaultedOrDeletedInfo. union { /// The body of the function. LazyDeclStmtPtr Body; /// Information about a future defaulted function definition. - DefaultedFunctionInfo *DefaultedInfo; + DefaultedOrDeletedFunctionInfo *DefaultedOrDeletedInfo; }; unsigned ODRHash; @@ -2070,13 +2057,12 @@ private: /// /// \param PointOfInstantiation point at which the function template /// specialization was first instantiated. - void setFunctionTemplateSpecialization(ASTContext &C, - FunctionTemplateDecl *Template, - const TemplateArgumentList *TemplateArgs, - void *InsertPos, - TemplateSpecializationKind TSK, - const TemplateArgumentListInfo *TemplateArgsAsWritten, - SourceLocation PointOfInstantiation); + void setFunctionTemplateSpecialization( + ASTContext &C, FunctionTemplateDecl *Template, + TemplateArgumentList *TemplateArgs, void *InsertPos, + TemplateSpecializationKind TSK, + const TemplateArgumentListInfo *TemplateArgsAsWritten, + SourceLocation PointOfInstantiation); /// Specify that this record is an instantiation of the /// member function FD. @@ -2152,7 +2138,7 @@ public: bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause); - static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); @@ -2163,6 +2149,8 @@ public: void setRangeEnd(SourceLocation E) { EndRangeLoc = E; } + void setDeclarationNameLoc(DeclarationNameLoc L) { DNLoc = L; } + /// Returns the location of the ellipsis of a variadic function. SourceLocation getEllipsisLoc() const { const auto *FPT = getType()->getAs(); @@ -2268,18 +2256,18 @@ public: /// Returns whether this specific declaration of the function has a body. bool doesThisDeclarationHaveABody() const { - return (!FunctionDeclBits.HasDefaultedFunctionInfo && Body) || + return (!FunctionDeclBits.HasDefaultedOrDeletedInfo && Body) || isLateTemplateParsed(); } void setBody(Stmt *B); void setLazyBody(uint64_t Offset) { - FunctionDeclBits.HasDefaultedFunctionInfo = false; + FunctionDeclBits.HasDefaultedOrDeletedInfo = false; Body = LazyDeclStmtPtr(Offset); } - void setDefaultedFunctionInfo(DefaultedFunctionInfo *Info); - DefaultedFunctionInfo *getDefaultedFunctionInfo() const; + void setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo *Info); + DefaultedOrDeletedFunctionInfo *getDefalutedOrDeletedInfo() const; /// Whether this function is variadic. bool isVariadic() const; @@ -2482,7 +2470,7 @@ public: return FunctionDeclBits.IsDeleted && !isDefaulted(); } - void setDeletedAsWritten(bool D = true) { FunctionDeclBits.IsDeleted = D; } + void setDeletedAsWritten(bool D = true, StringLiteral *Message = nullptr); /// Determines whether this function is "main", which is the /// entry point into an executable program. @@ -2615,10 +2603,18 @@ public: /// the target functionality. bool isTargetMultiVersion() const; + /// True if this function is the default version of a multiversioned dispatch + /// function as a part of the target functionality. + bool isTargetMultiVersionDefault() const; + /// True if this function is a multiversioned dispatch function as a part of /// the target-clones functionality. bool isTargetClonesMultiVersion() const; + /// True if this function is a multiversioned dispatch function as a part of + /// the target-version functionality. + bool isTargetVersionMultiVersion() const; + /// \brief Get the associated-constraints of this function declaration. /// Currently, this will either be a vector of size 1 containing the /// trailing-requires-clause or an empty vector. @@ -2630,6 +2626,13 @@ public: AC.push_back(TRC); } + /// Get the message that indicates why this function was deleted. + StringLiteral *getDeletedMessage() const { + return FunctionDeclBits.HasDefaultedOrDeletedInfo + ? DefaultedOrDeletedInfo->getDeletedMessage() + : nullptr; + } + void setPreviousDeclaration(FunctionDecl * PrevDecl); FunctionDecl *getCanonicalDecl() override; @@ -2940,12 +2943,12 @@ public: /// /// \param PointOfInstantiation point at which the function template /// specialization was first instantiated. - void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, - const TemplateArgumentList *TemplateArgs, - void *InsertPos, - TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, - const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr, - SourceLocation PointOfInstantiation = SourceLocation()) { + void setFunctionTemplateSpecialization( + FunctionTemplateDecl *Template, TemplateArgumentList *TemplateArgs, + void *InsertPos, + TemplateSpecializationKind TSK = TSK_ImplicitInstantiation, + TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr, + SourceLocation PointOfInstantiation = SourceLocation()) { setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs, InsertPos, TSK, TemplateArgsAsWritten, PointOfInstantiation); @@ -3000,6 +3003,16 @@ public: /// computed and stored. unsigned getODRHash() const; + FunctionEffectsRef getFunctionEffects() const { + // Effects may differ between declarations, but they should be propagated + // from old to new on any redeclaration, so it suffices to look at + // getMostRecentDecl(). + if (const auto *FPT = + getMostRecentDecl()->getType()->getAs()) + return FPT->getFunctionEffects(); + return {}; + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -3075,7 +3088,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable { protected: FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, QualType T, + SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), BitField(false), @@ -3091,11 +3104,11 @@ public: static FieldDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, QualType T, + const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle); - static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. @@ -3108,7 +3121,7 @@ public: bool isBitField() const { return BitField; } /// Determines whether this is an unnamed bitfield. - bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); } + bool isUnnamedBitField() const { return isBitField() && !getDeclName(); } /// Determines whether this field is a /// representative for an anonymous struct or union. Such fields are @@ -3270,7 +3283,7 @@ public: SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V); - static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static EnumConstantDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } @@ -3312,10 +3325,11 @@ public: friend class ASTDeclReader; static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - QualType T, llvm::MutableArrayRef CH); + SourceLocation L, const IdentifierInfo *Id, + QualType T, + llvm::MutableArrayRef CH); - static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using chain_iterator = ArrayRef::const_iterator; @@ -3361,9 +3375,9 @@ class TypeDecl : public NamedDecl { void anchor() override; protected: - TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation StartL = SourceLocation()) - : NamedDecl(DK, DC, L, Id), LocStart(StartL) {} + : NamedDecl(DK, DC, L, Id), LocStart(StartL) {} public: // Low-level accessor. If you just want the type defined by this node, @@ -3405,7 +3419,7 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable { protected: TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, TypeSourceInfo *TInfo) + const IdentifierInfo *Id, TypeSourceInfo *TInfo) : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C), MaybeModedTInfo(TInfo, 0) {} @@ -3492,14 +3506,15 @@ private: /// type specifier. class TypedefDecl : public TypedefNameDecl { TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) + SourceLocation IdLoc, const IdentifierInfo *Id, + TypeSourceInfo *TInfo) : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {} public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID); + const IdentifierInfo *Id, TypeSourceInfo *TInfo); + static TypedefDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3515,15 +3530,16 @@ class TypeAliasDecl : public TypedefNameDecl { TypeAliasTemplateDecl *Template; TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo) + SourceLocation IdLoc, const IdentifierInfo *Id, + TypeSourceInfo *TInfo) : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo), Template(nullptr) {} public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); + const IdentifierInfo *Id, TypeSourceInfo *TInfo); + static TypeAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3933,7 +3949,7 @@ public: IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed); - static EnumDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static EnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Overrides to provide correct range when there's an enum-base specifier /// with forward declarations. @@ -4138,7 +4154,7 @@ public: static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); - static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + static RecordDecl *CreateDeserialized(const ASTContext &C, GlobalDeclID ID); RecordDecl *getPreviousDecl() { return cast_or_null( @@ -4389,7 +4405,7 @@ public: StringLiteral *Str, SourceLocation AsmLoc, SourceLocation RParenLoc); - static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -4411,7 +4427,7 @@ public: /// /// \note This is used in libInterpreter, clang -cc1 -fincremental-extensions /// and in tools such as clang-repl. -class TopLevelStmtDecl : public Decl { +class TopLevelStmtDecl : public Decl, public DeclContext { friend class ASTDeclReader; friend class ASTDeclWriter; @@ -4419,26 +4435,30 @@ class TopLevelStmtDecl : public Decl { bool IsSemiMissing = false; TopLevelStmtDecl(DeclContext *DC, SourceLocation L, Stmt *S) - : Decl(TopLevelStmt, DC, L), Statement(S) {} + : Decl(TopLevelStmt, DC, L), DeclContext(TopLevelStmt), Statement(S) {} virtual void anchor(); public: static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement); - static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; Stmt *getStmt() { return Statement; } const Stmt *getStmt() const { return Statement; } - void setStmt(Stmt *S) { - assert(IsSemiMissing && "Operation supported for printing values only!"); - Statement = S; - } + void setStmt(Stmt *S); bool isSemiMissing() const { return IsSemiMissing; } void setSemiMissing(bool Missing = true) { IsSemiMissing = Missing; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == TopLevelStmt; } + + static DeclContext *castToDeclContext(const TopLevelStmtDecl *D) { + return static_cast(const_cast(D)); + } + static TopLevelStmtDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast(const_cast(DC)); + } }; /// Represents a block literal declaration, which is like an @@ -4515,7 +4535,7 @@ protected: public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static BlockDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getCaretLocation() const { return getLocation(); } @@ -4621,6 +4641,13 @@ public: SourceRange getSourceRange() const override LLVM_READONLY; + FunctionEffectsRef getFunctionEffects() const { + if (const TypeSourceInfo *TSI = getSignatureAsWritten()) + if (const auto *FPT = TSI->getType()->getAs()) + return FPT->getFunctionEffects(); + return {}; + } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Block; } @@ -4669,7 +4696,7 @@ public: static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); - static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static CapturedDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams); Stmt *getBody() const override; @@ -4803,7 +4830,7 @@ public: SourceLocation EndLoc); /// Create a new, deserialized module import declaration. - static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static ImportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. @@ -4844,7 +4871,7 @@ private: public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc); - static ExportDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ExportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getExportLoc() const { return getLocation(); } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -4883,7 +4910,7 @@ class EmptyDecl : public Decl { public: static EmptyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static EmptyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Empty; } @@ -4909,7 +4936,7 @@ public: bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); - static HLSLBufferDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getLocStart(), RBraceLoc); @@ -5001,6 +5028,11 @@ static constexpr StringRef getOpenMPVariantManglingSeparatorStr() { return "$ompvariant"; } +/// Returns whether the given FunctionDecl has an __arm[_locally]_streaming +/// attribute. +bool IsArmStreamingFunction(const FunctionDecl *FD, + bool IncludeLocallyStreaming); + } // namespace clang #endif // LLVM_CLANG_AST_DECL_H diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclAccessPair.h b/contrib/llvm-project/clang/include/clang/AST/DeclAccessPair.h index 805342c2910..4becfde9630 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclAccessPair.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclAccessPair.h @@ -19,6 +19,7 @@ #include "clang/Basic/Specifiers.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" namespace clang { @@ -27,9 +28,17 @@ class NamedDecl; /// A POD class for pairing a NamedDecl* with an access specifier. /// Can be put into unions. class DeclAccessPair { - uintptr_t Ptr; // we'd use llvm::PointerUnion, but it isn't trivial + /// Use the lower 2 bit to store AccessSpecifier. Use the higher + /// 61 bit to store the pointer to a NamedDecl or the DeclID to + /// a NamedDecl. If the 3rd bit is set, storing the DeclID, otherwise + /// storing the pointer. + llvm::support::detail::packed_endian_specific_integral< + uint64_t, llvm::endianness::native, alignof(void *)> + Ptr; - enum { Mask = 0x3 }; + enum { ASMask = 0x3, Mask = 0x7 }; + + bool isDeclID() const { return (Ptr >> 2) & 0x1; } public: static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) { @@ -38,12 +47,22 @@ public: return p; } + static DeclAccessPair makeLazy(uint64_t ID, AccessSpecifier AS) { + DeclAccessPair p; + p.Ptr = (ID << 3) | (0x1 << 2) | uint64_t(AS); + return p; + } + + uint64_t getDeclID() const { + assert(isDeclID()); + return (~Mask & Ptr) >> 3; + } + NamedDecl *getDecl() const { + assert(!isDeclID()); return reinterpret_cast(~Mask & Ptr); } - AccessSpecifier getAccess() const { - return AccessSpecifier(Mask & Ptr); - } + AccessSpecifier getAccess() const { return AccessSpecifier(ASMask & Ptr); } void setDecl(NamedDecl *D) { set(D, getAccess()); @@ -52,12 +71,18 @@ public: set(getDecl(), AS); } void set(NamedDecl *D, AccessSpecifier AS) { - Ptr = uintptr_t(AS) | reinterpret_cast(D); + Ptr = uint64_t(AS) | reinterpret_cast(D); } operator NamedDecl*() const { return getDecl(); } NamedDecl *operator->() const { return getDecl(); } }; + +// Make sure DeclAccessPair is pointer-aligned types. +static_assert(alignof(DeclAccessPair) == alignof(void *)); +// Make sure DeclAccessPair is still POD. +static_assert(std::is_standard_layout_v && + std::is_trivial_v); } #endif diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h index eb7a1a32060..40f01abf384 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclBase.h @@ -15,6 +15,7 @@ #include "clang/AST/ASTDumperUtils.h" #include "clang/AST/AttrIterator.h" +#include "clang/AST/DeclID.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/SelectorLocationsKind.h" #include "clang/Basic/IdentifierTable.h" @@ -358,7 +359,7 @@ protected: /// \param Ctx The context in which we will allocate memory. /// \param ID The global ID of the deserialized declaration. /// \param Extra The amount of extra space to allocate after the object. - void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID, + void *operator new(std::size_t Size, const ASTContext &Ctx, GlobalDeclID ID, std::size_t Extra = 0); /// Allocate memory for a non-deserialized declaration. @@ -669,19 +670,11 @@ public: /// Whether this declaration comes from another module unit. bool isInAnotherModuleUnit() const; - /// FIXME: Implement discarding declarations actually in global module - /// fragment. See [module.global.frag]p3,4 for details. - bool isDiscardedInGlobalModuleFragment() const { return false; } + /// Whether this declaration comes from explicit global module. + bool isFromExplicitGlobalModule() const; - /// Check if we should skip checking ODRHash for declaration \param D. - /// - /// The existing ODRHash mechanism seems to be not stable enough and - /// the false positive ODR violation reports are annoying and we rarely see - /// true ODR violation reports. Also we learned that MSVC disabled ODR checks - /// for declarations in GMF. So we try to disable ODR checks in the GMF to - /// get better user experiences before we make the ODR violation checks stable - /// enough. - bool shouldSkipCheckingODR() const; + /// Whether this declaration comes from a named module. + bool isInNamedModule() const; /// Return true if this declaration has an attribute which acts as /// definition of the entity, such as 'alias' or 'ifunc'. @@ -711,10 +704,7 @@ public: /// Set the owning module ID. This may only be called for /// deserialized Decls. - void setOwningModuleID(unsigned ID) { - assert(isFromASTFile() && "Only works on a deserialized declaration"); - *((unsigned*)this - 2) = ID; - } + void setOwningModuleID(unsigned ID); public: /// Determine the availability of the given declaration. @@ -787,19 +777,11 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - unsigned getGlobalID() const { - if (isFromASTFile()) - return *((const unsigned*)this - 1); - return 0; - } + GlobalDeclID getGlobalID() const; /// Retrieve the global ID of the module that owns this particular /// declaration. - unsigned getOwningModuleID() const { - if (isFromASTFile()) - return *((const unsigned*)this - 2); - return 0; - } + unsigned getOwningModuleID() const; private: Module *getOwningModuleSlow() const; @@ -846,10 +828,7 @@ public: /// Get the module that owns this declaration for linkage purposes. /// There only ever is such a standard C++ module. - /// - /// \param IgnoreLinkage Ignore the linkage of the entity; assume that - /// all declarations in a global module fragment are unowned. - Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const; + Module *getOwningModuleForLinkage() const; /// Determine whether this declaration is definitely visible to name lookup, /// independent of whether the owning module is visible. @@ -1508,6 +1487,27 @@ class DeclContext { /// Number of bits in DeclContextBitfields. enum { NumDeclContextBits = 13 }; + /// Stores the bits used by NamespaceDecl. + /// If modified NumNamespaceDeclBits and the accessor + /// methods in NamespaceDecl should be updated appropriately. + class NamespaceDeclBitfields { + friend class NamespaceDecl; + /// For the bits in DeclContextBitfields + LLVM_PREFERRED_TYPE(DeclContextBitfields) + uint64_t : NumDeclContextBits; + + /// True if this is an inline namespace. + LLVM_PREFERRED_TYPE(bool) + uint64_t IsInline : 1; + + /// True if this is a nested-namespace-definition. + LLVM_PREFERRED_TYPE(bool) + uint64_t IsNested : 1; + }; + + /// Number of inherited and non-inherited bits in NamespaceDeclBitfields. + enum { NumNamespaceDeclBits = NumDeclContextBits + 2 }; + /// Stores the bits used by TagDecl. /// If modified NumTagDeclBits and the accessor /// methods in TagDecl should be updated appropriately. @@ -1740,7 +1740,7 @@ class DeclContext { LLVM_PREFERRED_TYPE(bool) uint64_t IsExplicitlyDefaulted : 1; LLVM_PREFERRED_TYPE(bool) - uint64_t HasDefaultedFunctionInfo : 1; + uint64_t HasDefaultedOrDeletedInfo : 1; /// For member functions of complete types, whether this is an ineligible /// special member function or an unselected destructor. See @@ -2006,6 +2006,7 @@ protected: /// 8 bytes with static_asserts in the ctor of DeclContext. union { DeclContextBitfields DeclContextBits; + NamespaceDeclBitfields NamespaceDeclBits; TagDeclBitfields TagDeclBits; EnumDeclBitfields EnumDeclBits; RecordDeclBitfields RecordDeclBits; @@ -2019,6 +2020,8 @@ protected: static_assert(sizeof(DeclContextBitfields) <= 8, "DeclContextBitfields is larger than 8 bytes!"); + static_assert(sizeof(NamespaceDeclBitfields) <= 8, + "NamespaceDeclBitfields is larger than 8 bytes!"); static_assert(sizeof(TagDeclBitfields) <= 8, "TagDeclBitfields is larger than 8 bytes!"); static_assert(sizeof(EnumDeclBitfields) <= 8, @@ -2130,6 +2133,7 @@ public: case Decl::Block: case Decl::Captured: case Decl::ObjCMethod: + case Decl::TopLevelStmt: return true; default: return getDeclKind() >= Decl::firstFunction && @@ -2157,6 +2161,10 @@ public: getDeclKind() <= Decl::lastRecord; } + bool isRequiresExprBody() const { + return getDeclKind() == Decl::RequiresExprBody; + } + bool isNamespace() const { return getDeclKind() == Decl::Namespace; } bool isStdNamespace() const; diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h index 9cebaff63bb..fb52ac80484 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h @@ -120,7 +120,7 @@ public: return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } - static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static AccessSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -579,7 +579,8 @@ public: TypeSourceInfo *Info, SourceLocation Loc, unsigned DependencyKind, bool IsGeneric, LambdaCaptureDefault CaptureDefault); - static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -1869,6 +1870,10 @@ public: DL.MethodTyInfo = TS; } + void setLambdaDependencyKind(unsigned Kind) { + getLambdaData().DependencyKind = Kind; + } + void setLambdaIsGeneric(bool IsGeneric) { assert(DefinitionData && DefinitionData->IsLambda && "setting lambda property of non-lambda class"); @@ -1976,7 +1981,8 @@ public: CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal); - static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } @@ -2031,7 +2037,8 @@ public: static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc); - static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2074,7 +2081,7 @@ public: ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); bool isStatic() const; bool isInstance() const { return !isStatic(); } @@ -2575,7 +2582,7 @@ public: friend class ASTDeclWriter; friend TrailingObjects; - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, @@ -2818,7 +2825,7 @@ public: bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); - static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); + static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); @@ -2877,7 +2884,7 @@ public: bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->ExplicitSpec; @@ -2944,7 +2951,7 @@ public: SourceLocation ExternLoc, SourceLocation LangLoc, LinkageSpecLanguageIDs Lang, bool HasBraces); - static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the language specified by this linkage specification. LinkageSpecLanguageIDs getLanguage() const { @@ -3092,7 +3099,7 @@ public: SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); - static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(UsingLoc, getLocation()); @@ -3153,7 +3160,7 @@ public: SourceLocation IdentLoc, NamedDecl *Namespace); - static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3250,7 +3257,7 @@ public: LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling); } static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C, - unsigned ID) { + GlobalDeclID ID) { return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{}); } @@ -3353,7 +3360,7 @@ public: UsingShadowDecl(UsingShadow, C, DC, Loc, Name, Introducer, Target); } - static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingShadowDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3562,7 +3569,7 @@ public: const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword); - static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3641,7 +3648,7 @@ public: UsingDecl *Using, NamedDecl *Target, bool IsVirtual); static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + GlobalDeclID ID); /// Override the UsingShadowDecl's getIntroducer, returning the UsingDecl that /// introduced this. @@ -3753,7 +3760,7 @@ public: SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType); - static UsingEnumDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static UsingEnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3826,7 +3833,7 @@ public: NamedDecl *InstantiatedFrom, ArrayRef UsingDecls); - static UsingPackDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static UsingPackDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); SourceRange getSourceRange() const override LLVM_READONLY { @@ -3919,8 +3926,8 @@ public: NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc); - static UnresolvedUsingValueDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + static UnresolvedUsingValueDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -4010,8 +4017,8 @@ public: SourceLocation TargetNameLoc, DeclarationName TargetName, SourceLocation EllipsisLoc); - static UnresolvedUsingTypenameDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + static UnresolvedUsingTypenameDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// Retrieves the canonical declaration of this declaration. UnresolvedUsingTypenameDecl *getCanonicalDecl() override { @@ -4041,7 +4048,7 @@ public: SourceLocation Loc, DeclarationName Name); static UnresolvedUsingIfExistsDecl *CreateDeserialized(ASTContext &Ctx, - unsigned ID); + GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingIfExists; } @@ -4069,7 +4076,7 @@ public: SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc, bool Failed); - static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static StaticAssertDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); } const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); } @@ -4116,7 +4123,7 @@ public: static BindingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id); - static BindingDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Get the expression to which this declaration is bound. This may be null /// in two different cases: while parsing the initializer for the @@ -4185,7 +4192,7 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef Bindings); - static DecompositionDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static DecompositionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumBindings); ArrayRef bindings() const { @@ -4242,7 +4249,7 @@ public: SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter); - static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static MSPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return D->getKind() == MSProperty; } @@ -4296,7 +4303,7 @@ private: MSGuidDecl(DeclContext *DC, QualType T, Parts P); static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); - static MSGuidDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static MSGuidDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Only ASTContext::getMSGuidDecl and deserialization create these. friend class ASTContext; @@ -4349,7 +4356,7 @@ class UnnamedGlobalConstantDecl : public ValueDecl, static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T, const APValue &APVal); static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + GlobalDeclID ID); // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create // these. diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h b/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h index 903cdb7bfcc..e169c485921 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclContextInternals.h @@ -42,11 +42,12 @@ class StoredDeclsList { /// external declarations. DeclsAndHasExternalTy Data; - template - void erase_if(Fn ShouldErase) { + template DeclListNode::Decls *erase_if(Fn ShouldErase) { Decls List = Data.getPointer(); + if (!List) - return; + return nullptr; + ASTContext &C = getASTContext(); DeclListNode::Decls NewHead = nullptr; DeclListNode::Decls *NewLast = nullptr; @@ -79,6 +80,17 @@ class StoredDeclsList { Data.setPointer(NewHead); assert(llvm::none_of(getLookupResult(), ShouldErase) && "Still exists!"); + + if (!Data.getPointer()) + // All declarations are erased. + return nullptr; + else if (NewHead.is()) + // The list only contains a declaration, the header itself. + return (DeclListNode::Decls *)&Data; + else { + assert(NewLast && NewLast->is() && "Not the tail?"); + return NewLast; + } } void erase(NamedDecl *ND) { @@ -160,12 +172,16 @@ public: void replaceExternalDecls(ArrayRef Decls) { // Remove all declarations that are either external or are replaced with - // external declarations. - erase_if([Decls](NamedDecl *ND) { + // external declarations with higher visibilities. + DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; + // FIXME: Can we get rid of this loop completely? for (NamedDecl *D : Decls) - if (D->declarationReplaces(ND, /*IsKnownNewer=*/false)) + // Only replace the local declaration if the external declaration has + // higher visibilities. + if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false)) return true; return false; }); @@ -185,27 +201,18 @@ public: DeclsAsList = Node; } - DeclListNode::Decls Head = Data.getPointer(); - if (Head.isNull()) { + if (!Data.getPointer()) { Data.setPointer(DeclsAsList); return; } - // Find the end of the existing list. - // FIXME: It would be possible to preserve information from erase_if to - // avoid this rescan looking for the end of the list. - DeclListNode::Decls *Tail = &Head; - while (DeclListNode *Node = Tail->dyn_cast()) - Tail = &Node->Rest; - // Append the Decls. DeclListNode *Node = C.AllocateDeclListNode(Tail->get()); Node->Rest = DeclsAsList; *Tail = Node; - Data.setPointer(Head); } - /// Return an array of all the decls that this list represents. + /// Return the list of all the decls. DeclContext::lookup_result getLookupResult() const { return DeclContext::lookup_result(Data.getPointer()); } diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h b/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h index 3e6ca5b3219..9789282f351 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclFriend.h @@ -112,7 +112,7 @@ public: Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, ArrayRef FriendTypeTPLists = std::nullopt); - static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclID.h b/contrib/llvm-project/clang/include/clang/AST/DeclID.h new file mode 100644 index 00000000000..e5e27389fac --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/AST/DeclID.h @@ -0,0 +1,274 @@ +//===--- DeclID.h - ID number for deserialized declarations ----*- 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 DeclID class family to describe the deserialized +// declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to +// `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to +// require the use of `DeclID` to explicit. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLID_H +#define LLVM_CLANG_AST_DECLID_H + +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/iterator.h" + +#include + +namespace clang { + +/// Predefined declaration IDs. +/// +/// These declaration IDs correspond to predefined declarations in the AST +/// context, such as the NULL declaration ID. Such declarations are never +/// actually serialized, since they will be built by the AST context when +/// it is created. +enum PredefinedDeclIDs { + /// The NULL declaration. + PREDEF_DECL_NULL_ID = 0, + + /// The translation unit. + PREDEF_DECL_TRANSLATION_UNIT_ID = 1, + + /// The Objective-C 'id' type. + PREDEF_DECL_OBJC_ID_ID = 2, + + /// The Objective-C 'SEL' type. + PREDEF_DECL_OBJC_SEL_ID = 3, + + /// The Objective-C 'Class' type. + PREDEF_DECL_OBJC_CLASS_ID = 4, + + /// The Objective-C 'Protocol' type. + PREDEF_DECL_OBJC_PROTOCOL_ID = 5, + + /// The signed 128-bit integer type. + PREDEF_DECL_INT_128_ID = 6, + + /// The unsigned 128-bit integer type. + PREDEF_DECL_UNSIGNED_INT_128_ID = 7, + + /// The internal 'instancetype' typedef. + PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, + + /// The internal '__builtin_va_list' typedef. + PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, + + /// The internal '__va_list_tag' struct, if any. + PREDEF_DECL_VA_LIST_TAG = 10, + + /// The internal '__builtin_ms_va_list' typedef. + PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, + + /// The predeclared '_GUID' struct. + PREDEF_DECL_BUILTIN_MS_GUID_ID = 12, + + /// The extern "C" context. + PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13, + + /// The internal '__make_integer_seq' template. + PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14, + + /// The internal '__NSConstantString' typedef. + PREDEF_DECL_CF_CONSTANT_STRING_ID = 15, + + /// The internal '__NSConstantString' tag type. + PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16, + + /// The internal '__type_pack_element' template. + PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17, +}; + +/// The number of declaration IDs that are predefined. +/// +/// For more information about predefined declarations, see the +/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. +const unsigned int NUM_PREDEF_DECL_IDS = 18; + +/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means +/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the +/// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID. +/// Outside the serializer, all the DeclID been used should be GlobalDeclID. +/// We can translate a LocalDeclID to the GlobalDeclID by +/// `ASTReader::getGlobalDeclID()`. + +class DeclIDBase { +public: + /// An ID number that refers to a declaration in an AST file. + /// + /// The ID numbers of declarations are consecutive (in order of + /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. + /// At the start of a chain of precompiled headers, declaration ID 1 is + /// used for the translation unit declaration. + /// + /// DeclID should only be used directly in serialization. All other users + /// should use LocalDeclID or GlobalDeclID. + using DeclID = uint64_t; + +protected: + DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} + explicit DeclIDBase(DeclID ID) : ID(ID) {} + +public: + DeclID getRawValue() const { return ID; } + + explicit operator DeclID() const { return ID; } + + explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; } + + bool isValid() const { return ID != PREDEF_DECL_NULL_ID; } + + bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } + + unsigned getModuleFileIndex() const { return ID >> 32; } + + unsigned getLocalDeclIndex() const; + + // The DeclID may be compared with predefined decl ID. + friend bool operator==(const DeclIDBase &LHS, const DeclID &RHS) { + return LHS.ID == RHS; + } + friend bool operator!=(const DeclIDBase &LHS, const DeclID &RHS) { + return !operator==(LHS, RHS); + } + friend bool operator<(const DeclIDBase &LHS, const DeclID &RHS) { + return LHS.ID < RHS; + } + friend bool operator<=(const DeclIDBase &LHS, const DeclID &RHS) { + return LHS.ID <= RHS; + } + friend bool operator>(const DeclIDBase &LHS, const DeclID &RHS) { + return LHS.ID > RHS; + } + friend bool operator>=(const DeclIDBase &LHS, const DeclID &RHS) { + return LHS.ID >= RHS; + } + + friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID == RHS.ID; + } + friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID != RHS.ID; + } + + // We may sort the decl ID. + friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID < RHS.ID; + } + friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID > RHS.ID; + } + friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID <= RHS.ID; + } + friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID >= RHS.ID; + } + +protected: + DeclID ID; +}; + +class ASTWriter; +class ASTReader; +namespace serialization { +class ModuleFile; +} // namespace serialization + +class LocalDeclID : public DeclIDBase { + using Base = DeclIDBase; + + LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} + explicit LocalDeclID(DeclID ID) : Base(ID) {} + + // Every Decl ID is a local decl ID to the module being writing in ASTWriter. + friend class ASTWriter; + friend class GlobalDeclID; + +public: + LocalDeclID() : Base() {} + + static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF, + DeclID ID); + static LocalDeclID get(ASTReader &Reader, serialization::ModuleFile &MF, + unsigned ModuleFileIndex, unsigned LocalDeclID); + + LocalDeclID &operator++() { + ++ID; + return *this; + } + + LocalDeclID operator++(int) { + LocalDeclID Ret = *this; + ++(*this); + return Ret; + } +}; + +class GlobalDeclID : public DeclIDBase { + using Base = DeclIDBase; + +public: + GlobalDeclID() : Base() {} + explicit GlobalDeclID(DeclID ID) : Base(ID) {} + + explicit GlobalDeclID(unsigned ModuleFileIndex, unsigned LocalID) + : Base((DeclID)ModuleFileIndex << 32 | (DeclID)LocalID) {} + + // For DeclIDIterator to be able to convert a GlobalDeclID + // to a LocalDeclID. + explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } +}; + +/// A helper iterator adaptor to convert the iterators to +/// `SmallVector` to the iterators to `SmallVector`. +template +class DeclIDIterator + : public llvm::iterator_adaptor_base, + const FromTy *, + std::forward_iterator_tag, ToTy> { +public: + DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {} + + DeclIDIterator(const FromTy *ID) + : DeclIDIterator::iterator_adaptor_base(ID) {} + + ToTy operator*() const { return ToTy(*this->I); } + + bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; } +}; + +} // namespace clang + +namespace llvm { +template <> struct DenseMapInfo { + using GlobalDeclID = clang::GlobalDeclID; + using DeclID = GlobalDeclID::DeclID; + + static GlobalDeclID getEmptyKey() { + return GlobalDeclID(DenseMapInfo::getEmptyKey()); + } + + static GlobalDeclID getTombstoneKey() { + return GlobalDeclID(DenseMapInfo::getTombstoneKey()); + } + + static unsigned getHashValue(const GlobalDeclID &Key) { + return DenseMapInfo::getHashValue(Key.getRawValue()); + } + + static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { + return L == R; + } +}; + +} // namespace llvm + +#endif diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h b/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h index f8f894b4b10..d2cc61ca19f 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclObjC.h @@ -236,7 +236,7 @@ public: ObjCImplementationControl impControl = ObjCImplementationControl::None, bool HasRelatedResultType = false); - static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCMethodDecl *getCanonicalDecl() override; const ObjCMethodDecl *getCanonicalDecl() const { @@ -614,7 +614,8 @@ public: IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo); - static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, unsigned ID); + static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -772,7 +773,7 @@ private: // Synthesize ivar for this property ObjCIvarDecl *PropertyIvarDecl = nullptr; - ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + ObjCPropertyDecl(DeclContext *DC, SourceLocation L, const IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, TypeSourceInfo *TSI, PropertyControl propControl) : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), @@ -782,12 +783,14 @@ private: PropertyImplementation(propControl) {} public: - static ObjCPropertyDecl * - Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - SourceLocation AtLocation, SourceLocation LParenLocation, QualType T, - TypeSourceInfo *TSI, PropertyControl propControl = None); + static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, const IdentifierInfo *Id, + SourceLocation AtLocation, + SourceLocation LParenLocation, QualType T, + TypeSourceInfo *TSI, + PropertyControl propControl = None); - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } @@ -952,7 +955,7 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext { void anchor() override; public: - ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id, + ObjCContainerDecl(Kind DK, DeclContext *DC, const IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc); // Iterator access to instance/class properties. @@ -1240,7 +1243,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl llvm::PointerIntPair Data; ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, - IdentifierInfo *Id, ObjCTypeParamList *typeParamList, + const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, bool IsInternal); @@ -1271,15 +1274,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl } public: - static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC, - SourceLocation atLoc, - IdentifierInfo *Id, - ObjCTypeParamList *typeParamList, - ObjCInterfaceDecl *PrevDecl, - SourceLocation ClassLoc = SourceLocation(), - bool isInternal = false); + static ObjCInterfaceDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, + const IdentifierInfo *Id, ObjCTypeParamList *typeParamList, + ObjCInterfaceDecl *PrevDecl, + SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); /// Retrieve the type parameters of this class. /// @@ -1338,7 +1340,8 @@ public: ObjCImplementationDecl *getImplementation() const; void setImplementation(ObjCImplementationDecl *ImplD); - ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; + ObjCCategoryDecl * + FindCategoryDeclaration(const IdentifierInfo *CategoryId) const; // Get the local instance/class method declared in a category. ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; @@ -1794,9 +1797,9 @@ public: data().CategoryList = category; } - ObjCPropertyDecl - *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId, - ObjCPropertyQueryKind QueryKind) const; + ObjCPropertyDecl * + FindPropertyVisibleInPrimaryClass(const IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind) const; void collectPropertiesToImplement(PropertyMap &PM) const override; @@ -1954,8 +1957,8 @@ public: private: ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, + SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, bool synthesized) : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), @@ -1964,12 +1967,11 @@ private: public: static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC, SourceLocation StartLoc, SourceLocation IdLoc, - IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo, - AccessControl ac, Expr *BW = nullptr, - bool synthesized=false); + const IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, AccessControl ac, + Expr *BW = nullptr, bool synthesized = false); - static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the class interface that this ivar is logically contained /// in; this is either the interface where the ivar was declared, or the @@ -2039,7 +2041,8 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW); - static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2142,7 +2145,7 @@ public: SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); - static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "No definition available!"); @@ -2343,7 +2346,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl { ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, - IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, + const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc = SourceLocation(), SourceLocation IvarRBraceLoc = SourceLocation()); @@ -2354,16 +2357,14 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; - static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation AtLoc, - SourceLocation ClassNameLoc, - SourceLocation CategoryNameLoc, - IdentifierInfo *Id, - ObjCInterfaceDecl *IDecl, - ObjCTypeParamList *typeParamList, - SourceLocation IvarLBraceLoc=SourceLocation(), - SourceLocation IvarRBraceLoc=SourceLocation()); - static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCCategoryDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, + SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, + const IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, + ObjCTypeParamList *typeParamList, + SourceLocation IvarLBraceLoc = SourceLocation(), + SourceLocation IvarRBraceLoc = SourceLocation()); + static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -2472,10 +2473,9 @@ class ObjCImplDecl : public ObjCContainerDecl { void anchor() override; protected: - ObjCImplDecl(Kind DK, DeclContext *DC, - ObjCInterfaceDecl *classInterface, - IdentifierInfo *Id, - SourceLocation nameLoc, SourceLocation atStartLoc) + ObjCImplDecl(Kind DK, DeclContext *DC, ObjCInterfaceDecl *classInterface, + const IdentifierInfo *Id, SourceLocation nameLoc, + SourceLocation atStartLoc) : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc), ClassInterface(classInterface) {} @@ -2543,12 +2543,12 @@ class ObjCCategoryImplDecl : public ObjCImplDecl { // Category name location SourceLocation CategoryNameLoc; - ObjCCategoryImplDecl(DeclContext *DC, IdentifierInfo *Id, + ObjCCategoryImplDecl(DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc) - : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, - nameLoc, atStartLoc), + : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, nameLoc, + atStartLoc), CategoryNameLoc(CategoryNameLoc) {} void anchor() override; @@ -2557,13 +2557,12 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; - static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, - IdentifierInfo *Id, - ObjCInterfaceDecl *classInterface, - SourceLocation nameLoc, - SourceLocation atStartLoc, - SourceLocation CategoryNameLoc); - static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCCategoryImplDecl * + Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, + ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, + SourceLocation atStartLoc, SourceLocation CategoryNameLoc); + static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ObjCCategoryDecl *getCategoryDecl() const; @@ -2645,7 +2644,8 @@ public: SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); - static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// init_iterator - Iterates through the ivar initializer list. using init_iterator = CXXCtorInitializer **; @@ -2785,7 +2785,7 @@ public: ObjCInterfaceDecl* aliasedClass); static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + GlobalDeclID ID); const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } @@ -2856,7 +2856,8 @@ public: ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc); - static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h index 73725e6e856..e542c3c8e66 100644 --- a/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclOpenMP.h @@ -1,4 +1,4 @@ -//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-===// +//===- DeclOpenMP.h - Classes for representing OpenMP directives -*- C++ -*-==// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -59,7 +59,7 @@ protected: } template - static T *createEmptyDirective(const ASTContext &C, unsigned ID, + static T *createEmptyDirective(const ASTContext &C, GlobalDeclID ID, unsigned NumClauses, unsigned NumChildren, Params &&... P) { auto *Inst = new (C, ID, size(NumClauses, NumChildren)) @@ -133,7 +133,7 @@ public: SourceLocation L, ArrayRef VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, - unsigned ID, unsigned N); + GlobalDeclID ID, unsigned N); typedef MutableArrayRef::iterator varlist_iterator; typedef ArrayRef::iterator varlist_const_iterator; @@ -214,7 +214,7 @@ public: QualType T, OMPDeclareReductionDecl *PrevDeclInScope); /// Create deserialized declare reduction node. static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + GlobalDeclID ID); /// Get combiner expression of the declare reduction construct. Expr *getCombiner() { return Combiner; } @@ -318,8 +318,8 @@ public: ArrayRef Clauses, OMPDeclareMapperDecl *PrevDeclInScope); /// Creates deserialized declare mapper node. - static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID, - unsigned N); + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; using clauselist_const_iterator = ArrayRef::iterator; @@ -397,7 +397,8 @@ public: IdentifierInfo *Id, QualType T, SourceLocation StartLoc); - static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -427,7 +428,7 @@ public: static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef CL); /// Create deserialized requires node. - static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static OMPRequiresDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; @@ -495,7 +496,7 @@ public: static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef VL, ArrayRef CL); - static OMPAllocateDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NVars, unsigned NClauses); typedef MutableArrayRef::iterator varlist_iterator; diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h index 832ad2de6b0..5b6a6b40b28 100755 --- a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h @@ -134,6 +134,7 @@ public: const_iterator end() const { return begin() + NumParams; } unsigned size() const { return NumParams; } + bool empty() const { return NumParams == 0; } ArrayRef asArray() { return llvm::ArrayRef(begin(), end()); } ArrayRef asArray() const { @@ -241,9 +242,6 @@ public: /// A template argument list. class TemplateArgumentList final : private llvm::TrailingObjects { - /// The template argument list. - const TemplateArgument *Arguments; - /// The number of template arguments in this template /// argument list. unsigned NumArguments; @@ -258,30 +256,11 @@ public: TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; - /// Type used to indicate that the template argument list itself is a - /// stack object. It does not own its template arguments. - enum OnStackType { OnStack }; - /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, ArrayRef Args); - /// Construct a new, temporary template argument list on the stack. - /// - /// The template argument list does not own the template arguments - /// provided. - explicit TemplateArgumentList(OnStackType, ArrayRef Args) - : Arguments(Args.data()), NumArguments(Args.size()) {} - - /// Produces a shallow copy of the given template argument list. - /// - /// This operation assumes that the input argument list outlives it. - /// This takes the list as a pointer to avoid looking like a copy - /// constructor, since this really isn't safe to use that way. - explicit TemplateArgumentList(const TemplateArgumentList *Other) - : Arguments(Other->data()), NumArguments(Other->size()) {} - /// Retrieve the template argument at a given index. const TemplateArgument &get(unsigned Idx) const { assert(Idx < NumArguments && "Invalid template argument index"); @@ -301,7 +280,9 @@ public: unsigned size() const { return NumArguments; } /// Retrieve a pointer to the template argument list. - const TemplateArgument *data() const { return Arguments; } + const TemplateArgument *data() const { + return getTrailingObjects(); + } }; void *allocateDefaultArgStorageChain(const ASTContext &C); @@ -497,7 +478,7 @@ class FunctionTemplateSpecializationInfo final public: /// The template arguments used to produce the function template /// specialization from the function template. - const TemplateArgumentList *TemplateArguments; + TemplateArgumentList *TemplateArguments; /// The template arguments as written in the sources, if provided. /// FIXME: Normally null; tail-allocate this. @@ -510,7 +491,7 @@ public: private: FunctionTemplateSpecializationInfo( FunctionDecl *FD, FunctionTemplateDecl *Template, - TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, + TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo) : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1), @@ -530,8 +511,7 @@ public: static FunctionTemplateSpecializationInfo * Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, - TemplateSpecializationKind TSK, - const TemplateArgumentList *TemplateArgs, + TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo); @@ -816,7 +796,7 @@ protected: /// /// The first value in the array is the number of specializations/partial /// specializations that follow. - uint32_t *LazySpecializations = nullptr; + GlobalDeclID *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -1106,7 +1086,8 @@ public: NamedDecl *Decl); /// Create an empty function template node. - static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1204,7 +1185,7 @@ class TemplateTypeParmDecl final : public TypeDecl, /// The default template argument, if any. using DefArgStorage = - DefaultArgStorage; + DefaultArgStorage; DefArgStorage DefaultArgument; TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, @@ -1223,9 +1204,9 @@ public: bool Typename, bool ParameterPack, bool HasTypeConstraint = false, std::optional NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - unsigned ID); + GlobalDeclID ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - unsigned ID, + GlobalDeclID ID, bool HasTypeConstraint); /// Whether this template type parameter was declared with @@ -1244,13 +1225,9 @@ public: bool hasDefaultArgument() const { return DefaultArgument.isSet(); } /// Retrieve the default argument, if any. - QualType getDefaultArgument() const { - return DefaultArgument.get()->getType(); - } - - /// Retrieves the default argument's source information, if any. - TypeSourceInfo *getDefaultArgumentInfo() const { - return DefaultArgument.get(); + const TemplateArgumentLoc &getDefaultArgument() const { + static const TemplateArgumentLoc NoneLoc; + return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc; } /// Retrieves the location of the default argument declaration. @@ -1263,9 +1240,8 @@ public: } /// Set the default argument for this template parameter. - void setDefaultArgument(TypeSourceInfo *DefArg) { - DefaultArgument.set(DefArg); - } + void setDefaultArgument(const ASTContext &C, + const TemplateArgumentLoc &DefArg); /// Set that this default argument was inherited from another /// parameter. @@ -1384,7 +1360,8 @@ class NonTypeTemplateParmDecl final /// The default template argument, if any, and whether or not /// it was inherited. - using DefArgStorage = DefaultArgStorage; + using DefArgStorage = + DefaultArgStorage; DefArgStorage DefaultArgument; // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index @@ -1408,14 +1385,14 @@ class NonTypeTemplateParmDecl final NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, - IdentifierInfo *Id, QualType T, + const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo) : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), TemplateParmPosition(D, P), ParameterPack(ParameterPack) {} NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, - IdentifierInfo *Id, QualType T, + const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos); @@ -1423,20 +1400,19 @@ class NonTypeTemplateParmDecl final public: static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, + SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo); static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, + SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos); + static NonTypeTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID, - bool HasTypeConstraint); - static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID, + GlobalDeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint); @@ -1455,7 +1431,10 @@ public: bool hasDefaultArgument() const { return DefaultArgument.isSet(); } /// Retrieve the default argument, if any. - Expr *getDefaultArgument() const { return DefaultArgument.get(); } + const TemplateArgumentLoc &getDefaultArgument() const { + static const TemplateArgumentLoc NoneLoc; + return DefaultArgument.isSet() ? *DefaultArgument.get() : NoneLoc; + } /// Retrieve the location of the default argument, if any. SourceLocation getDefaultArgumentLoc() const; @@ -1469,7 +1448,8 @@ public: /// Set the default argument for this template parameter, and /// whether that default argument was inherited from another /// declaration. - void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); } + void setDefaultArgument(const ASTContext &C, + const TemplateArgumentLoc &DefArg); void setInheritedDefaultArgument(const ASTContext &C, NonTypeTemplateParmDecl *Parm) { DefaultArgument.setInherited(C, Parm); @@ -1600,26 +1580,36 @@ class TemplateTemplateParmDecl final DefaultArgStorage; DefArgStorage DefaultArgument; + /// Whether this template template parameter was declaration with + /// the 'typename' keyword. + /// + /// If false, it was declared with the 'class' keyword. + LLVM_PREFERRED_TYPE(bool) + unsigned Typename : 1; + /// Whether this parameter is a parameter pack. - bool ParameterPack; + LLVM_PREFERRED_TYPE(bool) + unsigned ParameterPack : 1; /// Whether this template template parameter is an "expanded" /// parameter pack, meaning that it is a pack expansion and we /// already know the set of template parameters that expansion expands to. - bool ExpandedParameterPack = false; + LLVM_PREFERRED_TYPE(bool) + unsigned ExpandedParameterPack : 1; /// The number of parameters in an expanded parameter pack. unsigned NumExpandedParams = 0; - TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, - unsigned D, unsigned P, bool ParameterPack, - IdentifierInfo *Id, TemplateParameterList *Params) + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, bool ParameterPack, IdentifierInfo *Id, + bool Typename, TemplateParameterList *Params) : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), - TemplateParmPosition(D, P), ParameterPack(ParameterPack) {} + TemplateParmPosition(D, P), Typename(Typename), + ParameterPack(ParameterPack), ExpandedParameterPack(false) {} - TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, - unsigned D, unsigned P, - IdentifierInfo *Id, TemplateParameterList *Params, + TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, bool Typename, + TemplateParameterList *Params, ArrayRef Expansions); void anchor() override; @@ -1632,20 +1622,18 @@ public: static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, - IdentifierInfo *Id, + IdentifierInfo *Id, bool Typename, TemplateParameterList *Params); - static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, - SourceLocation L, unsigned D, - unsigned P, - IdentifierInfo *Id, - TemplateParameterList *Params, - ArrayRef Expansions); + static TemplateTemplateParmDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, + unsigned P, IdentifierInfo *Id, bool Typename, + TemplateParameterList *Params, + ArrayRef Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID); - static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID, - unsigned NumExpansions); + GlobalDeclID ID); + static TemplateTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1653,6 +1641,14 @@ public: using TemplateParmPosition::setPosition; using TemplateParmPosition::getIndex; + /// Whether this template template parameter was declared with + /// the 'typename' keyword. + bool wasDeclaredWithTypename() const { return Typename; } + + /// Set whether this template template parameter was declared with + /// the 'typename' or 'class' keyword. + void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; } + /// Whether this template template parameter is a template /// parameter pack. /// @@ -1779,6 +1775,25 @@ public: BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; } }; +/// Provides information about an explicit instantiation of a variable or class +/// template. +struct ExplicitInstantiationInfo { + /// The template arguments as written.. + const ASTTemplateArgumentListInfo *TemplateArgsAsWritten = nullptr; + + /// The location of the extern keyword. + SourceLocation ExternKeywordLoc; + + /// The location of the template keyword. + SourceLocation TemplateKeywordLoc; + + ExplicitInstantiationInfo() = default; +}; + +using SpecializationOrInstantiationInfo = + llvm::PointerUnion; + /// Represents a class template specialization, which refers to /// a class template with a given set of template arguments. /// @@ -1792,8 +1807,8 @@ public: /// template<> /// class array { }; // class template specialization array /// \endcode -class ClassTemplateSpecializationDecl - : public CXXRecordDecl, public llvm::FoldingSetNode { +class ClassTemplateSpecializationDecl : public CXXRecordDecl, + public llvm::FoldingSetNode { /// Structure that stores information about a class template /// specialization that was instantiated from a class template partial /// specialization. @@ -1811,23 +1826,9 @@ class ClassTemplateSpecializationDecl llvm::PointerUnion SpecializedTemplate; - /// Further info for explicit template specialization/instantiation. - struct ExplicitSpecializationInfo { - /// The type-as-written. - TypeSourceInfo *TypeAsWritten = nullptr; - - /// The location of the extern keyword. - SourceLocation ExternLoc; - - /// The location of the template keyword. - SourceLocation TemplateKeywordLoc; - - ExplicitSpecializationInfo() = default; - }; - /// Further info for explicit template specialization/instantiation. /// Does not apply to implicit specializations. - ExplicitSpecializationInfo *ExplicitInfo = nullptr; + SpecializationOrInstantiationInfo ExplicitInfo = nullptr; /// The template arguments used to describe this specialization. const TemplateArgumentList *TemplateArgs; @@ -1859,8 +1860,8 @@ public: ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); - static ClassTemplateSpecializationDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2004,44 +2005,49 @@ public: SpecializedTemplate = TemplDecl; } - /// Sets the type of this specialization as it was written by - /// the user. This will be a class template specialization type. - void setTypeAsWritten(TypeSourceInfo *T) { - if (!ExplicitInfo) - ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; - ExplicitInfo->TypeAsWritten = T; + /// Retrieve the template argument list as written in the sources, + /// if any. + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + if (auto *Info = ExplicitInfo.dyn_cast()) + return Info->TemplateArgsAsWritten; + return ExplicitInfo.get(); } - /// Gets the type of this specialization as it was written by - /// the user, if it was so written. - TypeSourceInfo *getTypeAsWritten() const { - return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr; + /// Set the template argument list as written in the sources. + void + setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) { + if (auto *Info = ExplicitInfo.dyn_cast()) + Info->TemplateArgsAsWritten = ArgsWritten; + else + ExplicitInfo = ArgsWritten; + } + + /// Set the template argument list as written in the sources. + void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) { + setTemplateArgsAsWritten( + ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo)); } /// Gets the location of the extern keyword, if present. - SourceLocation getExternLoc() const { - return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); + SourceLocation getExternKeywordLoc() const { + if (auto *Info = ExplicitInfo.dyn_cast()) + return Info->ExternKeywordLoc; + return SourceLocation(); } /// Sets the location of the extern keyword. - void setExternLoc(SourceLocation Loc) { - if (!ExplicitInfo) - ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; - ExplicitInfo->ExternLoc = Loc; - } - - /// Sets the location of the template keyword. - void setTemplateKeywordLoc(SourceLocation Loc) { - if (!ExplicitInfo) - ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; - ExplicitInfo->TemplateKeywordLoc = Loc; - } + void setExternKeywordLoc(SourceLocation Loc); /// Gets the location of the template keyword, if present. SourceLocation getTemplateKeywordLoc() const { - return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); + if (auto *Info = ExplicitInfo.dyn_cast()) + return Info->TemplateKeywordLoc; + return SourceLocation(); } + /// Sets the location of the template keyword. + void setTemplateKeywordLoc(SourceLocation Loc); + SourceRange getSourceRange() const override LLVM_READONLY; void Profile(llvm::FoldingSetNodeID &ID) const { @@ -2069,10 +2075,6 @@ class ClassTemplatePartialSpecializationDecl /// The list of template parameters TemplateParameterList* TemplateParams = nullptr; - /// The source info for the template arguments as written. - /// FIXME: redundant with TypeAsWritten? - const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; - /// The class template partial specialization from which this /// class template partial specialization was instantiated. /// @@ -2081,15 +2083,11 @@ class ClassTemplatePartialSpecializationDecl llvm::PointerIntPair InstantiatedFromMember; - ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, - DeclContext *DC, - SourceLocation StartLoc, - SourceLocation IdLoc, - TemplateParameterList *Params, - ClassTemplateDecl *SpecializedTemplate, - ArrayRef Args, - const ASTTemplateArgumentListInfo *ArgsAsWritten, - ClassTemplatePartialSpecializationDecl *PrevDecl); + ClassTemplatePartialSpecializationDecl( + ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, TemplateParameterList *Params, + ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, + ClassTemplatePartialSpecializationDecl *PrevDecl); ClassTemplatePartialSpecializationDecl(ASTContext &C) : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization), @@ -2104,15 +2102,12 @@ public: static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, - TemplateParameterList *Params, - ClassTemplateDecl *SpecializedTemplate, - ArrayRef Args, - const TemplateArgumentListInfo &ArgInfos, - QualType CanonInjectedType, + TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, + ArrayRef Args, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * - CreateDeserialized(ASTContext &C, unsigned ID); + CreateDeserialized(ASTContext &C, GlobalDeclID ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -2139,11 +2134,6 @@ public: return TemplateParams->hasAssociatedConstraints(); } - /// Get the template arguments as written. - const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { - return ArgsAsWritten; - } - /// Retrieve the member class template partial specialization from /// which this particular class template partial specialization was /// instantiated. @@ -2196,7 +2186,7 @@ public: /// template<> template /// struct X::Inner { /* ... */ }; /// \endcode - bool isMemberSpecialization() { + bool isMemberSpecialization() const { const auto *First = cast(getFirstDecl()); return First->InstantiatedFromMember.getInt(); @@ -2219,6 +2209,8 @@ public: ->getInjectedSpecializationType(); } + SourceRange getSourceRange() const override LLVM_READONLY; + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(), getASTContext()); @@ -2308,7 +2300,7 @@ public: NamedDecl *Decl); /// Create an empty class template node. - static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -2474,7 +2466,7 @@ public: MutableArrayRef Params, FriendUnion Friend, SourceLocation FriendLoc); - static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// If this friend declaration names a templated type (or /// a dependent member type of a templated type), return that @@ -2575,7 +2567,8 @@ public: NamedDecl *Decl); /// Create an empty alias template node. - static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2615,27 +2608,12 @@ class VarTemplateSpecializationDecl : public VarDecl, llvm::PointerUnion SpecializedTemplate; - /// Further info for explicit template specialization/instantiation. - struct ExplicitSpecializationInfo { - /// The type-as-written. - TypeSourceInfo *TypeAsWritten = nullptr; - - /// The location of the extern keyword. - SourceLocation ExternLoc; - - /// The location of the template keyword. - SourceLocation TemplateKeywordLoc; - - ExplicitSpecializationInfo() = default; - }; - /// Further info for explicit template specialization/instantiation. /// Does not apply to implicit specializations. - ExplicitSpecializationInfo *ExplicitInfo = nullptr; + SpecializationOrInstantiationInfo ExplicitInfo = nullptr; /// The template arguments used to describe this specialization. const TemplateArgumentList *TemplateArgs; - const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr; /// The point where this template was instantiated (if any). SourceLocation PointOfInstantiation; @@ -2672,7 +2650,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2689,14 +2667,6 @@ public: /// specialization. const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; } - // TODO: Always set this when creating the new specialization? - void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo); - void setTemplateArgsInfo(const ASTTemplateArgumentListInfo *ArgsInfo); - - const ASTTemplateArgumentListInfo *getTemplateArgsInfo() const { - return TemplateArgsInfo; - } - /// Determine the kind of specialization that this /// declaration represents. TemplateSpecializationKind getSpecializationKind() const { @@ -2800,44 +2770,49 @@ public: SpecializedTemplate = TemplDecl; } - /// Sets the type of this specialization as it was written by - /// the user. - void setTypeAsWritten(TypeSourceInfo *T) { - if (!ExplicitInfo) - ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; - ExplicitInfo->TypeAsWritten = T; + /// Retrieve the template argument list as written in the sources, + /// if any. + const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { + if (auto *Info = ExplicitInfo.dyn_cast()) + return Info->TemplateArgsAsWritten; + return ExplicitInfo.get(); } - /// Gets the type of this specialization as it was written by - /// the user, if it was so written. - TypeSourceInfo *getTypeAsWritten() const { - return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr; + /// Set the template argument list as written in the sources. + void + setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) { + if (auto *Info = ExplicitInfo.dyn_cast()) + Info->TemplateArgsAsWritten = ArgsWritten; + else + ExplicitInfo = ArgsWritten; + } + + /// Set the template argument list as written in the sources. + void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) { + setTemplateArgsAsWritten( + ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo)); } /// Gets the location of the extern keyword, if present. - SourceLocation getExternLoc() const { - return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); + SourceLocation getExternKeywordLoc() const { + if (auto *Info = ExplicitInfo.dyn_cast()) + return Info->ExternKeywordLoc; + return SourceLocation(); } /// Sets the location of the extern keyword. - void setExternLoc(SourceLocation Loc) { - if (!ExplicitInfo) - ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; - ExplicitInfo->ExternLoc = Loc; - } - - /// Sets the location of the template keyword. - void setTemplateKeywordLoc(SourceLocation Loc) { - if (!ExplicitInfo) - ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; - ExplicitInfo->TemplateKeywordLoc = Loc; - } + void setExternKeywordLoc(SourceLocation Loc); /// Gets the location of the template keyword, if present. SourceLocation getTemplateKeywordLoc() const { - return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); + if (auto *Info = ExplicitInfo.dyn_cast()) + return Info->TemplateKeywordLoc; + return SourceLocation(); } + /// Sets the location of the template keyword. + void setTemplateKeywordLoc(SourceLocation Loc); + SourceRange getSourceRange() const override LLVM_READONLY; void Profile(llvm::FoldingSetNodeID &ID) const { @@ -2865,10 +2840,6 @@ class VarTemplatePartialSpecializationDecl /// The list of template parameters TemplateParameterList *TemplateParams = nullptr; - /// The source info for the template arguments as written. - /// FIXME: redundant with TypeAsWritten? - const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; - /// The variable template partial specialization from which this /// variable template partial specialization was instantiated. /// @@ -2881,8 +2852,7 @@ class VarTemplatePartialSpecializationDecl ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, ArrayRef Args, - const ASTTemplateArgumentListInfo *ArgInfos); + StorageClass S, ArrayRef Args); VarTemplatePartialSpecializationDecl(ASTContext &Context) : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, @@ -2899,11 +2869,11 @@ public: Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, - TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args, - const TemplateArgumentListInfo &ArgInfos); + TypeSourceInfo *TInfo, StorageClass S, + ArrayRef Args); - static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + static VarTemplatePartialSpecializationDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID); VarTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -2916,11 +2886,6 @@ public: return TemplateParams; } - /// Get the template arguments as written. - const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { - return ArgsAsWritten; - } - /// \brief All associated constraints of this partial specialization, /// including the requires clause and any constraints derived from /// constrained-parameters. @@ -2983,7 +2948,7 @@ public: /// template<> template /// U* X::Inner = (T*)(0) + 1; /// \endcode - bool isMemberSpecialization() { + bool isMemberSpecialization() const { const auto *First = cast(getFirstDecl()); return First->InstantiatedFromMember.getInt(); @@ -3080,7 +3045,7 @@ public: VarDecl *Decl); /// Create an empty variable template node. - static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -3185,7 +3150,7 @@ public: SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr); - static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID); + static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getConstraintExpr() const { return ConstraintExpr; @@ -3234,7 +3199,7 @@ public: Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef ConvertedArgs); static ImplicitConceptSpecializationDecl * - CreateDeserialized(const ASTContext &C, unsigned ID, + CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs); ArrayRef getTemplateArguments() const { @@ -3277,7 +3242,7 @@ private: static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T, const APValue &V); static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + GlobalDeclID ID); /// Only ASTContext::getTemplateParamObjectDecl and deserialization /// create these. diff --git a/contrib/llvm-project/clang/include/clang/AST/Expr.h b/contrib/llvm-project/clang/include/clang/AST/Expr.h index 9820bd11da8..5b813bfc2fa 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Expr.h +++ b/contrib/llvm-project/clang/include/clang/AST/Expr.h @@ -82,7 +82,7 @@ struct SubobjectAdjustment { union { struct DTB DerivedToBase; - FieldDecl *Field; + const FieldDecl *Field; struct P Ptr; }; @@ -93,8 +93,7 @@ struct SubobjectAdjustment { DerivedToBase.DerivedClass = DerivedClass; } - SubobjectAdjustment(FieldDecl *Field) - : Kind(FieldAdjustment) { + SubobjectAdjustment(const FieldDecl *Field) : Kind(FieldAdjustment) { this->Field = Field; } @@ -154,6 +153,12 @@ public: TR = t; } + /// If this expression is an enumeration constant, return the + /// enumeration type under which said constant was declared. + /// Otherwise return the expression's type. + /// Note this effectively circumvents the weak typing of C's enum constants + QualType getEnumCoercedType(const ASTContext &Ctx) const; + ExprDependence getDependence() const { return static_cast(ExprBits.Dependent); } @@ -379,7 +384,7 @@ public: bool isRValue() const { return Kind >= CL_XValue; } bool isModifiable() const { return getModifiable() == CM_Modifiable; } - /// Create a simple, modifiably lvalue + /// Create a simple, modifiable lvalue static Classification makeSimpleLValue() { return Classification(CL_LValue, CM_Modifiable); } @@ -472,6 +477,13 @@ public: /// bit-fields, but it will return null for a conditional bit-field. FieldDecl *getSourceBitField(); + /// If this expression refers to an enum constant, retrieve its declaration + EnumConstantDecl *getEnumConstantDecl(); + + const EnumConstantDecl *getEnumConstantDecl() const { + return const_cast(this)->getEnumConstantDecl(); + } + const FieldDecl *getSourceBitField() const { return const_cast(this)->getSourceBitField(); } @@ -775,6 +787,11 @@ public: const Expr *PtrExpression, ASTContext &Ctx, EvalResult &Status) const; + /// If the current Expr can be evaluated to a pointer to a null-terminated + /// constant string, return the constant string (without the terminating + /// null). + std::optional tryEvaluateString(ASTContext &Ctx) const; + /// Enumeration used to describe the kind of Null pointer constant /// returned from \c isNullPointerConstant(). enum NullPointerConstantKind { @@ -1275,7 +1292,7 @@ class DeclRefExpr final DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, - bool RefersToEnlosingVariableOrCapture, + bool RefersToEnclosingVariableOrCapture, const DeclarationNameInfo &NameInfo, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK, NonOdrUseReason NOUR); @@ -1641,14 +1658,14 @@ public: } /// Get a raw enumeration value representing the floating-point semantics of - /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. + /// this literal (32-bit IEEE, x87, ...), suitable for serialization. llvm::APFloatBase::Semantics getRawSemantics() const { return static_cast( FloatingLiteralBits.Semantics); } /// Set the raw enumeration value representing the floating-point semantics of - /// this literal (32-bit IEEE, x87, ...), suitable for serialisation. + /// this literal (32-bit IEEE, x87, ...), suitable for serialization. void setRawSemantics(llvm::APFloatBase::Semantics Sem) { FloatingLiteralBits.Semantics = Sem; } @@ -1863,6 +1880,17 @@ public: llvm_unreachable("Unsupported character width!"); } + // Get code unit but preserve sign info. + int64_t getCodeUnitS(size_t I, uint64_t BitWidth) const { + int64_t V = getCodeUnit(I); + if (isOrdinary() || isWide()) { + unsigned Width = getCharByteWidth() * BitWidth; + llvm::APInt AInt(Width, (uint64_t)V); + V = AInt.getSExtValue(); + } + return V; + } + unsigned getByteLength() const { return getCharByteWidth() * getLength(); } unsigned getLength() const { return *getTrailingObjects(); } unsigned getCharByteWidth() const { return StringLiteralBits.CharByteWidth; } @@ -2022,7 +2050,8 @@ public: } static std::string ComputeName(PredefinedIdentKind IK, - const Decl *CurrentDecl); + const Decl *CurrentDecl, + bool ForceElaboratedPrinting = false); SourceLocation getBeginLoc() const { return getLocation(); } SourceLocation getEndLoc() const { return getLocation(); } @@ -2101,7 +2130,7 @@ public: static std::string ComputeName(ASTContext &Context, QualType Ty); }; -/// ParenExpr - This represents a parethesized expression, e.g. "(1)". This +/// ParenExpr - This represents a parenthesized expression, e.g. "(1)". This /// AST node is only formed if full location information is requested. class ParenExpr : public Expr { SourceLocation L, R; @@ -2217,7 +2246,7 @@ public: bool canOverflow() const { return UnaryOperatorBits.CanOverflow; } void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; } - /// Get the FP contractability status of this operator. Only meaningful for + /// Get the FP contractibility status of this operator. Only meaningful for /// operations on floating point types. bool isFPContractableWithinStatement(const LangOptions &LO) const { return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); @@ -2304,6 +2333,11 @@ public: return getTrailingFPFeatures(); } + /// Get the store FPOptionsOverride or default if not stored. + FPOptionsOverride getStoredFPFeaturesOrDefault() const { + return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride(); + } + protected: /// Set FPFeatures in trailing storage, used by Serialization & ASTImporter. void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; } @@ -3067,6 +3101,11 @@ public: *getTrailingFPFeatures() = F; } + /// Get the store FPOptionsOverride or default if not stored. + FPOptionsOverride getStoredFPFeaturesOrDefault() const { + return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride(); + } + /// Get the FP features status of this operator. Only meaningful for /// operations on floating point types. FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { @@ -3139,23 +3178,12 @@ public: } }; -/// Extra data stored in some MemberExpr objects. -struct MemberExprNameQualifier { - /// The nested-name-specifier that qualifies the name, including - /// source-location information. - NestedNameSpecifierLoc QualifierLoc; - - /// The DeclAccessPair through which the MemberDecl was found due to - /// name qualifiers. - DeclAccessPair FoundDecl; -}; - /// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F. /// class MemberExpr final : public Expr, - private llvm::TrailingObjects { friend class ASTReader; friend class ASTStmtReader; @@ -3177,26 +3205,30 @@ class MemberExpr final /// MemberLoc - This is the location of the member name. SourceLocation MemberLoc; - size_t numTrailingObjects(OverloadToken) const { - return hasQualifierOrFoundDecl(); + size_t numTrailingObjects(OverloadToken) const { + return hasQualifier(); + } + + size_t numTrailingObjects(OverloadToken) const { + return hasFoundDecl(); } size_t numTrailingObjects(OverloadToken) const { return hasTemplateKWAndArgsInfo(); } - bool hasQualifierOrFoundDecl() const { - return MemberExprBits.HasQualifierOrFoundDecl; - } + bool hasFoundDecl() const { return MemberExprBits.HasFoundDecl; } bool hasTemplateKWAndArgsInfo() const { return MemberExprBits.HasTemplateKWAndArgsInfo; } MemberExpr(Expr *Base, bool IsArrow, SourceLocation OperatorLoc, - ValueDecl *MemberDecl, const DeclarationNameInfo &NameInfo, - QualType T, ExprValueKind VK, ExprObjectKind OK, - NonOdrUseReason NOUR); + NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, + ValueDecl *MemberDecl, DeclAccessPair FoundDecl, + const DeclarationNameInfo &NameInfo, + const TemplateArgumentListInfo *TemplateArgs, QualType T, + ExprValueKind VK, ExprObjectKind OK, NonOdrUseReason NOUR); MemberExpr(EmptyShell Empty) : Expr(MemberExprClass, Empty), Base(), MemberDecl() {} @@ -3240,24 +3272,24 @@ public: /// Retrieves the declaration found by lookup. DeclAccessPair getFoundDecl() const { - if (!hasQualifierOrFoundDecl()) + if (!hasFoundDecl()) return DeclAccessPair::make(getMemberDecl(), getMemberDecl()->getAccess()); - return getTrailingObjects()->FoundDecl; + return *getTrailingObjects(); } /// Determines whether this member expression actually had /// a C++ nested-name-specifier prior to the name of the member, e.g., /// x->Base::foo. - bool hasQualifier() const { return getQualifier() != nullptr; } + bool hasQualifier() const { return MemberExprBits.HasQualifier; } /// If the member name was qualified, retrieves the /// nested-name-specifier that precedes the member name, with source-location /// information. NestedNameSpecifierLoc getQualifierLoc() const { - if (!hasQualifierOrFoundDecl()) + if (!hasQualifier()) return NestedNameSpecifierLoc(); - return getTrailingObjects()->QualifierLoc; + return *getTrailingObjects(); } /// If the member name was qualified, retrieves the @@ -3538,6 +3570,18 @@ public: path_const_iterator path_begin() const { return path_buffer(); } path_const_iterator path_end() const { return path_buffer() + path_size(); } + /// Path through the class hierarchy taken by casts between base and derived + /// classes (see implementation of `CastConsistency()` for a full list of + /// cast kinds that have a path). + /// + /// For each derived-to-base edge in the path, the path contains a + /// `CXXBaseSpecifier` for the base class of that edge; the entries are + /// ordered from derived class to base class. + /// + /// For example, given classes `Base`, `Intermediate : public Base` and + /// `Derived : public Intermediate`, the path for a cast from `Derived *` to + /// `Base *` contains two entries: One for `Intermediate`, and one for `Base`, + /// in that order. llvm::iterator_range path() { return llvm::make_range(path_begin(), path_end()); } @@ -3558,6 +3602,11 @@ public: return *getTrailingFPFeatures(); } + /// Get the store FPOptionsOverride or default if not stored. + FPOptionsOverride getStoredFPFeaturesOrDefault() const { + return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride(); + } + /// Get the FP features status of this operation. Only meaningful for /// operations on floating point types. FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { @@ -4004,6 +4053,10 @@ public: assert(BinaryOperatorBits.HasFPFeatures); *getTrailingFPFeatures() = F; } + /// Get the store FPOptionsOverride or default if not stored. + FPOptionsOverride getStoredFPFeaturesOrDefault() const { + return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride(); + } /// Get the FP features status of this operator. Only meaningful for /// operations on floating point types. @@ -4020,7 +4073,7 @@ public: return FPOptionsOverride(); } - /// Get the FP contractability status of this operator. Only meaningful for + /// Get the FP contractibility status of this operator. Only meaningful for /// operations on floating point types. bool isFPContractableWithinStatement(const LangOptions &LO) const { return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); @@ -4261,7 +4314,7 @@ public: } /// getFalseExpr - Return the subexpression which will be - /// evaluated if the condnition evaluates to false; this is + /// evaluated if the condition evaluates to false; this is /// defined in terms of the opaque value. Expr *getFalseExpr() const { return cast(SubExprs[RHS]); @@ -4770,6 +4823,164 @@ private: friend class ASTStmtReader; }; +/// Stores data related to a single #embed directive. +struct EmbedDataStorage { + StringLiteral *BinaryData; + size_t getDataElementCount() const { return BinaryData->getByteLength(); } +}; + +/// Represents a reference to #emded data. By default, this references the whole +/// range. Otherwise it represents a subrange of data imported by #embed +/// directive. Needed to handle nested initializer lists with #embed directives. +/// Example: +/// struct S { +/// int x, y; +/// }; +/// +/// struct T { +/// int x[2]; +/// struct S s +/// }; +/// +/// struct T t[] = { +/// #embed "data" // data contains 10 elements; +/// }; +/// +/// The resulting semantic form of initializer list will contain (EE stands +/// for EmbedExpr): +/// { {EE(first two data elements), {EE(3rd element), EE(4th element) }}, +/// { {EE(5th and 6th element), {EE(7th element), EE(8th element) }}, +/// { {EE(9th and 10th element), { zeroinitializer }}} +/// +/// EmbedExpr inside of a semantic initializer list and referencing more than +/// one element can only appear for arrays of scalars. +class EmbedExpr final : public Expr { + SourceLocation EmbedKeywordLoc; + IntegerLiteral *FakeChildNode = nullptr; + const ASTContext *Ctx = nullptr; + EmbedDataStorage *Data; + unsigned Begin = 0; + unsigned NumOfElements; + +public: + EmbedExpr(const ASTContext &Ctx, SourceLocation Loc, EmbedDataStorage *Data, + unsigned Begin, unsigned NumOfElements); + explicit EmbedExpr(EmptyShell Empty) : Expr(SourceLocExprClass, Empty) {} + + SourceLocation getLocation() const { return EmbedKeywordLoc; } + SourceLocation getBeginLoc() const { return EmbedKeywordLoc; } + SourceLocation getEndLoc() const { return EmbedKeywordLoc; } + + StringLiteral *getDataStringLiteral() const { return Data->BinaryData; } + EmbedDataStorage *getData() const { return Data; } + + unsigned getStartingElementPos() const { return Begin; } + size_t getDataElementCount() const { return NumOfElements; } + + // Allows accessing every byte of EmbedExpr data and iterating over it. + // An Iterator knows the EmbedExpr that it refers to, and an offset value + // within the data. + // Dereferencing an Iterator results in construction of IntegerLiteral AST + // node filled with byte of data of the corresponding EmbedExpr within offset + // that the Iterator currently has. + template + class ChildElementIter + : public llvm::iterator_facade_base< + ChildElementIter, std::random_access_iterator_tag, + std::conditional_t> { + friend class EmbedExpr; + + EmbedExpr *EExpr = nullptr; + unsigned long long CurOffset = ULLONG_MAX; + using BaseTy = typename ChildElementIter::iterator_facade_base; + + ChildElementIter(EmbedExpr *E) : EExpr(E) { + if (E) + CurOffset = E->getStartingElementPos(); + } + + public: + ChildElementIter() : CurOffset(ULLONG_MAX) {} + typename BaseTy::reference operator*() const { + assert(EExpr && CurOffset != ULLONG_MAX && + "trying to dereference an invalid iterator"); + IntegerLiteral *N = EExpr->FakeChildNode; + StringRef DataRef = EExpr->Data->BinaryData->getBytes(); + N->setValue(*EExpr->Ctx, + llvm::APInt(N->getValue().getBitWidth(), DataRef[CurOffset], + N->getType()->isSignedIntegerType())); + // We want to return a reference to the fake child node in the + // EmbedExpr, not the local variable N. + return const_cast(EExpr->FakeChildNode); + } + typename BaseTy::pointer operator->() const { return **this; } + using BaseTy::operator++; + ChildElementIter &operator++() { + assert(EExpr && "trying to increment an invalid iterator"); + assert(CurOffset != ULLONG_MAX && + "Already at the end of what we can iterate over"); + if (++CurOffset >= + EExpr->getDataElementCount() + EExpr->getStartingElementPos()) { + CurOffset = ULLONG_MAX; + EExpr = nullptr; + } + return *this; + } + bool operator==(ChildElementIter Other) const { + return (EExpr == Other.EExpr && CurOffset == Other.CurOffset); + } + }; // class ChildElementIter + +public: + using fake_child_range = llvm::iterator_range>; + using const_fake_child_range = llvm::iterator_range>; + + fake_child_range underlying_data_elements() { + return fake_child_range(ChildElementIter(this), + ChildElementIter()); + } + + const_fake_child_range underlying_data_elements() const { + return const_fake_child_range( + ChildElementIter(const_cast(this)), + ChildElementIter()); + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == EmbedExprClass; + } + + ChildElementIter begin() { return ChildElementIter(this); } + + ChildElementIter begin() const { + return ChildElementIter(const_cast(this)); + } + + template + bool doForEachDataElement(Call &&C, unsigned &StartingIndexInArray, + Targs &&...Fargs) const { + for (auto It : underlying_data_elements()) { + if (!std::invoke(std::forward(C), const_cast(It), + StartingIndexInArray, std::forward(Fargs)...)) + return false; + StartingIndexInArray++; + } + return true; + } + +private: + friend class ASTStmtReader; +}; + /// Describes an C or C++ initializer list. /// /// InitListExpr describes an initializer list, which can be used to @@ -5811,7 +6022,7 @@ class GenericSelectionExpr final // if *It1 and *It2 are bound to the same objects. // An alternative design approach was discussed during review; // store an Association object inside the iterator, and return a reference - // to it when dereferenced. This idea was discarded beacuse of nasty + // to it when dereferenced. This idea was discarded because of nasty // lifetime issues: // AssociationIterator It = ...; // const Association &Assoc = *It++; // Oops, Assoc is dangling. @@ -5820,7 +6031,7 @@ class GenericSelectionExpr final std::conditional_t; using TSIPtrPtrTy = std::conditional_t; - StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped. + StmtPtrPtrTy E = nullptr; TSIPtrPtrTy TSI; // Kept in sync with E. unsigned Offset = 0, SelectedOffset = 0; AssociationIteratorTy(StmtPtrPtrTy E, TSIPtrPtrTy TSI, unsigned Offset, @@ -6410,7 +6621,7 @@ public: enum AtomicOp { #define BUILTIN(ID, TYPE, ATTRS) #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) AO ## ID, -#include "clang/Basic/Builtins.def" +#include "clang/Basic/Builtins.inc" // Avoid trailing comma BI_First = 0 }; @@ -6476,7 +6687,7 @@ public: #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ case AO##ID: \ return #ID; -#include "clang/Basic/Builtins.def" +#include "clang/Basic/Builtins.inc" } llvm_unreachable("not an atomic operator?"); } @@ -6505,8 +6716,8 @@ public: } bool isOpenCL() const { - return getOp() >= AO__opencl_atomic_init && - getOp() <= AO__opencl_atomic_fetch_max; + return getOp() >= AO__opencl_atomic_compare_exchange_strong && + getOp() <= AO__opencl_atomic_store; } SourceLocation getBuiltinLoc() const { return BuiltinLoc; } @@ -6531,11 +6742,14 @@ public: /// \return empty atomic scope model if the atomic op code does not have /// scope operand. static std::unique_ptr getScopeModel(AtomicOp Op) { - if (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max) + // FIXME: Allow grouping of builtins to be able to only check >= and <= + if (Op >= AO__opencl_atomic_compare_exchange_strong && + Op <= AO__opencl_atomic_store && Op != AO__opencl_atomic_init) return AtomicScopeModel::create(AtomicScopeModelKind::OpenCL); - else if (Op >= AO__hip_atomic_load && Op <= AO__hip_atomic_fetch_max) + if (Op >= AO__hip_atomic_compare_exchange_strong && + Op <= AO__hip_atomic_store) return AtomicScopeModel::create(AtomicScopeModelKind::HIP); - else if (Op >= AO__scoped_atomic_load && Op <= AO__scoped_atomic_fetch_max) + if (Op >= AO__scoped_atomic_add_fetch && Op <= AO__scoped_atomic_xor_fetch) return AtomicScopeModel::create(AtomicScopeModelKind::Generic); return AtomicScopeModel::create(AtomicScopeModelKind::None); } @@ -6578,6 +6792,275 @@ public: }; +/// This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', +/// with a boolean differentiator. +/// OpenMP 5.0 [2.1.5, Array Sections]. +/// To specify an array section in an OpenMP construct, array subscript +/// expressions are extended with the following syntax: +/// \code +/// [ lower-bound : length : stride ] +/// [ lower-bound : length : ] +/// [ lower-bound : length ] +/// [ lower-bound : : stride ] +/// [ lower-bound : : ] +/// [ lower-bound : ] +/// [ : length : stride ] +/// [ : length : ] +/// [ : length ] +/// [ : : stride ] +/// [ : : ] +/// [ : ] +/// \endcode +/// The array section must be a subset of the original array. +/// Array sections are allowed on multidimensional arrays. Base language array +/// subscript expressions can be used to specify length-one dimensions of +/// multidimensional array sections. +/// Each of the lower-bound, length, and stride expressions if specified must be +/// an integral type expressions of the base language. When evaluated +/// they represent a set of integer values as follows: +/// \code +/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... , +/// lower-bound + ((length - 1) * stride) } +/// \endcode +/// The lower-bound and length must evaluate to non-negative integers. +/// The stride must evaluate to a positive integer. +/// When the size of the array dimension is not known, the length must be +/// specified explicitly. +/// When the stride is absent it defaults to 1. +/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉, +/// where size is the size of the array dimension. When the lower-bound is +/// absent it defaults to 0. +/// +/// +/// OpenACC 3.3 [2.7.1 Data Specification in Data Clauses] +/// In C and C++, a subarray is an array name followed by an extended array +/// range specification in brackets, with start and length, such as +/// +/// AA[2:n] +/// +/// If the lower bound is missing, zero is used. If the length is missing and +/// the array has known size, the size of the array is used; otherwise the +/// length is required. The subarray AA[2:n] means elements AA[2], AA[3], . . . +/// , AA[2+n-1]. In C and C++, a two dimensional array may be declared in at +/// least four ways: +/// +/// -Statically-sized array: float AA[100][200]; +/// -Pointer to statically sized rows: typedef float row[200]; row* BB; +/// -Statically-sized array of pointers: float* CC[200]; +/// -Pointer to pointers: float** DD; +/// +/// Each dimension may be statically sized, or a pointer to dynamically +/// allocated memory. Each of these may be included in a data clause using +/// subarray notation to specify a rectangular array: +/// +/// -AA[2:n][0:200] +/// -BB[2:n][0:m] +/// -CC[2:n][0:m] +/// -DD[2:n][0:m] +/// +/// Multidimensional rectangular subarrays in C and C++ may be specified for any +/// array with any combination of statically-sized or dynamically-allocated +/// dimensions. For statically sized dimensions, all dimensions except the first +/// must specify the whole extent to preserve the contiguous data restriction, +/// discussed below. For dynamically allocated dimensions, the implementation +/// will allocate pointers in device memory corresponding to the pointers in +/// local memory and will fill in those pointers as appropriate. +/// +/// In Fortran, a subarray is an array name followed by a comma-separated list +/// of range specifications in parentheses, with lower and upper bound +/// subscripts, such as +/// +/// arr(1:high,low:100) +/// +/// If either the lower or upper bounds are missing, the declared or allocated +/// bounds of the array, if known, are used. All dimensions except the last must +/// specify the whole extent, to preserve the contiguous data restriction, +/// discussed below. +/// +/// Restrictions +/// +/// -In Fortran, the upper bound for the last dimension of an assumed-size dummy +/// array must be specified. +/// +/// -In C and C++, the length for dynamically allocated dimensions of an array +/// must be explicitly specified. +/// +/// -In C and C++, modifying pointers in pointer arrays during the data +/// lifetime, either on the host or on the device, may result in undefined +/// behavior. +/// +/// -If a subarray appears in a data clause, the implementation may choose to +/// allocate memory for only that subarray on the accelerator. +/// +/// -In Fortran, array pointers may appear, but pointer association is not +/// preserved in device memory. +/// +/// -Any array or subarray in a data clause, including Fortran array pointers, +/// must be a contiguous section of memory, except for dynamic multidimensional +/// C arrays. +/// +/// -In C and C++, if a variable or array of composite type appears, all the +/// data members of the struct or class are allocated and copied, as +/// appropriate. If a composite member is a pointer type, the data addressed by +/// that pointer are not implicitly copied. +/// +/// -In Fortran, if a variable or array of composite type appears, all the +/// members of that derived type are allocated and copied, as appropriate. If +/// any member has the allocatable or pointer attribute, the data accessed +/// through that member are not copied. +/// +/// -If an expression is used in a subscript or subarray expression in a clause +/// on a data construct, the same value is used when copying data at the end of +/// the data region, even if the values of variables in the expression change +/// during the data region. +class ArraySectionExpr : public Expr { + friend class ASTStmtReader; + friend class ASTStmtWriter; + +public: + enum ArraySectionType { OMPArraySection, OpenACCArraySection }; + +private: + enum { + BASE, + LOWER_BOUND, + LENGTH, + STRIDE, + END_EXPR, + OPENACC_END_EXPR = STRIDE + }; + + ArraySectionType ASType = OMPArraySection; + Stmt *SubExprs[END_EXPR] = {nullptr}; + SourceLocation ColonLocFirst; + SourceLocation ColonLocSecond; + SourceLocation RBracketLoc; + +public: + // Constructor for OMP array sections, which include a 'stride'. + ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride, + QualType Type, ExprValueKind VK, ExprObjectKind OK, + SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, + SourceLocation RBracketLoc) + : Expr(ArraySectionExprClass, Type, VK, OK), ASType(OMPArraySection), + ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond), + RBracketLoc(RBracketLoc) { + setBase(Base); + setLowerBound(LowerBound); + setLength(Length); + setStride(Stride); + setDependence(computeDependence(this)); + } + + // Constructor for OpenACC sub-arrays, which do not permit a 'stride'. + ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type, + ExprValueKind VK, ExprObjectKind OK, SourceLocation ColonLoc, + SourceLocation RBracketLoc) + : Expr(ArraySectionExprClass, Type, VK, OK), ASType(OpenACCArraySection), + ColonLocFirst(ColonLoc), RBracketLoc(RBracketLoc) { + setBase(Base); + setLowerBound(LowerBound); + setLength(Length); + setDependence(computeDependence(this)); + } + + /// Create an empty array section expression. + explicit ArraySectionExpr(EmptyShell Shell) + : Expr(ArraySectionExprClass, Shell) {} + + /// Return original type of the base expression for array section. + static QualType getBaseOriginalType(const Expr *Base); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ArraySectionExprClass; + } + + bool isOMPArraySection() const { return ASType == OMPArraySection; } + bool isOpenACCArraySection() const { return ASType == OpenACCArraySection; } + + /// Get base of the array section. + Expr *getBase() { return cast(SubExprs[BASE]); } + const Expr *getBase() const { return cast(SubExprs[BASE]); } + + /// Get lower bound of array section. + Expr *getLowerBound() { return cast_or_null(SubExprs[LOWER_BOUND]); } + const Expr *getLowerBound() const { + return cast_or_null(SubExprs[LOWER_BOUND]); + } + + /// Get length of array section. + Expr *getLength() { return cast_or_null(SubExprs[LENGTH]); } + const Expr *getLength() const { return cast_or_null(SubExprs[LENGTH]); } + + /// Get stride of array section. + Expr *getStride() { + assert(ASType != OpenACCArraySection && + "Stride not valid in OpenACC subarrays"); + return cast_or_null(SubExprs[STRIDE]); + } + + const Expr *getStride() const { + assert(ASType != OpenACCArraySection && + "Stride not valid in OpenACC subarrays"); + return cast_or_null(SubExprs[STRIDE]); + } + + SourceLocation getBeginLoc() const LLVM_READONLY { + return getBase()->getBeginLoc(); + } + SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } + + SourceLocation getColonLocFirst() const { return ColonLocFirst; } + SourceLocation getColonLocSecond() const { + assert(ASType != OpenACCArraySection && + "second colon for stride not valid in OpenACC subarrays"); + return ColonLocSecond; + } + SourceLocation getRBracketLoc() const { return RBracketLoc; } + + SourceLocation getExprLoc() const LLVM_READONLY { + return getBase()->getExprLoc(); + } + + child_range children() { + return child_range( + &SubExprs[BASE], + &SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]); + } + + const_child_range children() const { + return const_child_range( + &SubExprs[BASE], + &SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]); + } + +private: + /// Set base of the array section. + void setBase(Expr *E) { SubExprs[BASE] = E; } + + /// Set lower bound of the array section. + void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; } + + /// Set length of the array section. + void setLength(Expr *E) { SubExprs[LENGTH] = E; } + + /// Set length of the array section. + void setStride(Expr *E) { + assert(ASType != OpenACCArraySection && + "Stride not valid in OpenACC subarrays"); + SubExprs[STRIDE] = E; + } + + void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; } + + void setColonLocSecond(SourceLocation L) { + assert(ASType != OpenACCArraySection && + "second colon for stride not valid in OpenACC subarrays"); + ColonLocSecond = L; + } + void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } +}; + /// Frontend produces RecoveryExprs on semantic errors that prevent creating /// other well-formed expressions. E.g. when type-checking of a binary operator /// fails, we cannot produce a BinaryOperator expression. Instead, we can choose diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h b/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h index 9a7c632c36c..c2feac525c1 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h +++ b/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h @@ -919,6 +919,10 @@ public: reinterpret_cast(&const_cast(this)->Operand); return const_child_range(begin, begin + 1); } + + /// Whether this is of a form like "typeid(*ptr)" that can throw a + /// std::bad_typeid if a pointer is a null pointer ([expr.typeid]p2) + bool hasNullCheck() const; }; /// A member reference to an MSPropertyDecl. @@ -1149,6 +1153,7 @@ class CXXThisExpr : public Expr { CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit, ExprValueKind VK) : Expr(CXXThisExprClass, Ty, VK, OK_Ordinary) { CXXThisExprBits.IsImplicit = IsImplicit; + CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; CXXThisExprBits.Loc = L; setDependence(computeDependence(this)); } @@ -1170,6 +1175,15 @@ public: bool isImplicit() const { return CXXThisExprBits.IsImplicit; } void setImplicit(bool I) { CXXThisExprBits.IsImplicit = I; } + bool isCapturedByCopyInLambdaWithExplicitObjectParameter() const { + return CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter; + } + + void setCapturedByCopyInLambdaWithExplicitObjectParameter(bool Set) { + CXXThisExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = Set; + setDependence(computeDependence(this)); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXThisExprClass; } @@ -1472,6 +1486,8 @@ public: /// const S &s_ref = S(); // Requires a CXXBindTemporaryExpr. /// } /// \endcode +/// +/// Destructor might be null if destructor declaration is not valid. class CXXBindTemporaryExpr : public Expr { CXXTemporary *Temp = nullptr; Stmt *SubExpr = nullptr; @@ -2549,7 +2565,7 @@ public: class PseudoDestructorTypeStorage { /// Either the type source information or the name of the type, if /// it couldn't be resolved due to type-dependence. - llvm::PointerUnion Type; + llvm::PointerUnion Type; /// The starting source location of the pseudo-destructor type. SourceLocation Location; @@ -2557,7 +2573,7 @@ class PseudoDestructorTypeStorage { public: PseudoDestructorTypeStorage() = default; - PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc) + PseudoDestructorTypeStorage(const IdentifierInfo *II, SourceLocation Loc) : Type(II), Location(Loc) {} PseudoDestructorTypeStorage(TypeSourceInfo *Info); @@ -2566,8 +2582,8 @@ public: return Type.dyn_cast(); } - IdentifierInfo *getIdentifier() const { - return Type.dyn_cast(); + const IdentifierInfo *getIdentifier() const { + return Type.dyn_cast(); } SourceLocation getLocation() const { return Location; } @@ -2698,7 +2714,7 @@ public: /// In a dependent pseudo-destructor expression for which we do not /// have full type information on the destroyed type, provides the name /// of the destroyed type. - IdentifierInfo *getDestroyedTypeIdentifier() const { + const IdentifierInfo *getDestroyedTypeIdentifier() const { return DestroyedType.getIdentifier(); } @@ -3013,9 +3029,10 @@ protected: public: struct FindResult { - OverloadExpr *Expression; - bool IsAddressOfOperand; - bool HasFormOfMemberPointer; + OverloadExpr *Expression = nullptr; + bool IsAddressOfOperand = false; + bool IsAddressOfOperandWithParen = false; + bool HasFormOfMemberPointer = false; }; /// Finds the overloaded expression in the given expression \p E of @@ -3027,6 +3044,7 @@ public: assert(E->getType()->isSpecificBuiltinType(BuiltinType::Overload)); FindResult Result; + bool HasParen = isa(E); E = E->IgnoreParens(); if (isa(E)) { @@ -3036,10 +3054,9 @@ public: Result.HasFormOfMemberPointer = (E == Ovl && Ovl->getQualifier()); Result.IsAddressOfOperand = true; + Result.IsAddressOfOperandWithParen = HasParen; Result.Expression = Ovl; } else { - Result.HasFormOfMemberPointer = false; - Result.IsAddressOfOperand = false; Result.Expression = cast(E); } @@ -3151,8 +3168,30 @@ public: /// This arises in several ways: /// * we might be waiting for argument-dependent lookup; /// * the name might resolve to an overloaded function; +/// * the name might resolve to a non-function template; for example, in the +/// following snippet, the return expression of the member function +/// 'foo()' might remain unresolved until instantiation: +/// +/// \code +/// struct P { +/// template using I = T; +/// }; +/// +/// struct Q { +/// template int foo() { +/// return T::template I; +/// } +/// }; +/// \endcode +/// +/// ...which is distinct from modeling function overloads, and therefore we use +/// a different builtin type 'UnresolvedTemplate' to avoid confusion. This is +/// done in Sema::BuildTemplateIdExpr. +/// /// and eventually: /// * the lookup might have included a function template. +/// * the unresolved template gets transformed in an instantiation or gets +/// diagnosed for its direct use. /// /// These never include UnresolvedUsingValueDecls, which are always class /// members and therefore appear only in UnresolvedMemberLookupExprs. @@ -3188,7 +3227,6 @@ class UnresolvedLookupExpr final NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, - bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent); @@ -3208,8 +3246,9 @@ public: static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, - UnresolvedSetIterator Begin, UnresolvedSetIterator End); + const DeclarationNameInfo &NameInfo, bool RequiresADL, + UnresolvedSetIterator Begin, UnresolvedSetIterator End, + bool KnownDependent); // After canonicalization, there may be dependent template arguments in // CanonicalConverted But none of Args is dependent. When any of @@ -3230,9 +3269,6 @@ public: /// argument-dependent lookup. bool requiresADL() const { return UnresolvedLookupExprBits.RequiresADL; } - /// True if this lookup is overloaded. - bool isOverloaded() const { return UnresolvedLookupExprBits.Overloaded; } - /// Gets the 'naming class' (in the sense of C++0x /// [class.access.base]p5) of the lookup. This is the scope /// that was looked in to find these results. @@ -4331,6 +4367,116 @@ public: } }; +class PackIndexingExpr final + : public Expr, + private llvm::TrailingObjects { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + + SourceLocation EllipsisLoc; + + // The location of the closing bracket + SourceLocation RSquareLoc; + + // The pack being indexed, followed by the index + Stmt *SubExprs[2]; + + // The size of the trailing expressions. + unsigned TransformedExpressions : 31; + + LLVM_PREFERRED_TYPE(bool) + unsigned ExpandedToEmptyPack : 1; + + PackIndexingExpr(QualType Type, SourceLocation EllipsisLoc, + SourceLocation RSquareLoc, Expr *PackIdExpr, Expr *IndexExpr, + ArrayRef SubstitutedExprs = {}, + bool ExpandedToEmptyPack = false) + : Expr(PackIndexingExprClass, Type, VK_LValue, OK_Ordinary), + EllipsisLoc(EllipsisLoc), RSquareLoc(RSquareLoc), + SubExprs{PackIdExpr, IndexExpr}, + TransformedExpressions(SubstitutedExprs.size()), + ExpandedToEmptyPack(ExpandedToEmptyPack) { + + auto *Exprs = getTrailingObjects(); + std::uninitialized_copy(SubstitutedExprs.begin(), SubstitutedExprs.end(), + Exprs); + + setDependence(computeDependence(this)); + if (!isInstantiationDependent()) + setValueKind(getSelectedExpr()->getValueKind()); + } + + /// Create an empty expression. + PackIndexingExpr(EmptyShell Empty) : Expr(PackIndexingExprClass, Empty) {} + + unsigned numTrailingObjects(OverloadToken) const { + return TransformedExpressions; + } + +public: + static PackIndexingExpr *Create(ASTContext &Context, + SourceLocation EllipsisLoc, + SourceLocation RSquareLoc, Expr *PackIdExpr, + Expr *IndexExpr, std::optional Index, + ArrayRef SubstitutedExprs = {}, + bool ExpandedToEmptyPack = false); + static PackIndexingExpr *CreateDeserialized(ASTContext &Context, + unsigned NumTransformedExprs); + + /// Determine if the expression was expanded to empty. + bool expandsToEmptyPack() const { return ExpandedToEmptyPack; } + + /// Determine the location of the 'sizeof' keyword. + SourceLocation getEllipsisLoc() const { return EllipsisLoc; } + + /// Determine the location of the parameter pack. + SourceLocation getPackLoc() const { return SubExprs[0]->getBeginLoc(); } + + /// Determine the location of the right parenthesis. + SourceLocation getRSquareLoc() const { return RSquareLoc; } + + SourceLocation getBeginLoc() const LLVM_READONLY { return getPackLoc(); } + SourceLocation getEndLoc() const LLVM_READONLY { return RSquareLoc; } + + Expr *getPackIdExpression() const { return cast(SubExprs[0]); } + + NamedDecl *getPackDecl() const; + + Expr *getIndexExpr() const { return cast(SubExprs[1]); } + + std::optional getSelectedIndex() const { + if (isInstantiationDependent()) + return std::nullopt; + ConstantExpr *CE = cast(getIndexExpr()); + auto Index = CE->getResultAsAPSInt(); + assert(Index.isNonNegative() && "Invalid index"); + return static_cast(Index.getExtValue()); + } + + Expr *getSelectedExpr() const { + std::optional Index = getSelectedIndex(); + assert(Index && "extracting the indexed expression of a dependant pack"); + return getTrailingObjects()[*Index]; + } + + /// Return the trailing expressions, regardless of the expansion. + ArrayRef getExpressions() const { + return {getTrailingObjects(), TransformedExpressions}; + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == PackIndexingExprClass; + } + + // Iterators + child_range children() { return child_range(SubExprs, SubExprs + 2); } + + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + 2); + } +}; + /// Represents a reference to a non-type template parameter /// that has been substituted with a template argument. class SubstNonTypeTemplateParmExpr : public Expr { @@ -4939,6 +5085,9 @@ class CoroutineSuspendExpr : public Expr { OpaqueValueExpr *OpaqueValue = nullptr; public: + // These types correspond to the three C++ 'await_suspend' return variants + enum class SuspendReturnType { SuspendVoid, SuspendBool, SuspendHandle }; + CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Operand, Expr *Common, Expr *Ready, Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) @@ -4998,6 +5147,24 @@ public: return static_cast(SubExprs[SubExpr::Operand]); } + SuspendReturnType getSuspendReturnType() const { + auto *SuspendExpr = getSuspendExpr(); + assert(SuspendExpr); + + auto SuspendType = SuspendExpr->getType(); + + if (SuspendType->isVoidType()) + return SuspendReturnType::SuspendVoid; + if (SuspendType->isBooleanType()) + return SuspendReturnType::SuspendBool; + + // Void pointer is the type of handle.address(), which is returned + // from the await suspend wrapper so that the temporary coroutine handle + // value won't go to the frame by mistake + assert(SuspendType->isVoidPointerType()); + return SuspendReturnType::SuspendHandle; + } + SourceLocation getKeywordLoc() const { return KeywordLoc; } SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; } diff --git a/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h index be5b1f3fdd1..54a0c203f65 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h +++ b/contrib/llvm-project/clang/include/clang/AST/ExprOpenMP.h @@ -17,130 +17,6 @@ #include "clang/AST/Expr.h" namespace clang { -/// OpenMP 5.0 [2.1.5, Array Sections]. -/// To specify an array section in an OpenMP construct, array subscript -/// expressions are extended with the following syntax: -/// \code -/// [ lower-bound : length : stride ] -/// [ lower-bound : length : ] -/// [ lower-bound : length ] -/// [ lower-bound : : stride ] -/// [ lower-bound : : ] -/// [ lower-bound : ] -/// [ : length : stride ] -/// [ : length : ] -/// [ : length ] -/// [ : : stride ] -/// [ : : ] -/// [ : ] -/// \endcode -/// The array section must be a subset of the original array. -/// Array sections are allowed on multidimensional arrays. Base language array -/// subscript expressions can be used to specify length-one dimensions of -/// multidimensional array sections. -/// Each of the lower-bound, length, and stride expressions if specified must be -/// an integral type expressions of the base language. When evaluated -/// they represent a set of integer values as follows: -/// \code -/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... , -/// lower-bound + ((length - 1) * stride) } -/// \endcode -/// The lower-bound and length must evaluate to non-negative integers. -/// The stride must evaluate to a positive integer. -/// When the size of the array dimension is not known, the length must be -/// specified explicitly. -/// When the stride is absent it defaults to 1. -/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉, -/// where size is the size of the array dimension. When the lower-bound is -/// absent it defaults to 0. -class OMPArraySectionExpr : public Expr { - enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR }; - Stmt *SubExprs[END_EXPR]; - SourceLocation ColonLocFirst; - SourceLocation ColonLocSecond; - SourceLocation RBracketLoc; - -public: - OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride, - QualType Type, ExprValueKind VK, ExprObjectKind OK, - SourceLocation ColonLocFirst, - SourceLocation ColonLocSecond, SourceLocation RBracketLoc) - : Expr(OMPArraySectionExprClass, Type, VK, OK), - ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond), - RBracketLoc(RBracketLoc) { - SubExprs[BASE] = Base; - SubExprs[LOWER_BOUND] = LowerBound; - SubExprs[LENGTH] = Length; - SubExprs[STRIDE] = Stride; - setDependence(computeDependence(this)); - } - - /// Create an empty array section expression. - explicit OMPArraySectionExpr(EmptyShell Shell) - : Expr(OMPArraySectionExprClass, Shell) {} - - /// An array section can be written only as Base[LowerBound:Length]. - - /// Get base of the array section. - Expr *getBase() { return cast(SubExprs[BASE]); } - const Expr *getBase() const { return cast(SubExprs[BASE]); } - /// Set base of the array section. - void setBase(Expr *E) { SubExprs[BASE] = E; } - - /// Return original type of the base expression for array section. - static QualType getBaseOriginalType(const Expr *Base); - - /// Get lower bound of array section. - Expr *getLowerBound() { return cast_or_null(SubExprs[LOWER_BOUND]); } - const Expr *getLowerBound() const { - return cast_or_null(SubExprs[LOWER_BOUND]); - } - /// Set lower bound of the array section. - void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; } - - /// Get length of array section. - Expr *getLength() { return cast_or_null(SubExprs[LENGTH]); } - const Expr *getLength() const { return cast_or_null(SubExprs[LENGTH]); } - /// Set length of the array section. - void setLength(Expr *E) { SubExprs[LENGTH] = E; } - - /// Get stride of array section. - Expr *getStride() { return cast_or_null(SubExprs[STRIDE]); } - const Expr *getStride() const { return cast_or_null(SubExprs[STRIDE]); } - /// Set length of the array section. - void setStride(Expr *E) { SubExprs[STRIDE] = E; } - - SourceLocation getBeginLoc() const LLVM_READONLY { - return getBase()->getBeginLoc(); - } - SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } - - SourceLocation getColonLocFirst() const { return ColonLocFirst; } - void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; } - - SourceLocation getColonLocSecond() const { return ColonLocSecond; } - void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; } - - SourceLocation getRBracketLoc() const { return RBracketLoc; } - void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } - - SourceLocation getExprLoc() const LLVM_READONLY { - return getBase()->getExprLoc(); - } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == OMPArraySectionExprClass; - } - - child_range children() { - return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); - } - - const_child_range children() const { - return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); - } -}; - /// An explicit cast in C or a C-style cast in C++, which uses the syntax /// ([s1][s2]...[sn])expr. For example: @c ([3][3])f. class OMPArrayShapingExpr final diff --git a/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h index 8e573965b0a..385c32edbae 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h +++ b/contrib/llvm-project/clang/include/clang/AST/ExternalASTSource.h @@ -99,7 +99,7 @@ public: /// passes back decl sets as VisibleDeclaration objects. /// /// The default implementation of this method is a no-op. - virtual Decl *GetExternalDecl(uint32_t ID); + virtual Decl *GetExternalDecl(GlobalDeclID ID); /// Resolve a selector ID into a selector. /// @@ -138,7 +138,7 @@ public: virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); /// Update an out-of-date identifier. - virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {} + virtual void updateOutOfDateIdentifier(const IdentifierInfo &II) {} /// Find all declarations with the given name in the given context, /// and add them to the context by calling SetExternalVisibleDeclsForName @@ -375,7 +375,7 @@ public: if (isOffset()) { assert(Source && "Cannot deserialize a lazy pointer without an AST source"); - Ptr = reinterpret_cast((Source->*Get)(Ptr >> 1)); + Ptr = reinterpret_cast((Source->*Get)(OffsT(Ptr >> 1))); } return reinterpret_cast(Ptr); } @@ -579,7 +579,7 @@ using LazyDeclStmtPtr = /// A lazy pointer to a declaration. using LazyDeclPtr = - LazyOffsetPtr; + LazyOffsetPtr; /// A lazy pointer to a set of CXXCtorInitializers. using LazyCXXCtorInitializersPtr = diff --git a/contrib/llvm-project/clang/include/clang/AST/FormatString.h b/contrib/llvm-project/clang/include/clang/AST/FormatString.h index 5c4ad9baaef..a074dd23e2a 100644 --- a/contrib/llvm-project/clang/include/clang/AST/FormatString.h +++ b/contrib/llvm-project/clang/include/clang/AST/FormatString.h @@ -171,6 +171,14 @@ public: ZArg, // MS extension + // ISO/IEC TR 18037 (fixed-point) specific specifiers. + kArg, // %k for signed accum types + KArg, // %K for unsigned accum types + rArg, // %r for signed fract types + RArg, // %R for unsigned fract types + FixedPointArgBeg = kArg, + FixedPointArgEnd = RArg, + // Objective-C specific specifiers. ObjCObjArg, // '@' ObjCBeg = ObjCObjArg, @@ -237,6 +245,9 @@ public: bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgEnd; } + bool isFixedPointArg() const { + return kind >= FixedPointArgBeg && kind <= FixedPointArgEnd; + } const char *toString() const; @@ -273,6 +284,8 @@ public: /// The conversion specifier and the argument type are disallowed by the C /// standard, but are in practice harmless. For instance, "%p" and int*. NoMatchPedantic, + /// The conversion specifier and the argument type have different sign. + NoMatchSignedness, /// The conversion specifier and the argument type are compatible, but still /// seems likely to be an error. For instance, "%hd" and _Bool. NoMatchTypeConfusion, diff --git a/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h index 88abba28c99..386693cabb1 100644 --- a/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h +++ b/contrib/llvm-project/clang/include/clang/AST/GlobalDecl.h @@ -145,6 +145,10 @@ public: LHS.MultiVersionIndex == RHS.MultiVersionIndex; } + bool operator!=(const GlobalDecl &Other) const { + return !(*this == Other); + } + void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } explicit operator bool() const { return getAsOpaquePtr(); } diff --git a/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h b/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h index 4def5389137..55bd583e304 100644 --- a/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h +++ b/contrib/llvm-project/clang/include/clang/AST/JSONNodeDumper.h @@ -197,16 +197,19 @@ public: void Visit(const Type *T); void Visit(QualType T); void Visit(const Decl *D); + void Visit(TypeLoc TL); void Visit(const comments::Comment *C, const comments::FullComment *FC); void Visit(const TemplateArgument &TA, SourceRange R = {}, const Decl *From = nullptr, StringRef Label = {}); void Visit(const CXXCtorInitializer *Init); + void Visit(const OpenACCClause *C); void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); void Visit(const concepts::Requirement *R); void Visit(const APValue &Value, QualType Ty); + void Visit(const ConceptReference *); void VisitAliasAttr(const AliasAttr *AA); void VisitCleanupAttr(const CleanupAttr *CA); @@ -307,6 +310,8 @@ public: void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE); void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *ME); void VisitRequiresExpr(const RequiresExpr *RE); + void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node); + void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node); void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE); void VisitObjCMessageExpr(const ObjCMessageExpr *OME); diff --git a/contrib/llvm-project/clang/include/clang/AST/Mangle.h b/contrib/llvm-project/clang/include/clang/AST/Mangle.h index e586b0cec43..d5f6c0f6cc6 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Mangle.h +++ b/contrib/llvm-project/clang/include/clang/AST/Mangle.h @@ -130,15 +130,15 @@ public: // FIXME: consider replacing raw_ostream & with something like SmallString &. void mangleName(GlobalDecl GD, raw_ostream &); virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0; - virtual void mangleThunk(const CXXMethodDecl *MD, - const ThunkInfo &Thunk, - raw_ostream &) = 0; + virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, + bool ElideOverrideInfo, raw_ostream &) = 0; virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, - const ThisAdjustment &ThisAdjustment, - raw_ostream &) = 0; + const ThunkInfo &Thunk, + bool ElideOverrideInfo, raw_ostream &) = 0; virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &) = 0; + virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers = false) = 0; @@ -192,7 +192,6 @@ public: bool IsAux = false) : MangleContext(C, D, MK_Itanium, IsAux) {} - virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; virtual void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset, const CXXRecordDecl *Type, diff --git a/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h index 3b6cf972118..a1d9e30e660 100644 --- a/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h +++ b/contrib/llvm-project/clang/include/clang/AST/NestedNameSpecifier.h @@ -124,7 +124,7 @@ public: /// cannot be resolved. static NestedNameSpecifier *Create(const ASTContext &Context, NestedNameSpecifier *Prefix, - IdentifierInfo *II); + const IdentifierInfo *II); /// Builds a nested name specifier that names a namespace. static NestedNameSpecifier *Create(const ASTContext &Context, @@ -134,7 +134,7 @@ public: /// Builds a nested name specifier that names a namespace alias. static NestedNameSpecifier *Create(const ASTContext &Context, NestedNameSpecifier *Prefix, - NamespaceAliasDecl *Alias); + const NamespaceAliasDecl *Alias); /// Builds a nested name specifier that names a type. static NestedNameSpecifier *Create(const ASTContext &Context, @@ -148,7 +148,7 @@ public: /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent /// type. static NestedNameSpecifier *Create(const ASTContext &Context, - IdentifierInfo *II); + const IdentifierInfo *II); /// Returns the nested name specifier representing the global /// scope. @@ -266,7 +266,7 @@ public: explicit operator bool() const { return Qualifier; } /// Evaluates true when this nested-name-specifier location is - /// empty. + /// non-empty. bool hasQualifier() const { return Qualifier; } /// Retrieve the nested-name-specifier to which this instance diff --git a/contrib/llvm-project/clang/include/clang/AST/OpenACCClause.h b/contrib/llvm-project/clang/include/clang/AST/OpenACCClause.h new file mode 100644 index 00000000000..ea1ffbc7fd0 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/AST/OpenACCClause.h @@ -0,0 +1,917 @@ +//===- OpenACCClause.h - Classes for OpenACC clauses ------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// \file +// This file defines OpenACC AST classes for clauses. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_OPENACCCLAUSE_H +#define LLVM_CLANG_AST_OPENACCCLAUSE_H +#include "clang/AST/ASTContext.h" +#include "clang/AST/StmtIterator.h" +#include "clang/Basic/OpenACCKinds.h" + +#include + +namespace clang { +/// This is the base type for all OpenACC Clauses. +class OpenACCClause { + OpenACCClauseKind Kind; + SourceRange Location; + +protected: + OpenACCClause(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation EndLoc) + : Kind(K), Location(BeginLoc, EndLoc) { + assert(!BeginLoc.isInvalid() && !EndLoc.isInvalid() && + "Begin and end location must be valid for OpenACCClause"); + } + +public: + OpenACCClauseKind getClauseKind() const { return Kind; } + SourceLocation getBeginLoc() const { return Location.getBegin(); } + SourceLocation getEndLoc() const { return Location.getEnd(); } + + static bool classof(const OpenACCClause *) { return false; } + + using child_iterator = StmtIterator; + using const_child_iterator = ConstStmtIterator; + using child_range = llvm::iterator_range; + using const_child_range = llvm::iterator_range; + + child_range children(); + const_child_range children() const { + auto Children = const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + virtual ~OpenACCClause() = default; +}; + +// Represents the 'auto' clause. +class OpenACCAutoClause : public OpenACCClause { +protected: + OpenACCAutoClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Auto, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Auto; + } + + static OpenACCAutoClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Represents the 'independent' clause. +class OpenACCIndependentClause : public OpenACCClause { +protected: + OpenACCIndependentClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Independent, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Independent; + } + + static OpenACCIndependentClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; +// Represents the 'seq' clause. +class OpenACCSeqClause : public OpenACCClause { +protected: + OpenACCSeqClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Seq, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Seq; + } + + static OpenACCSeqClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so +// this provides a basic, do-nothing implementation. We still need to add this +// type to the visitors/etc, as well as get it to take its proper arguments. +class OpenACCGangClause : public OpenACCClause { +protected: + OpenACCGangClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) { + llvm_unreachable("Not yet implemented"); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Gang; + } + + static OpenACCGangClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so +// this provides a basic, do-nothing implementation. We still need to add this +// type to the visitors/etc, as well as get it to take its proper arguments. +class OpenACCVectorClause : public OpenACCClause { +protected: + OpenACCVectorClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Vector, BeginLoc, EndLoc) { + llvm_unreachable("Not yet implemented"); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Gang; + } + + static OpenACCVectorClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Not yet implemented, but the type name is necessary for 'seq' diagnostics, so +// this provides a basic, do-nothing implementation. We still need to add this +// type to the visitors/etc, as well as get it to take its proper arguments. +class OpenACCWorkerClause : public OpenACCClause { +protected: + OpenACCWorkerClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Gang, BeginLoc, EndLoc) { + llvm_unreachable("Not yet implemented"); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Gang; + } + + static OpenACCWorkerClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +/// Represents a clause that has a list of parameters. +class OpenACCClauseWithParams : public OpenACCClause { + /// Location of the '('. + SourceLocation LParenLoc; + +protected: + OpenACCClauseWithParams(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OpenACCClause(K, BeginLoc, EndLoc), LParenLoc(LParenLoc) {} + +public: + static bool classof(const OpenACCClause *C); + + SourceLocation getLParenLoc() const { return LParenLoc; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +using DeviceTypeArgument = std::pair; +/// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or +/// an identifier. The 'asterisk' means 'the rest'. +class OpenACCDeviceTypeClause final + : public OpenACCClauseWithParams, + public llvm::TrailingObjects { + // Data stored in trailing objects as IdentifierInfo* /SourceLocation pairs. A + // nullptr IdentifierInfo* represents an asterisk. + unsigned NumArchs; + OpenACCDeviceTypeClause(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, + ArrayRef Archs, + SourceLocation EndLoc) + : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc), + NumArchs(Archs.size()) { + assert( + (K == OpenACCClauseKind::DeviceType || K == OpenACCClauseKind::DType) && + "Invalid clause kind for device-type"); + + assert(!llvm::any_of(Archs, [](const DeviceTypeArgument &Arg) { + return Arg.second.isInvalid(); + }) && "Invalid SourceLocation for an argument"); + + assert( + (Archs.size() == 1 || !llvm::any_of(Archs, + [](const DeviceTypeArgument &Arg) { + return Arg.first == nullptr; + })) && + "Only a single asterisk version is permitted, and must be the " + "only one"); + + std::uninitialized_copy(Archs.begin(), Archs.end(), + getTrailingObjects()); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::DType || + C->getClauseKind() == OpenACCClauseKind::DeviceType; + } + bool hasAsterisk() const { + return getArchitectures().size() > 0 && + getArchitectures()[0].first == nullptr; + } + + ArrayRef getArchitectures() const { + return ArrayRef( + getTrailingObjects(), NumArchs); + } + + static OpenACCDeviceTypeClause * + Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, ArrayRef Archs, + SourceLocation EndLoc); +}; + +/// A 'default' clause, has the optional 'none' or 'present' argument. +class OpenACCDefaultClause : public OpenACCClauseWithParams { + friend class ASTReaderStmt; + friend class ASTWriterStmt; + + OpenACCDefaultClauseKind DefaultClauseKind; + +protected: + OpenACCDefaultClause(OpenACCDefaultClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OpenACCClauseWithParams(OpenACCClauseKind::Default, BeginLoc, LParenLoc, + EndLoc), + DefaultClauseKind(K) { + assert((DefaultClauseKind == OpenACCDefaultClauseKind::None || + DefaultClauseKind == OpenACCDefaultClauseKind::Present) && + "Invalid Clause Kind"); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Default; + } + OpenACCDefaultClauseKind getDefaultClauseKind() const { + return DefaultClauseKind; + } + + static OpenACCDefaultClause *Create(const ASTContext &C, + OpenACCDefaultClauseKind K, + SourceLocation BeginLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); +}; + +/// Represents one of the handful of classes that has an optional/required +/// 'condition' expression as an argument. +class OpenACCClauseWithCondition : public OpenACCClauseWithParams { + Expr *ConditionExpr = nullptr; + +protected: + OpenACCClauseWithCondition(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, Expr *ConditionExpr, + SourceLocation EndLoc) + : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc), + ConditionExpr(ConditionExpr) {} + +public: + static bool classof(const OpenACCClause *C); + + bool hasConditionExpr() const { return ConditionExpr; } + const Expr *getConditionExpr() const { return ConditionExpr; } + Expr *getConditionExpr() { return ConditionExpr; } + + child_range children() { + if (ConditionExpr) + return child_range(reinterpret_cast(&ConditionExpr), + reinterpret_cast(&ConditionExpr + 1)); + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + if (ConditionExpr) + return const_child_range( + reinterpret_cast(&ConditionExpr), + reinterpret_cast(&ConditionExpr + 1)); + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +/// An 'if' clause, which has a required condition expression. +class OpenACCIfClause : public OpenACCClauseWithCondition { +protected: + OpenACCIfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + Expr *ConditionExpr, SourceLocation EndLoc); + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::If; + } + static OpenACCIfClause *Create(const ASTContext &C, SourceLocation BeginLoc, + SourceLocation LParenLoc, Expr *ConditionExpr, + SourceLocation EndLoc); +}; + +/// A 'self' clause, which has an optional condition expression. +class OpenACCSelfClause : public OpenACCClauseWithCondition { + OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + Expr *ConditionExpr, SourceLocation EndLoc); + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Self; + } + static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc, + SourceLocation LParenLoc, + Expr *ConditionExpr, SourceLocation EndLoc); +}; + +/// Represents a clause that has one or more expressions associated with it. +class OpenACCClauseWithExprs : public OpenACCClauseWithParams { + MutableArrayRef Exprs; + +protected: + OpenACCClauseWithExprs(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OpenACCClauseWithParams(K, BeginLoc, LParenLoc, EndLoc) {} + + /// Used only for initialization, the leaf class can initialize this to + /// trailing storage. + void setExprs(MutableArrayRef NewExprs) { + assert(Exprs.empty() && "Cannot change Exprs list"); + Exprs = NewExprs; + } + + /// Gets the entire list of expressions, but leave it to the + /// individual clauses to expose this how they'd like. + llvm::ArrayRef getExprs() const { return Exprs; } + +public: + static bool classof(const OpenACCClause *C); + child_range children() { + return child_range(reinterpret_cast(Exprs.begin()), + reinterpret_cast(Exprs.end())); + } + + const_child_range children() const { + child_range Children = + const_cast(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } +}; + +// Represents the 'devnum' and expressions lists for the 'wait' clause. +class OpenACCWaitClause final + : public OpenACCClauseWithExprs, + public llvm::TrailingObjects { + SourceLocation QueuesLoc; + OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + Expr *DevNumExpr, SourceLocation QueuesLoc, + ArrayRef QueueIdExprs, SourceLocation EndLoc) + : OpenACCClauseWithExprs(OpenACCClauseKind::Wait, BeginLoc, LParenLoc, + EndLoc), + QueuesLoc(QueuesLoc) { + // The first element of the trailing storage is always the devnum expr, + // whether it is used or not. + std::uninitialized_copy(&DevNumExpr, &DevNumExpr + 1, + getTrailingObjects()); + std::uninitialized_copy(QueueIdExprs.begin(), QueueIdExprs.end(), + getTrailingObjects() + 1); + setExprs( + MutableArrayRef(getTrailingObjects(), QueueIdExprs.size() + 1)); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Wait; + } + static OpenACCWaitClause *Create(const ASTContext &C, SourceLocation BeginLoc, + SourceLocation LParenLoc, Expr *DevNumExpr, + SourceLocation QueuesLoc, + ArrayRef QueueIdExprs, + SourceLocation EndLoc); + + bool hasQueuesTag() const { return !QueuesLoc.isInvalid(); } + SourceLocation getQueuesLoc() const { return QueuesLoc; } + bool hasDevNumExpr() const { return getExprs()[0]; } + Expr *getDevNumExpr() const { return getExprs()[0]; } + llvm::ArrayRef getQueueIdExprs() { + return OpenACCClauseWithExprs::getExprs().drop_front(); + } + llvm::ArrayRef getQueueIdExprs() const { + return OpenACCClauseWithExprs::getExprs().drop_front(); + } +}; + +class OpenACCNumGangsClause final + : public OpenACCClauseWithExprs, + public llvm::TrailingObjects { + + OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef IntExprs, SourceLocation EndLoc) + : OpenACCClauseWithExprs(OpenACCClauseKind::NumGangs, BeginLoc, LParenLoc, + EndLoc) { + std::uninitialized_copy(IntExprs.begin(), IntExprs.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), IntExprs.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::NumGangs; + } + static OpenACCNumGangsClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef IntExprs, SourceLocation EndLoc); + + llvm::ArrayRef getIntExprs() { + return OpenACCClauseWithExprs::getExprs(); + } + + llvm::ArrayRef getIntExprs() const { + return OpenACCClauseWithExprs::getExprs(); + } +}; + +/// Represents one of a handful of clauses that have a single integer +/// expression. +class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs { + Expr *IntExpr; + +protected: + OpenACCClauseWithSingleIntExpr(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, Expr *IntExpr, + SourceLocation EndLoc) + : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc), + IntExpr(IntExpr) { + if (IntExpr) + setExprs(MutableArrayRef{&this->IntExpr, 1}); + } + +public: + static bool classof(const OpenACCClause *C); + bool hasIntExpr() const { return !getExprs().empty(); } + const Expr *getIntExpr() const { + return hasIntExpr() ? getExprs()[0] : nullptr; + } + + Expr *getIntExpr() { return hasIntExpr() ? getExprs()[0] : nullptr; }; +}; + +class OpenACCNumWorkersClause : public OpenACCClauseWithSingleIntExpr { + OpenACCNumWorkersClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + Expr *IntExpr, SourceLocation EndLoc); + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::NumWorkers; + } + static OpenACCNumWorkersClause *Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation LParenLoc, + Expr *IntExpr, SourceLocation EndLoc); +}; + +class OpenACCVectorLengthClause : public OpenACCClauseWithSingleIntExpr { + OpenACCVectorLengthClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + Expr *IntExpr, SourceLocation EndLoc); + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::VectorLength; + } + static OpenACCVectorLengthClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + Expr *IntExpr, SourceLocation EndLoc); +}; + +class OpenACCAsyncClause : public OpenACCClauseWithSingleIntExpr { + OpenACCAsyncClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + Expr *IntExpr, SourceLocation EndLoc); + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Async; + } + static OpenACCAsyncClause *Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation LParenLoc, Expr *IntExpr, + SourceLocation EndLoc); +}; + +/// Represents a clause with one or more 'var' objects, represented as an expr, +/// as its arguments. Var-list is expected to be stored in trailing storage. +/// For now, we're just storing the original expression in its entirety, unlike +/// OMP which has to do a bunch of work to create a private. +class OpenACCClauseWithVarList : public OpenACCClauseWithExprs { +protected: + OpenACCClauseWithVarList(OpenACCClauseKind K, SourceLocation BeginLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OpenACCClauseWithExprs(K, BeginLoc, LParenLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C); + ArrayRef getVarList() { return getExprs(); } + ArrayRef getVarList() const { return getExprs(); } +}; + +class OpenACCPrivateClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + + OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::Private, BeginLoc, + LParenLoc, EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Private; + } + static OpenACCPrivateClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCFirstPrivateClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + + OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::FirstPrivate, BeginLoc, + LParenLoc, EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::FirstPrivate; + } + static OpenACCFirstPrivateClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCDevicePtrClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + + OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::DevicePtr, BeginLoc, + LParenLoc, EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::DevicePtr; + } + static OpenACCDevicePtrClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCAttachClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + + OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::Attach, BeginLoc, LParenLoc, + EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Attach; + } + static OpenACCAttachClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCNoCreateClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + + OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::NoCreate, BeginLoc, + LParenLoc, EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::NoCreate; + } + static OpenACCNoCreateClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCPresentClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + + OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::Present, BeginLoc, + LParenLoc, EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Present; + } + static OpenACCPresentClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCCopyClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + + OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, + SourceLocation LParenLoc, ArrayRef VarList, + SourceLocation EndLoc) + : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc) { + assert((Spelling == OpenACCClauseKind::Copy || + Spelling == OpenACCClauseKind::PCopy || + Spelling == OpenACCClauseKind::PresentOrCopy) && + "Invalid clause kind for copy-clause"); + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Copy || + C->getClauseKind() == OpenACCClauseKind::PCopy || + C->getClauseKind() == OpenACCClauseKind::PresentOrCopy; + } + static OpenACCCopyClause * + Create(const ASTContext &C, OpenACCClauseKind Spelling, + SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCCopyInClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + bool IsReadOnly; + + OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, + SourceLocation LParenLoc, bool IsReadOnly, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), + IsReadOnly(IsReadOnly) { + assert((Spelling == OpenACCClauseKind::CopyIn || + Spelling == OpenACCClauseKind::PCopyIn || + Spelling == OpenACCClauseKind::PresentOrCopyIn) && + "Invalid clause kind for copyin-clause"); + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::CopyIn || + C->getClauseKind() == OpenACCClauseKind::PCopyIn || + C->getClauseKind() == OpenACCClauseKind::PresentOrCopyIn; + } + bool isReadOnly() const { return IsReadOnly; } + static OpenACCCopyInClause * + Create(const ASTContext &C, OpenACCClauseKind Spelling, + SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCCopyOutClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + bool IsZero; + + OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, + SourceLocation LParenLoc, bool IsZero, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), + IsZero(IsZero) { + assert((Spelling == OpenACCClauseKind::CopyOut || + Spelling == OpenACCClauseKind::PCopyOut || + Spelling == OpenACCClauseKind::PresentOrCopyOut) && + "Invalid clause kind for copyout-clause"); + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::CopyOut || + C->getClauseKind() == OpenACCClauseKind::PCopyOut || + C->getClauseKind() == OpenACCClauseKind::PresentOrCopyOut; + } + bool isZero() const { return IsZero; } + static OpenACCCopyOutClause * + Create(const ASTContext &C, OpenACCClauseKind Spelling, + SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCCreateClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + bool IsZero; + + OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, + SourceLocation LParenLoc, bool IsZero, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(Spelling, BeginLoc, LParenLoc, EndLoc), + IsZero(IsZero) { + assert((Spelling == OpenACCClauseKind::Create || + Spelling == OpenACCClauseKind::PCreate || + Spelling == OpenACCClauseKind::PresentOrCreate) && + "Invalid clause kind for create-clause"); + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Create || + C->getClauseKind() == OpenACCClauseKind::PCreate || + C->getClauseKind() == OpenACCClauseKind::PresentOrCreate; + } + bool isZero() const { return IsZero; } + static OpenACCCreateClause * + Create(const ASTContext &C, OpenACCClauseKind Spelling, + SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCReductionClause final + : public OpenACCClauseWithVarList, + public llvm::TrailingObjects { + OpenACCReductionOperator Op; + + OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + OpenACCReductionOperator Operator, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::Reduction, BeginLoc, + LParenLoc, EndLoc), + Op(Operator) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Reduction; + } + + static OpenACCReductionClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + OpenACCReductionOperator Operator, ArrayRef VarList, + SourceLocation EndLoc); + + OpenACCReductionOperator getReductionOp() const { return Op; } +}; + +template class OpenACCClauseVisitor { + Impl &getDerived() { return static_cast(*this); } + +public: + void VisitClauseList(ArrayRef List) { + for (const OpenACCClause *Clause : List) + Visit(Clause); + } + + void Visit(const OpenACCClause *C) { + if (!C) + return; + + switch (C->getClauseKind()) { +#define VISIT_CLAUSE(CLAUSE_NAME) \ + case OpenACCClauseKind::CLAUSE_NAME: \ + Visit##CLAUSE_NAME##Clause(*cast(C)); \ + return; +#define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \ + case OpenACCClauseKind::ALIAS_NAME: \ + Visit##CLAUSE_NAME##Clause(*cast(C)); \ + return; +#include "clang/Basic/OpenACCClauses.def" + + default: + llvm_unreachable("Clause visitor not yet implemented"); + } + llvm_unreachable("Invalid Clause kind"); + } + +#define VISIT_CLAUSE(CLAUSE_NAME) \ + void Visit##CLAUSE_NAME##Clause( \ + const OpenACC##CLAUSE_NAME##Clause &Clause) { \ + return getDerived().Visit##CLAUSE_NAME##Clause(Clause); \ + } + +#include "clang/Basic/OpenACCClauses.def" +}; + +class OpenACCClausePrinter final + : public OpenACCClauseVisitor { + raw_ostream &OS; + const PrintingPolicy &Policy; + + void printExpr(const Expr *E); + +public: + void VisitClauseList(ArrayRef List) { + for (const OpenACCClause *Clause : List) { + Visit(Clause); + + if (Clause != List.back()) + OS << ' '; + } + } + OpenACCClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) + : OS(OS), Policy(Policy) {} + +#define VISIT_CLAUSE(CLAUSE_NAME) \ + void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause); +#include "clang/Basic/OpenACCClauses.def" +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_OPENACCCLAUSE_H diff --git a/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h b/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h index 924ca189381..325a1baa446 100644 --- a/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h +++ b/contrib/llvm-project/clang/include/clang/AST/OpenMPClause.h @@ -2513,6 +2513,46 @@ public: } }; +/// This represents 'weak' clause in the '#pragma omp atomic' +/// directives. +/// +/// \code +/// #pragma omp atomic compare weak +/// \endcode +/// In this example directive '#pragma omp atomic' has 'weak' clause. +class OMPWeakClause final : public OMPClause { +public: + /// Build 'weak' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPWeakClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_weak, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPWeakClause() + : OMPClause(llvm::omp::OMPC_weak, SourceLocation(), SourceLocation()) {} + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_weak; + } +}; + /// This represents 'fail' clause in the '#pragma omp atomic' /// directive. /// diff --git a/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def b/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def index 8dd98730dff..8788b8ff0ef 100644 --- a/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def +++ b/contrib/llvm-project/clang/include/clang/AST/OperationKinds.def @@ -361,6 +361,12 @@ CAST_OPERATION(AddressSpaceConversion) // Convert an integer initializer to an OpenCL sampler. CAST_OPERATION(IntToOCLSampler) +// Truncate a vector type by dropping elements from the end (HLSL only). +CAST_OPERATION(HLSLVectorTruncation) + +// Non-decaying array RValue cast (HLSL only). +CAST_OPERATION(HLSLArrayRValue) + //===- Binary Operations -------------------------------------------------===// // Operators listed in order of precedence. // Note that additions to this should also update the StmtVisitor class, diff --git a/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h b/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h index d3b2e3986a9..6f79038627d 100644 --- a/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h +++ b/contrib/llvm-project/clang/include/clang/AST/ParentMapContext.h @@ -1,4 +1,4 @@ -//===- ParentMapContext.h - Map of parents using DynTypedNode -------*- C++ -*-===// +//===- ParentMapContext.h - Map of parents using DynTypedNode ---*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h index da276e26049..332ac3c6a00 100644 --- a/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h +++ b/contrib/llvm-project/clang/include/clang/AST/PrettyPrinter.h @@ -77,7 +77,7 @@ struct PrintingPolicy { PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true), UsePreferredNames(true), AlwaysIncludeTypeForTemplateArgument(false), CleanUglifiedParameters(false), EntireContentsOfLargeArray(true), - UseEnumerators(true) {} + UseEnumerators(true), UseHLSLTypes(LO.HLSL) {} /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -342,6 +342,11 @@ struct PrintingPolicy { LLVM_PREFERRED_TYPE(bool) unsigned UseEnumerators : 1; + /// Whether or not we're printing known HLSL code and should print HLSL + /// sugared types when possible. + LLVM_PREFERRED_TYPE(bool) + unsigned UseHLSLTypes : 1; + /// Callbacks to use to allow the behavior of printing to be customized. const PrintingCallbacks *Callbacks = nullptr; }; diff --git a/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td b/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td index 0270c086d06..5f7d6195187 100644 --- a/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td +++ b/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td @@ -117,6 +117,8 @@ def ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">; def FixedPointSemantics : PropertyType<"llvm::FixedPointSemantics"> { let PassByReference = 1; } +def FunctionEffect : PropertyType<"FunctionEffect">; +def EffectConditionExpr : PropertyType<"EffectConditionExpr">; def Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; } def LValuePathEntry : PropertyType<"APValue::LValuePathEntry">; def LValuePathSerializationHelper : @@ -143,6 +145,7 @@ def UInt32 : CountPropertyType<"uint32_t">; def UInt64 : CountPropertyType<"uint64_t">; def UnaryTypeTransformKind : EnumPropertyType<"UnaryTransformType::UTTKind">; def VectorKind : EnumPropertyType<"VectorKind">; +def TypeCoupledDeclRefInfo : PropertyType; def ExceptionSpecInfo : PropertyType<"FunctionProtoType::ExceptionSpecInfo"> { let BufferElementTypes = [ QualType ]; diff --git a/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h b/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h index 53aae24fa7b..3e4567b546a 100644 --- a/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h +++ b/contrib/llvm-project/clang/include/clang/AST/RawCommentList.h @@ -175,17 +175,22 @@ private: mutable StringRef RawText; mutable const char *BriefText = nullptr; - mutable bool RawTextValid : 1; ///< True if RawText is valid - mutable bool BriefTextValid : 1; ///< True if BriefText is valid + LLVM_PREFERRED_TYPE(bool) + mutable unsigned RawTextValid : 1; + LLVM_PREFERRED_TYPE(bool) + mutable unsigned BriefTextValid : 1; LLVM_PREFERRED_TYPE(CommentKind) unsigned Kind : 3; /// True if comment is attached to a declaration in ASTContext. - bool IsAttached : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IsAttached : 1; - bool IsTrailingComment : 1; - bool IsAlmostTrailingComment : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IsTrailingComment : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned IsAlmostTrailingComment : 1; /// Constructor for AST deserialization. RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, diff --git a/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h index 2aee6a94714..e3c0cb46799 100644 --- a/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h @@ -30,10 +30,12 @@ #include "clang/AST/ExprOpenMP.h" #include "clang/AST/LambdaCapture.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OpenACCClause.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenACC.h" #include "clang/AST/StmtOpenMP.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" @@ -505,6 +507,11 @@ private: bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node); bool PostVisitStmt(Stmt *S); + bool TraverseOpenACCConstructStmt(OpenACCConstructStmt *S); + bool + TraverseOpenACCAssociatedStmtConstruct(OpenACCAssociatedStmtConstruct *S); + bool VisitOpenACCClauseList(ArrayRef); + bool VisitOpenACCClause(const OpenACCClause *); }; template @@ -731,13 +738,27 @@ bool RecursiveASTVisitor::TraverseDecl(Decl *D) { // As a syntax visitor, by default we want to ignore declarations for // implicit declarations (ones not typed explicitly by the user). - if (!getDerived().shouldVisitImplicitCode() && D->isImplicit()) { - // For an implicit template type parameter, its type constraints are not - // implicit and are not represented anywhere else. We still need to visit - // them. - if (auto *TTPD = dyn_cast(D)) - return TraverseTemplateTypeParamDeclConstraints(TTPD); - return true; + if (!getDerived().shouldVisitImplicitCode()) { + if (D->isImplicit()) { + // For an implicit template type parameter, its type constraints are not + // implicit and are not represented anywhere else. We still need to visit + // them. + if (auto *TTPD = dyn_cast(D)) + return TraverseTemplateTypeParamDeclConstraints(TTPD); + return true; + } + + // Deduction guides for alias templates are always synthesized, so they + // should not be traversed unless shouldVisitImplicitCode() returns true. + // + // It's important to note that checking the implicit bit is not efficient + // for the alias case. For deduction guides synthesized from explicit + // user-defined deduction guides, we must maintain the explicit bit to + // ensure correct overload resolution. + if (auto *FTD = dyn_cast(D)) + if (llvm::isa_and_present( + FTD->getDeclName().getCXXDeductionGuideTemplate())) + return true; } switch (D->getKind()) { @@ -834,10 +855,14 @@ bool RecursiveASTVisitor::TraverseDeclarationNameInfo( template bool RecursiveASTVisitor::TraverseTemplateName(TemplateName Template) { - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) + if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier())); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); + } else if (QualifiedTemplateName *QTN = + Template.getAsQualifiedTemplateName()) { + if (QTN->getQualifier()) { + TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); + } + } return true; } @@ -989,6 +1014,12 @@ DEF_TRAVERSE_TYPE(ConstantArrayType, { TRY_TO(TraverseStmt(const_cast(T->getSizeExpr()))); }) +DEF_TRAVERSE_TYPE(ArrayParameterType, { + TRY_TO(TraverseType(T->getElementType())); + if (T->getSizeExpr()) + TRY_TO(TraverseStmt(const_cast(T->getSizeExpr()))); +}) + DEF_TRAVERSE_TYPE(IncompleteArrayType, { TRY_TO(TraverseType(T->getElementType())); }) @@ -1065,6 +1096,11 @@ DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); }) DEF_TRAVERSE_TYPE(DecltypeType, { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPE(PackIndexingType, { + TRY_TO(TraverseType(T->getPattern())); + TRY_TO(TraverseStmt(T->getIndexExpr())); +}) + DEF_TRAVERSE_TYPE(UnaryTransformType, { TRY_TO(TraverseType(T->getBaseType())); TRY_TO(TraverseType(T->getUnderlyingType())); @@ -1101,6 +1137,12 @@ DEF_TRAVERSE_TYPE(InjectedClassNameType, {}) DEF_TRAVERSE_TYPE(AttributedType, { TRY_TO(TraverseType(T->getModifiedType())); }) +DEF_TRAVERSE_TYPE(CountAttributedType, { + if (T->getCountExpr()) + TRY_TO(TraverseStmt(T->getCountExpr())); + TRY_TO(TraverseType(T->desugar())); +}) + DEF_TRAVERSE_TYPE(BTFTagAttributedType, { TRY_TO(TraverseType(T->getWrappedType())); }) @@ -1245,6 +1287,11 @@ DEF_TRAVERSE_TYPELOC(ConstantArrayType, { TRY_TO(TraverseArrayTypeLocHelper(TL)); }) +DEF_TRAVERSE_TYPELOC(ArrayParameterType, { + TRY_TO(TraverseTypeLoc(TL.getElementLoc())); + TRY_TO(TraverseArrayTypeLocHelper(TL)); +}) + DEF_TRAVERSE_TYPELOC(IncompleteArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); TRY_TO(TraverseArrayTypeLocHelper(TL)); @@ -1343,6 +1390,11 @@ DEF_TRAVERSE_TYPELOC(DecltypeType, { TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPELOC(PackIndexingType, { + TRY_TO(TraverseType(TL.getPattern())); + TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr())); +}) + DEF_TRAVERSE_TYPELOC(UnaryTransformType, { TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); }) @@ -1387,6 +1439,9 @@ DEF_TRAVERSE_TYPELOC(MacroQualifiedType, DEF_TRAVERSE_TYPELOC(AttributedType, { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) +DEF_TRAVERSE_TYPELOC(CountAttributedType, + { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) + DEF_TRAVERSE_TYPELOC(BTFTagAttributedType, { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); }) @@ -1911,7 +1966,7 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); TRY_TO(TraverseTemplateTypeParamDeclConstraints(D)); if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc())); + TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); }) DEF_TRAVERSE_DECL(TypedefDecl, { @@ -1995,6 +2050,15 @@ DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); }) DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); }) +template +bool RecursiveASTVisitor::TraverseTemplateArgumentLocsHelper( + const TemplateArgumentLoc *TAL, unsigned Count) { + for (unsigned I = 0; I < Count; ++I) { + TRY_TO(TraverseTemplateArgumentLoc(TAL[I])); + } + return true; +} + #define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \ /* For implicit instantiations ("set x;"), we don't want to \ @@ -2004,9 +2068,12 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); }) TemplateSpecializationType). For explicit instantiations \ ("template set;"), we do need a callback, since this \ is the only callback that's made for this instantiation. \ - We use getTypeAsWritten() to distinguish. */ \ - if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \ - TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \ + We use getTemplateArgsAsWritten() to distinguish. */ \ + if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \ + /* The args that remains unspecialized. */ \ + TRY_TO(TraverseTemplateArgumentLocsHelper( \ + ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \ + } \ \ if (getDerived().shouldVisitTemplateInstantiations() || \ D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \ @@ -2026,15 +2093,6 @@ DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); }) DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord) DEF_TRAVERSE_TMPL_SPEC_DECL(Var, Var) -template -bool RecursiveASTVisitor::TraverseTemplateArgumentLocsHelper( - const TemplateArgumentLoc *TAL, unsigned Count) { - for (unsigned I = 0; I < Count; ++I) { - TRY_TO(TraverseTemplateArgumentLoc(TAL[I])); - } - return true; -} - #define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \ DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \ /* The partial specialization. */ \ @@ -2268,7 +2326,7 @@ DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, { // A non-type template parameter, e.g. "S" in template class Foo ... TRY_TO(TraverseDeclaratorHelper(D)); if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) - TRY_TO(TraverseStmt(D->getDefaultArgument())); + TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); }) DEF_TRAVERSE_DECL(ParmVarDecl, { @@ -2705,7 +2763,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {}) -DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) +DEF_TRAVERSE_STMT(ArraySectionExpr, {}) DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) @@ -2806,6 +2864,11 @@ DEF_TRAVERSE_STMT(ShuffleVectorExpr, {}) DEF_TRAVERSE_STMT(ConvertVectorExpr, {}) DEF_TRAVERSE_STMT(StmtExpr, {}) DEF_TRAVERSE_STMT(SourceLocExpr, {}) +DEF_TRAVERSE_STMT(EmbedExpr, { + for (IntegerLiteral *IL : S->underlying_data_elements()) { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(IL); + } +}) DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); @@ -2854,6 +2917,7 @@ DEF_TRAVERSE_STMT(CompoundAssignOperator, {}) DEF_TRAVERSE_STMT(CXXNoexceptExpr, {}) DEF_TRAVERSE_STMT(PackExpansionExpr, {}) DEF_TRAVERSE_STMT(SizeOfPackExpr, {}) +DEF_TRAVERSE_STMT(PackIndexingExpr, {}) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {}) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {}) DEF_TRAVERSE_STMT(FunctionParmPackExpr, {}) @@ -2968,6 +3032,12 @@ DEF_TRAVERSE_STMT(OMPTileDirective, DEF_TRAVERSE_STMT(OMPUnrollDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPReverseDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPInterchangeDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPForDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) @@ -3425,6 +3495,11 @@ bool RecursiveASTVisitor::VisitOMPRelaxedClause(OMPRelaxedClause *) { return true; } +template +bool RecursiveASTVisitor::VisitOMPWeakClause(OMPWeakClause *) { + return true; +} + template bool RecursiveASTVisitor::VisitOMPThreadsClause(OMPThreadsClause *) { return true; @@ -3894,6 +3969,51 @@ bool RecursiveASTVisitor::VisitOMPXBareClause(OMPXBareClause *C) { return true; } +template +bool RecursiveASTVisitor::TraverseOpenACCConstructStmt( + OpenACCConstructStmt *C) { + TRY_TO(VisitOpenACCClauseList(C->clauses())); + return true; +} + +template +bool RecursiveASTVisitor::TraverseOpenACCAssociatedStmtConstruct( + OpenACCAssociatedStmtConstruct *S) { + TRY_TO(TraverseOpenACCConstructStmt(S)); + TRY_TO(TraverseStmt(S->getAssociatedStmt())); + return true; +} + +template +bool RecursiveASTVisitor::VisitOpenACCClause(const OpenACCClause *C) { + for (const Stmt *Child : C->children()) + TRY_TO(TraverseStmt(const_cast(Child))); + return true; +} + +template +bool RecursiveASTVisitor::VisitOpenACCClauseList( + ArrayRef Clauses) { + + for (const auto *C : Clauses) + TRY_TO(VisitOpenACCClause(C)); +// if (const auto *WithCond = dyn_cast(C); +// WithCond && WIthCond->hasConditionExpr()) { +// TRY_TO(TraverseStmt(WithCond->getConditionExpr()); +// } else if (const auto * +// } +// OpenACCClauseWithCondition::getConditionExpr/hasConditionExpr +//OpenACCClauseWithExprs::children (might be null?) + // TODO OpenACC: When we have Clauses with expressions, we should visit them + // here. + return true; +} + +DEF_TRAVERSE_STMT(OpenACCComputeConstruct, + { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) +DEF_TRAVERSE_STMT(OpenACCLoopConstruct, + { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) + // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods // returning decls or qualtypes or nestednamespecifier -- though I'm diff --git a/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h b/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h index 091bb886f2d..74ccd74ed60 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h +++ b/contrib/llvm-project/clang/include/clang/AST/Redeclarable.h @@ -281,10 +281,10 @@ public: return tmp; } - friend bool operator==(redecl_iterator x, redecl_iterator y) { + friend bool operator==(const redecl_iterator &x, const redecl_iterator &y) { return x.Current == y.Current; } - friend bool operator!=(redecl_iterator x, redecl_iterator y) { + friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y) { return x.Current != y.Current; } }; diff --git a/contrib/llvm-project/clang/include/clang/AST/Stmt.h b/contrib/llvm-project/clang/include/clang/AST/Stmt.h index 55eca4007d1..bbd7634bcc3 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm-project/clang/include/clang/AST/Stmt.h @@ -460,10 +460,10 @@ protected: unsigned : NumExprBits; static_assert( - llvm::APFloat::S_MaxSemantics < 16, - "Too many Semantics enum values to fit in bitfield of size 4"); + llvm::APFloat::S_MaxSemantics < 32, + "Too many Semantics enum values to fit in bitfield of size 5"); LLVM_PREFERRED_TYPE(llvm::APFloat::Semantics) - unsigned Semantics : 4; // Provides semantics for APFloat construction + unsigned Semantics : 5; // Provides semantics for APFloat construction LLVM_PREFERRED_TYPE(bool) unsigned IsExact : 1; }; @@ -583,11 +583,13 @@ protected: unsigned IsArrow : 1; /// True if this member expression used a nested-name-specifier to - /// refer to the member, e.g., "x->Base::f", or found its member via - /// a using declaration. When true, a MemberExprNameQualifier - /// structure is allocated immediately after the MemberExpr. + /// refer to the member, e.g., "x->Base::f". LLVM_PREFERRED_TYPE(bool) - unsigned HasQualifierOrFoundDecl : 1; + unsigned HasQualifier : 1; + + // True if this member expression found its member via a using declaration. + LLVM_PREFERRED_TYPE(bool) + unsigned HasFoundDecl : 1; /// True if this member expression specified a template keyword /// and/or a template argument list explicitly, e.g., x->f, @@ -782,6 +784,11 @@ protected: LLVM_PREFERRED_TYPE(bool) unsigned IsImplicit : 1; + /// Whether there is a lambda with an explicit object parameter that + /// captures this "this" by copy. + LLVM_PREFERRED_TYPE(bool) + unsigned CapturedByCopyInLambdaWithExplicitObjectParameter : 1; + /// The location of the "this". SourceLocation Loc; }; @@ -1060,11 +1067,6 @@ protected: /// argument-dependent lookup if this is the operand of a function call. LLVM_PREFERRED_TYPE(bool) unsigned RequiresADL : 1; - - /// True if these lookup results are overloaded. This is pretty trivially - /// rederivable if we urgently need to kill this field. - LLVM_PREFERRED_TYPE(bool) - unsigned Overloaded : 1; }; static_assert(sizeof(UnresolvedLookupExprBitfields) <= 4, "UnresolvedLookupExprBitfields must be <= than 4 bytes to" @@ -1656,6 +1658,11 @@ public: return *getTrailingObjects(); } + /// Get the store FPOptionsOverride or default if not stored. + FPOptionsOverride getStoredFPFeaturesOrDefault() const { + return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride(); + } + using body_iterator = Stmt **; using body_range = llvm::iterator_range; diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h b/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h index c46ff4634c8..03bc61f54cd 100644 --- a/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h +++ b/contrib/llvm-project/clang/include/clang/AST/StmtObjC.h @@ -177,7 +177,8 @@ class ObjCAtTryStmt final unsigned NumCatchStmts : 16; // Whether this statement has a \@finally statement. - bool HasFinally : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned HasFinally : 1; /// Retrieve the statements that are stored after this \@try statement. /// diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtOpenACC.h b/contrib/llvm-project/clang/include/clang/AST/StmtOpenACC.h new file mode 100644 index 00000000000..b3aea09be03 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/AST/StmtOpenACC.h @@ -0,0 +1,256 @@ +//===- StmtOpenACC.h - Classes for OpenACC directives ----------*- 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 +// +//===----------------------------------------------------------------------===// +/// \file +/// This file defines OpenACC AST classes for statement-level contructs. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_STMTOPENACC_H +#define LLVM_CLANG_AST_STMTOPENACC_H + +#include "clang/AST/OpenACCClause.h" +#include "clang/AST/Stmt.h" +#include "clang/Basic/OpenACCKinds.h" +#include "clang/Basic/SourceLocation.h" +#include + +namespace clang { +/// This is the base class for an OpenACC statement-level construct, other +/// construct types are expected to inherit from this. +class OpenACCConstructStmt : public Stmt { + friend class ASTStmtWriter; + friend class ASTStmtReader; + /// The directive kind. Each implementation of this interface should handle + /// specific kinds. + OpenACCDirectiveKind Kind = OpenACCDirectiveKind::Invalid; + /// The location of the directive statement, from the '#' to the last token of + /// the directive. + SourceRange Range; + /// The location of the directive name. + SourceLocation DirectiveLoc; + + /// The list of clauses. This is stored here as an ArrayRef, as this is the + /// most convienient place to access the list, however the list itself should + /// be stored in leaf nodes, likely in trailing-storage. + MutableArrayRef Clauses; + +protected: + OpenACCConstructStmt(StmtClass SC, OpenACCDirectiveKind K, + SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End) + : Stmt(SC), Kind(K), Range(Start, End), DirectiveLoc(DirectiveLoc) {} + + // Used only for initialization, the leaf class can initialize this to + // trailing storage. + void setClauseList(MutableArrayRef NewClauses) { + assert(Clauses.empty() && "Cannot change clause list"); + Clauses = NewClauses; + } + +public: + OpenACCDirectiveKind getDirectiveKind() const { return Kind; } + + static bool classof(const Stmt *S) { + return S->getStmtClass() >= firstOpenACCConstructStmtConstant && + S->getStmtClass() <= lastOpenACCConstructStmtConstant; + } + + SourceLocation getBeginLoc() const { return Range.getBegin(); } + SourceLocation getEndLoc() const { return Range.getEnd(); } + SourceLocation getDirectiveLoc() const { return DirectiveLoc; } + ArrayRef clauses() const { return Clauses; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_cast(this)->children(); + } +}; + +/// This is a base class for any OpenACC statement-level constructs that have an +/// associated statement. This class is not intended to be instantiated, but is +/// a convenient place to hold the associated statement. +class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt { + friend class ASTStmtWriter; + friend class ASTStmtReader; + template friend class RecursiveASTVisitor; + Stmt *AssociatedStmt = nullptr; + +protected: + OpenACCAssociatedStmtConstruct(StmtClass SC, OpenACCDirectiveKind K, + SourceLocation Start, + SourceLocation DirectiveLoc, + SourceLocation End, Stmt *AssocStmt) + : OpenACCConstructStmt(SC, K, Start, DirectiveLoc, End), + AssociatedStmt(AssocStmt) {} + + void setAssociatedStmt(Stmt *S) { AssociatedStmt = S; } + Stmt *getAssociatedStmt() { return AssociatedStmt; } + const Stmt *getAssociatedStmt() const { + return const_cast(this) + ->getAssociatedStmt(); + } + +public: + static bool classof(const Stmt *T) { + return false; + } + + child_range children() { + if (getAssociatedStmt()) + return child_range(&AssociatedStmt, &AssociatedStmt + 1); + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_cast(this)->children(); + } +}; + +class OpenACCLoopConstruct; +/// This class represents a compute construct, representing a 'Kind' of +/// `parallel', 'serial', or 'kernel'. These constructs are associated with a +/// 'structured block', defined as: +/// +/// in C or C++, an executable statement, possibly compound, with a single +/// entry at the top and a single exit at the bottom +/// +/// At the moment there is no real motivation to have a different AST node for +/// those three, as they are semantically identical, and have only minor +/// differences in the permitted list of clauses, which can be differentiated by +/// the 'Kind'. +class OpenACCComputeConstruct final + : public OpenACCAssociatedStmtConstruct, + public llvm::TrailingObjects { + friend class ASTStmtWriter; + friend class ASTStmtReader; + friend class ASTContext; + OpenACCComputeConstruct(unsigned NumClauses) + : OpenACCAssociatedStmtConstruct( + OpenACCComputeConstructClass, OpenACCDirectiveKind::Invalid, + SourceLocation{}, SourceLocation{}, SourceLocation{}, + /*AssociatedStmt=*/nullptr) { + // We cannot send the TrailingObjects storage to the base class (which holds + // a reference to the data) until it is constructed, so we have to set it + // separately here. + std::uninitialized_value_construct( + getTrailingObjects(), + getTrailingObjects() + NumClauses); + setClauseList(MutableArrayRef(getTrailingObjects(), + NumClauses)); + } + + OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, + SourceLocation DirectiveLoc, SourceLocation End, + ArrayRef Clauses, + Stmt *StructuredBlock) + : OpenACCAssociatedStmtConstruct(OpenACCComputeConstructClass, K, Start, + DirectiveLoc, End, StructuredBlock) { + assert(isOpenACCComputeDirectiveKind(K) && + "Only parallel, serial, and kernels constructs should be " + "represented by this type"); + + // Initialize the trailing storage. + std::uninitialized_copy(Clauses.begin(), Clauses.end(), + getTrailingObjects()); + + setClauseList(MutableArrayRef(getTrailingObjects(), + Clauses.size())); + } + + void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); } + // Serialization helper function that searches the structured block for 'loop' + // constructs that should be associated with this, and sets their parent + // compute construct to this one. This isn't necessary normally, since we have + // the ability to record the state during parsing. + void findAndSetChildLoops(); + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCComputeConstructClass; + } + + static OpenACCComputeConstruct *CreateEmpty(const ASTContext &C, + unsigned NumClauses); + static OpenACCComputeConstruct * + Create(const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, + SourceLocation DirectiveLoc, SourceLocation EndLoc, + ArrayRef Clauses, Stmt *StructuredBlock, + ArrayRef AssociatedLoopConstructs); + + Stmt *getStructuredBlock() { return getAssociatedStmt(); } + const Stmt *getStructuredBlock() const { + return const_cast(this)->getStructuredBlock(); + } +}; +/// This class represents a 'loop' construct. The 'loop' construct applies to a +/// 'for' loop (or range-for loop), and is optionally associated with a Compute +/// Construct. +class OpenACCLoopConstruct final + : public OpenACCAssociatedStmtConstruct, + public llvm::TrailingObjects { + // The compute construct this loop is associated with, or nullptr if this is + // an orphaned loop construct, or if it hasn't been set yet. Because we + // construct the directives at the end of their statement, the 'parent' + // construct is not yet available at the time of construction, so this needs + // to be set 'later'. + const OpenACCComputeConstruct *ParentComputeConstruct = nullptr; + + friend class ASTStmtWriter; + friend class ASTStmtReader; + friend class ASTContext; + friend class OpenACCComputeConstruct; + + OpenACCLoopConstruct(unsigned NumClauses); + + OpenACCLoopConstruct(SourceLocation Start, SourceLocation DirLoc, + SourceLocation End, + ArrayRef Clauses, Stmt *Loop); + void setLoop(Stmt *Loop); + + void setParentComputeConstruct(OpenACCComputeConstruct *CC) { + assert(!ParentComputeConstruct && "Parent already set?"); + ParentComputeConstruct = CC; + } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCLoopConstructClass; + } + + static OpenACCLoopConstruct *CreateEmpty(const ASTContext &C, + unsigned NumClauses); + + static OpenACCLoopConstruct * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation DirLoc, + SourceLocation EndLoc, ArrayRef Clauses, + Stmt *Loop); + + Stmt *getLoop() { return getAssociatedStmt(); } + const Stmt *getLoop() const { + return const_cast(this)->getLoop(); + } + + /// OpenACC 3.3 2.9: + /// An orphaned loop construct is a loop construct that is not lexically + /// enclosed within a compute construct. The parent compute construct of a + /// loop construct is the nearest compute construct that lexically contains + /// the loop construct. + bool isOrphanedLoopConstruct() const { + return ParentComputeConstruct == nullptr; + } + const OpenACCComputeConstruct *getParentComputeConstruct() const { + return ParentComputeConstruct; + } +}; +} // namespace clang +#endif // LLVM_CLANG_AST_STMTOPENACC_H diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h b/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h index 62164339153..194eb2d10dc 100644 --- a/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h +++ b/contrib/llvm-project/clang/include/clang/AST/StmtOpenMP.h @@ -1007,8 +1007,9 @@ public: Stmt *getPreInits() const; static bool classof(const Stmt *T) { - return T->getStmtClass() == OMPTileDirectiveClass || - T->getStmtClass() == OMPUnrollDirectiveClass; + Stmt::StmtClass C = T->getStmtClass(); + return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass || + C == OMPReverseDirectiveClass || C == OMPInterchangeDirectiveClass; } }; @@ -2974,6 +2975,7 @@ class OMPAtomicDirective : public OMPExecutableDirective { /// This field is 1 for the first form of the expression and 0 for the /// second. Required for correct codegen of non-associative operations (like /// << or >>). + LLVM_PREFERRED_TYPE(bool) uint8_t IsXLHSInRHSPart : 1; /// Used for 'atomic update' or 'atomic capture' constructs. They may /// have atomic expressions of forms: @@ -2983,9 +2985,11 @@ class OMPAtomicDirective : public OMPExecutableDirective { /// \endcode /// This field is 1 for the first(postfix) form of the expression and 0 /// otherwise. + LLVM_PREFERRED_TYPE(bool) uint8_t IsPostfixUpdate : 1; /// 1 if 'v' is updated only when the condition is false (compare capture /// only). + LLVM_PREFERRED_TYPE(bool) uint8_t IsFailOnly : 1; } Flags; @@ -5708,6 +5712,144 @@ public: } }; +/// Represents the '#pragma omp reverse' loop transformation directive. +/// +/// \code +/// #pragma omp reverse +/// for (int i = 0; i < n; ++i) +/// ... +/// \endcode +class OMPReverseDirective final : public OMPLoopTransformationDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Offsets of child members. + enum { + PreInitsOffset = 0, + TransformedStmtOffset, + }; + + explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPLoopTransformationDirective(OMPReverseDirectiveClass, + llvm::omp::OMPD_reverse, StartLoc, + EndLoc, 1) {} + + void setPreInits(Stmt *PreInits) { + Data->getChildren()[PreInitsOffset] = PreInits; + } + + void setTransformedStmt(Stmt *S) { + Data->getChildren()[TransformedStmtOffset] = S; + } + +public: + /// Create a new AST node representation for '#pragma omp reverse'. + /// + /// \param C Context of the AST. + /// \param StartLoc Location of the introducer (e.g. the 'omp' token). + /// \param EndLoc Location of the directive's end (e.g. the tok::eod). + /// \param AssociatedStmt The outermost associated loop. + /// \param TransformedStmt The loop nest after tiling, or nullptr in + /// dependent contexts. + /// \param PreInits Helper preinits statements for the loop nest. + static OMPReverseDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits); + + /// Build an empty '#pragma omp reverse' AST node for deserialization. + /// + /// \param C Context of the AST. + /// \param NumClauses Number of clauses to allocate. + static OMPReverseDirective *CreateEmpty(const ASTContext &C); + + /// Gets/sets the associated loops after the transformation, i.e. after + /// de-sugaring. + Stmt *getTransformedStmt() const { + return Data->getChildren()[TransformedStmtOffset]; + } + + /// Return preinits statement. + Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPReverseDirectiveClass; + } +}; + +/// Represents the '#pragma omp interchange' loop transformation directive. +/// +/// \code{c} +/// #pragma omp interchange +/// for (int i = 0; i < m; ++i) +/// for (int j = 0; j < n; ++j) +/// .. +/// \endcode +class OMPInterchangeDirective final : public OMPLoopTransformationDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Offsets of child members. + enum { + PreInitsOffset = 0, + TransformedStmtOffset, + }; + + explicit OMPInterchangeDirective(SourceLocation StartLoc, + SourceLocation EndLoc, unsigned NumLoops) + : OMPLoopTransformationDirective(OMPInterchangeDirectiveClass, + llvm::omp::OMPD_interchange, StartLoc, + EndLoc, NumLoops) { + setNumGeneratedLoops(3 * NumLoops); + } + + void setPreInits(Stmt *PreInits) { + Data->getChildren()[PreInitsOffset] = PreInits; + } + + void setTransformedStmt(Stmt *S) { + Data->getChildren()[TransformedStmtOffset] = S; + } + +public: + /// Create a new AST node representation for '#pragma omp interchange'. + /// + /// \param C Context of the AST. + /// \param StartLoc Location of the introducer (e.g. the 'omp' token). + /// \param EndLoc Location of the directive's end (e.g. the tok::eod). + /// \param Clauses The directive's clauses. + /// \param NumLoops Number of affected loops + /// (number of items in the 'permutation' clause if present). + /// \param AssociatedStmt The outermost associated loop. + /// \param TransformedStmt The loop nest after tiling, or nullptr in + /// dependent contexts. + /// \param PreInits Helper preinits statements for the loop nest. + static OMPInterchangeDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef Clauses, unsigned NumLoops, Stmt *AssociatedStmt, + Stmt *TransformedStmt, Stmt *PreInits); + + /// Build an empty '#pragma omp interchange' AST node for deserialization. + /// + /// \param C Context of the AST. + /// \param NumClauses Number of clauses to allocate. + /// \param NumLoops Number of associated loops to allocate. + static OMPInterchangeDirective * + CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned NumLoops); + + /// Gets the associated loops after the transformation. This is the de-sugared + /// replacement or nullptr in dependent contexts. + Stmt *getTransformedStmt() const { + return Data->getChildren()[TransformedStmtOffset]; + } + + /// Return preinits statement. + Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPInterchangeDirectiveClass; + } +}; + /// This represents '#pragma omp scan' directive. /// /// \code @@ -6106,6 +6248,8 @@ public: class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { friend class ASTStmtReader; friend class OMPExecutableDirective; + /// true if loop directive's associated loop can be a parallel for. + bool CanBeParallelFor = false; /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -6128,6 +6272,9 @@ class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { llvm::omp::OMPD_target_teams_loop, SourceLocation(), SourceLocation(), CollapsedNum) {} + /// Set whether associated loop can be a parallel for. + void setCanBeParallelFor(bool ParFor) { CanBeParallelFor = ParFor; } + public: /// Creates directive with a list of \p Clauses. /// @@ -6142,7 +6289,7 @@ public: static OMPTargetTeamsGenericLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool CanBeParallelFor); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -6156,6 +6303,10 @@ public: unsigned CollapsedNum, EmptyShell); + /// Return true if current loop directive's associated loop can be a + /// parallel for. + bool canBeParallelFor() const { return CanBeParallelFor; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass; } diff --git a/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h b/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h index 3e5155199ea..990aa2df180 100644 --- a/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h +++ b/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h @@ -13,13 +13,14 @@ #ifndef LLVM_CLANG_AST_STMTVISITOR_H #define LLVM_CLANG_AST_STMTVISITOR_H -#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" +#include "clang/AST/StmtOpenACC.h" #include "clang/AST/StmtOpenMP.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/STLExtras.h" diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h b/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h index fea2c8ccfee..0eaa4b0eedb 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h +++ b/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h @@ -459,7 +459,7 @@ public: bool IncludeType) const; /// Debugging aid that dumps the template argument. - void dump(raw_ostream &Out) const; + void dump(raw_ostream &Out, const ASTContext &Context) const; /// Debugging aid that dumps the template argument to standard error. void dump() const; diff --git a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h index b7732e54ba1..e3b7dd26153 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TemplateName.h +++ b/contrib/llvm-project/clang/include/clang/AST/TemplateName.h @@ -198,7 +198,8 @@ public: /// /// Here, "apply" is treated as a template name within the typename /// specifier in the typedef. "apply" is a nested template, and can -/// only be understood in the context of +/// only be understood in the context of a template instantiation, +/// hence is represented as a dependent template name. class TemplateName { // NameDecl is either a TemplateDecl or a UsingShadowDecl depending on the // NameKind. @@ -314,11 +315,6 @@ public: TemplateName getUnderlying() const; - /// Get the template name to substitute when this template name is used as a - /// template template argument. This refers to the most recent declaration of - /// the template, including any default template arguments. - TemplateName getNameToSubstitute() const; - TemplateNameDependence getDependence() const; /// Determines whether this is a dependent template name. @@ -332,7 +328,7 @@ public: /// unexpanded parameter pack (for C++0x variadic templates). bool containsUnexpandedParameterPack() const; - enum class Qualified { None, AsWritten, Fully }; + enum class Qualified { None, AsWritten }; /// Print the template name. /// /// \param OS the output stream to which the template name will be @@ -345,13 +341,15 @@ public: Qualified Qual = Qualified::AsWritten) const; /// Debugging aid that dumps the template name. - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; /// Debugging aid that dumps the template name to standard /// error. void dump() const; - void Profile(llvm::FoldingSetNodeID &ID); + void Profile(llvm::FoldingSetNodeID &ID) { + ID.AddPointer(Storage.getOpaqueValue()); + } /// Retrieve the template name as a void pointer. void *getAsVoidPointer() const { return Storage.getOpaqueValue(); } @@ -360,6 +358,10 @@ public: static TemplateName getFromVoidPointer(void *Ptr) { return TemplateName(Ptr); } + + /// Structural equality. + bool operator==(TemplateName Other) const { return Storage == Other.Storage; } + bool operator!=(TemplateName Other) const { return !operator==(Other); } }; /// Insertion operator for diagnostics. This allows sending TemplateName's @@ -417,17 +419,18 @@ inline TemplateName TemplateName::getUnderlying() const { return *this; } -/// Represents a template name that was expressed as a -/// qualified name. +/// Represents a template name as written in source code. /// -/// This kind of template name refers to a template name that was +/// This kind of template name may refer to a template name that was /// preceded by a nested name specifier, e.g., \c std::vector. Here, /// the nested name specifier is "std::" and the template name is the -/// declaration for "vector". The QualifiedTemplateName class is only -/// used to provide "sugar" for template names that were expressed -/// with a qualified name, and has no semantic meaning. In this -/// manner, it is to TemplateName what ElaboratedType is to Type, -/// providing extra syntactic sugar for downstream clients. +/// declaration for "vector". It may also have been written with the +/// 'template' keyword. The QualifiedTemplateName class is only +/// used to provide "sugar" for template names, so that they can +/// be differentiated from canonical template names. and has no +/// semantic meaning. In this manner, it is to TemplateName what +/// ElaboratedType is to Type, providing extra syntactic sugar +/// for downstream clients. class QualifiedTemplateName : public llvm::FoldingSetNode { friend class ASTContext; diff --git a/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h b/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h index 732749ad305..39dd1f515c9 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h +++ b/contrib/llvm-project/clang/include/clang/AST/TextNodeDumper.h @@ -24,6 +24,7 @@ #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" #include "clang/AST/Type.h" +#include "clang/AST/TypeLocVisitor.h" #include "clang/AST/TypeVisitor.h" namespace clang { @@ -132,6 +133,7 @@ class TextNodeDumper public ConstTemplateArgumentVisitor, public ConstStmtVisitor, public TypeVisitor, + public TypeLocVisitor, public ConstDeclVisitor { raw_ostream &OS; const bool ShowColors; @@ -179,12 +181,16 @@ public: void Visit(QualType T); + void Visit(TypeLoc); + void Visit(const Decl *D); void Visit(const CXXCtorInitializer *Init); void Visit(const OMPClause *C); + void Visit(const OpenACCClause *C); + void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); @@ -207,6 +213,9 @@ public: void dumpTemplateSpecializationKind(TemplateSpecializationKind TSK); void dumpNestedNameSpecifier(const NestedNameSpecifier *NNS); void dumpConceptReference(const ConceptReference *R); + void dumpTemplateArgument(const TemplateArgument &TA); + void dumpBareTemplateName(TemplateName TN); + void dumpTemplateName(TemplateName TN, StringRef Label = {}); void dumpDeclRef(const Decl *D, StringRef Label = {}); @@ -291,6 +300,8 @@ public: void VisitTypeTraitExpr(const TypeTraitExpr *Node); void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node); void VisitExpressionTraitExpr(const ExpressionTraitExpr *Node); + void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node); + void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node); void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); void VisitExprWithCleanups(const ExprWithCleanups *Node); void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); @@ -337,6 +348,8 @@ public: void VisitObjCInterfaceType(const ObjCInterfaceType *T); void VisitPackExpansionType(const PackExpansionType *T); + void VisitTypeLoc(TypeLoc TL); + void VisitLabelDecl(const LabelDecl *D); void VisitTypedefDecl(const TypedefDecl *D); void VisitEnumDecl(const EnumDecl *D); @@ -344,6 +357,7 @@ public: void VisitEnumConstantDecl(const EnumConstantDecl *D); void VisitIndirectFieldDecl(const IndirectFieldDecl *D); void VisitFunctionDecl(const FunctionDecl *D); + void VisitCXXDeductionGuideDecl(const CXXDeductionGuideDecl *D); void VisitFieldDecl(const FieldDecl *D); void VisitVarDecl(const VarDecl *D); void VisitBindingDecl(const BindingDecl *D); @@ -393,6 +407,9 @@ public: void VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D); void VisitHLSLBufferDecl(const HLSLBufferDecl *D); + void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S); + void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S); + void VisitEmbedExpr(const EmbedExpr *S); }; } // namespace clang diff --git a/contrib/llvm-project/clang/include/clang/AST/Type.h b/contrib/llvm-project/clang/include/clang/AST/Type.h index 6384cf9420b..25defea58c2 100644 --- a/contrib/llvm-project/clang/include/clang/AST/Type.h +++ b/contrib/llvm-project/clang/include/clang/AST/Type.h @@ -25,8 +25,10 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/Linkage.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/PointerAuthOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/Visibility.h" @@ -61,6 +63,7 @@ class BTFTypeTagAttr; class ExtQuals; class QualType; class ConceptDecl; +class ValueDecl; class TagDecl; class TemplateParameterList; class Type; @@ -115,6 +118,7 @@ class EnumDecl; class Expr; class ExtQualsTypeCommonBase; class FunctionDecl; +class FunctionEffectSet; class IdentifierInfo; class NamedDecl; class ObjCInterfaceDecl; @@ -138,6 +142,174 @@ using CanQualType = CanQual; #define TYPE(Class, Base) class Class##Type; #include "clang/AST/TypeNodes.inc" +/// Pointer-authentication qualifiers. +class PointerAuthQualifier { + enum : uint32_t { + EnabledShift = 0, + EnabledBits = 1, + EnabledMask = 1 << EnabledShift, + AddressDiscriminatedShift = EnabledShift + EnabledBits, + AddressDiscriminatedBits = 1, + AddressDiscriminatedMask = 1 << AddressDiscriminatedShift, + AuthenticationModeShift = + AddressDiscriminatedShift + AddressDiscriminatedBits, + AuthenticationModeBits = 2, + AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1) + << AuthenticationModeShift, + IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits, + IsaPointerBits = 1, + IsaPointerMask = ((1 << IsaPointerBits) - 1) << IsaPointerShift, + AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits, + AuthenticatesNullValuesBits = 1, + AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1) + << AuthenticatesNullValuesShift, + KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits, + KeyBits = 10, + KeyMask = ((1 << KeyBits) - 1) << KeyShift, + DiscriminatorShift = KeyShift + KeyBits, + DiscriminatorBits = 16, + DiscriminatorMask = ((1u << DiscriminatorBits) - 1) << DiscriminatorShift, + }; + + // bits: |0 |1 |2..3 |4 | + // |Enabled|Address|AuthenticationMode|ISA pointer| + // bits: |5 |6..15| 16...31 | + // |AuthenticatesNull|Key |Discriminator| + uint32_t Data = 0; + + // The following static assertions check that each of the 32 bits is present + // exactly in one of the constants. + static_assert((EnabledBits + AddressDiscriminatedBits + + AuthenticationModeBits + IsaPointerBits + + AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) == + 32, + "PointerAuthQualifier should be exactly 32 bits"); + static_assert((EnabledMask + AddressDiscriminatedMask + + AuthenticationModeMask + IsaPointerMask + + AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) == + 0xFFFFFFFF, + "All masks should cover the entire bits"); + static_assert((EnabledMask ^ AddressDiscriminatedMask ^ + AuthenticationModeMask ^ IsaPointerMask ^ + AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) == + 0xFFFFFFFF, + "All masks should cover the entire bits"); + + PointerAuthQualifier(unsigned Key, bool IsAddressDiscriminated, + unsigned ExtraDiscriminator, + PointerAuthenticationMode AuthenticationMode, + bool IsIsaPointer, bool AuthenticatesNullValues) + : Data(EnabledMask | + (IsAddressDiscriminated + ? llvm::to_underlying(AddressDiscriminatedMask) + : 0) | + (Key << KeyShift) | + (llvm::to_underlying(AuthenticationMode) + << AuthenticationModeShift) | + (ExtraDiscriminator << DiscriminatorShift) | + (IsIsaPointer << IsaPointerShift) | + (AuthenticatesNullValues << AuthenticatesNullValuesShift)) { + assert(Key <= KeyNoneInternal); + assert(ExtraDiscriminator <= MaxDiscriminator); + assert((Data == 0) == + (getAuthenticationMode() == PointerAuthenticationMode::None)); + } + +public: + enum { + KeyNoneInternal = (1u << KeyBits) - 1, + + /// The maximum supported pointer-authentication key. + MaxKey = KeyNoneInternal - 1, + + /// The maximum supported pointer-authentication discriminator. + MaxDiscriminator = (1u << DiscriminatorBits) - 1 + }; + +public: + PointerAuthQualifier() = default; + + static PointerAuthQualifier + Create(unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator, + PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer, + bool AuthenticatesNullValues) { + if (Key == PointerAuthKeyNone) + Key = KeyNoneInternal; + assert(Key <= KeyNoneInternal && "out-of-range key value"); + return PointerAuthQualifier(Key, IsAddressDiscriminated, ExtraDiscriminator, + AuthenticationMode, IsIsaPointer, + AuthenticatesNullValues); + } + + bool isPresent() const { + assert((Data == 0) == + (getAuthenticationMode() == PointerAuthenticationMode::None)); + return Data != 0; + } + + explicit operator bool() const { return isPresent(); } + + unsigned getKey() const { + assert(isPresent()); + return (Data & KeyMask) >> KeyShift; + } + + bool hasKeyNone() const { return isPresent() && getKey() == KeyNoneInternal; } + + bool isAddressDiscriminated() const { + assert(isPresent()); + return (Data & AddressDiscriminatedMask) >> AddressDiscriminatedShift; + } + + unsigned getExtraDiscriminator() const { + assert(isPresent()); + return (Data >> DiscriminatorShift); + } + + PointerAuthenticationMode getAuthenticationMode() const { + return PointerAuthenticationMode((Data & AuthenticationModeMask) >> + AuthenticationModeShift); + } + + bool isIsaPointer() const { + assert(isPresent()); + return (Data & IsaPointerMask) >> IsaPointerShift; + } + + bool authenticatesNullValues() const { + assert(isPresent()); + return (Data & AuthenticatesNullValuesMask) >> AuthenticatesNullValuesShift; + } + + PointerAuthQualifier withoutKeyNone() const { + return hasKeyNone() ? PointerAuthQualifier() : *this; + } + + friend bool operator==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { + return Lhs.Data == Rhs.Data; + } + friend bool operator!=(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { + return Lhs.Data != Rhs.Data; + } + + bool isEquivalent(PointerAuthQualifier Other) const { + return withoutKeyNone() == Other.withoutKeyNone(); + } + + uint32_t getAsOpaqueValue() const { return Data; } + + // Deserialize pointer-auth qualifiers from an opaque representation. + static PointerAuthQualifier fromOpaqueValue(uint32_t Opaque) { + PointerAuthQualifier Result; + Result.Data = Opaque; + assert((Result.Data == 0) == + (Result.getAuthenticationMode() == PointerAuthenticationMode::None)); + return Result; + } + + void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Data); } +}; + /// The collection of all-type qualifiers we support. /// Clang supports five independent qualifiers: /// * C99: const, volatile, and restrict @@ -146,8 +318,9 @@ using CanQualType = CanQual; /// * Objective C: the GC attributes (none, weak, or strong) class Qualifiers { public: - enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. - Const = 0x1, + enum TQ : uint64_t { + // NOTE: These flags must be kept in sync with DeclSpec::TQ. + Const = 0x1, Restrict = 0x2, Volatile = 0x4, CVRMask = Const | Volatile | Restrict @@ -181,7 +354,7 @@ public: OCL_Autoreleasing }; - enum { + enum : uint64_t { /// The maximum supported address space number. /// 23 bits should be enough for anyone. MaxAddressSpace = 0x7fffffu, @@ -196,16 +369,25 @@ public: /// Returns the common set of qualifiers while removing them from /// the given sets. static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { + Qualifiers Q; + PointerAuthQualifier LPtrAuth = L.getPointerAuth(); + if (LPtrAuth.isPresent() && + LPtrAuth.getKey() != PointerAuthQualifier::KeyNoneInternal && + LPtrAuth == R.getPointerAuth()) { + Q.setPointerAuth(LPtrAuth); + PointerAuthQualifier Empty; + L.setPointerAuth(Empty); + R.setPointerAuth(Empty); + } + // If both are only CVR-qualified, bit operations are sufficient. if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { - Qualifiers Q; Q.Mask = L.Mask & R.Mask; L.Mask &= ~Q.Mask; R.Mask &= ~Q.Mask; return Q; } - Qualifiers Q; unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); Q.addCVRQualifiers(CommonCRV); L.removeCVRQualifiers(CommonCRV); @@ -250,16 +432,14 @@ public: } // Deserialize qualifiers from an opaque representation. - static Qualifiers fromOpaqueValue(unsigned opaque) { + static Qualifiers fromOpaqueValue(uint64_t opaque) { Qualifiers Qs; Qs.Mask = opaque; return Qs; } // Serialize these qualifiers into an opaque representation. - unsigned getAsOpaqueValue() const { - return Mask; - } + uint64_t getAsOpaqueValue() const { return Mask; } bool hasConst() const { return Mask & Const; } bool hasOnlyConst() const { return Mask == Const; } @@ -301,7 +481,7 @@ public: } void removeCVRQualifiers(unsigned mask) { assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); - Mask &= ~mask; + Mask &= ~static_cast(mask); } void removeCVRQualifiers() { removeCVRQualifiers(CVRMask); @@ -406,6 +586,20 @@ public: setAddressSpace(space); } + bool hasPointerAuth() const { return Mask & PtrAuthMask; } + PointerAuthQualifier getPointerAuth() const { + return PointerAuthQualifier::fromOpaqueValue(Mask >> PtrAuthShift); + } + void setPointerAuth(PointerAuthQualifier Q) { + Mask = (Mask & ~PtrAuthMask) | + (uint64_t(Q.getAsOpaqueValue()) << PtrAuthShift); + } + void removePointerAuth() { Mask &= ~PtrAuthMask; } + void addPointerAuth(PointerAuthQualifier Q) { + assert(Q.isPresent()); + setPointerAuth(Q); + } + // Fast qualifiers are those that can be allocated directly // on a QualType object. bool hasFastQualifiers() const { return getFastQualifiers(); } @@ -416,7 +610,7 @@ public: } void removeFastQualifiers(unsigned mask) { assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); - Mask &= ~mask; + Mask &= ~static_cast(mask); } void removeFastQualifiers() { removeFastQualifiers(FastMask); @@ -453,6 +647,8 @@ public: addObjCGCAttr(Q.getObjCGCAttr()); if (Q.hasObjCLifetime()) addObjCLifetime(Q.getObjCLifetime()); + if (Q.hasPointerAuth()) + addPointerAuth(Q.getPointerAuth()); } } @@ -470,6 +666,8 @@ public: removeObjCLifetime(); if (getAddressSpace() == Q.getAddressSpace()) removeAddressSpace(); + if (getPointerAuth() == Q.getPointerAuth()) + removePointerAuth(); } } @@ -482,6 +680,8 @@ public: !hasObjCGCAttr() || !qs.hasObjCGCAttr()); assert(getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()); + assert(!hasPointerAuth() || !qs.hasPointerAuth() || + getPointerAuth() == qs.getPointerAuth()); Mask |= qs.Mask; } @@ -535,6 +735,8 @@ public: // be changed. (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || !other.hasObjCGCAttr()) && + // Pointer-auth qualifiers must match exactly. + getPointerAuth() == other.getPointerAuth() && // ObjC lifetime qualifiers must match exactly. getObjCLifetime() == other.getObjCLifetime() && // CVR qualifiers may subset. @@ -604,24 +806,26 @@ public: void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty = false) const; - void Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger(Mask); - } + void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Mask); } private: - // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| - // |C R V|U|GCAttr|Lifetime|AddressSpace| - uint32_t Mask = 0; + // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|32 ... 63| + // |C R V|U|GCAttr|Lifetime|AddressSpace| PtrAuth | + uint64_t Mask = 0; + static_assert(sizeof(PointerAuthQualifier) == sizeof(uint32_t), + "PointerAuthQualifier must be 32 bits"); - static const uint32_t UMask = 0x8; - static const uint32_t UShift = 3; - static const uint32_t GCAttrMask = 0x30; - static const uint32_t GCAttrShift = 4; - static const uint32_t LifetimeMask = 0x1C0; - static const uint32_t LifetimeShift = 6; - static const uint32_t AddressSpaceMask = + static constexpr uint64_t UMask = 0x8; + static constexpr uint64_t UShift = 3; + static constexpr uint64_t GCAttrMask = 0x30; + static constexpr uint64_t GCAttrShift = 4; + static constexpr uint64_t LifetimeMask = 0x1C0; + static constexpr uint64_t LifetimeShift = 6; + static constexpr uint64_t AddressSpaceMask = ~(CVRMask | UMask | GCAttrMask | LifetimeMask); - static const uint32_t AddressSpaceShift = 9; + static constexpr uint64_t AddressSpaceShift = 9; + static constexpr uint64_t PtrAuthShift = 32; + static constexpr uint64_t PtrAuthMask = uint64_t(0xffffffff) << PtrAuthShift; }; class QualifiersAndAtomic { @@ -917,15 +1121,26 @@ public: /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) bool isTriviallyCopyableType(const ASTContext &Context) const; + /// Return true if the type is safe to bitwise copy using memcpy/memmove. + /// + /// This is an extension in clang: bitwise cloneable types act as trivially + /// copyable types, meaning their underlying bytes can be safely copied by + /// memcpy or memmove. After the copy, the destination object has the same + /// object representation. + /// + /// However, there are cases where it is not safe to copy: + /// - When sanitizers, such as AddressSanitizer, add padding with poison, + /// which can cause issues if those poisoned padding bits are accessed. + /// - Types with Objective-C lifetimes, where specific runtime + /// semantics may not be preserved during a bitwise copy. + bool isBitwiseCloneableType(const ASTContext &Context) const; + /// Return true if this is a trivially copyable type bool isTriviallyCopyConstructibleType(const ASTContext &Context) const; /// Return true if this is a trivially relocatable type. bool isTriviallyRelocatableType(const ASTContext &Context) const; - /// Return true if this is a trivially equality comparable type. - bool isTriviallyEqualityComparableType(const ASTContext &Context) const; - /// Returns true if it is a class and it might be dynamic. bool mayBeDynamicClass() const; @@ -1241,6 +1456,10 @@ public: // true when Type is objc's weak and weak is enabled but ARC isn't. bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; + PointerAuthQualifier getPointerAuth() const { + return getQualifiers().getPointerAuth(); + } + enum PrimitiveDefaultInitializeKind { /// The type does not fall into any of the following categories. Note that /// this case is zero-valued so that values of this enum can be used as a @@ -1398,6 +1617,10 @@ public: QualType stripObjCKindOfType(const ASTContext &ctx) const; /// Remove all qualifiers including _Atomic. + /// + /// Like getUnqualifiedType(), the type may still be qualified if it is a + /// sugared array type. To strip qualifiers even from within a sugared array + /// type, use in conjunction with ASTContext::getUnqualifiedArrayType. QualType getAtomicUnqualifiedType() const; private: @@ -1689,7 +1912,10 @@ protected: /// Whether we have a stored size expression. LLVM_PREFERRED_TYPE(bool) - unsigned HasStoredSizeExpr : 1; + unsigned HasExternalSize : 1; + + LLVM_PREFERRED_TYPE(unsigned) + unsigned SizeWidth : 5; }; class BuiltinTypeBitfields { @@ -1882,8 +2108,8 @@ protected: LLVM_PREFERRED_TYPE(TypeBitfields) unsigned : NumTypeBits; - LLVM_PREFERRED_TYPE(bool) - unsigned IsUnqual : 1; // If true: typeof_unqual, else: typeof + LLVM_PREFERRED_TYPE(TypeOfKind) + unsigned Kind : 1; }; class UsingBitfields { @@ -2000,6 +2226,21 @@ protected: unsigned NumExpansions; }; + class CountAttributedTypeBitfields { + friend class CountAttributedType; + + LLVM_PREFERRED_TYPE(TypeBitfields) + unsigned : NumTypeBits; + + static constexpr unsigned NumCoupledDeclsBits = 4; + unsigned NumCoupledDecls : NumCoupledDeclsBits; + LLVM_PREFERRED_TYPE(bool) + unsigned CountInBytes : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned OrNull : 1; + }; + static_assert(sizeof(CountAttributedTypeBitfields) <= sizeof(unsigned)); + union { TypeBitfields TypeBits; ArrayTypeBitfields ArrayTypeBits; @@ -2022,6 +2263,7 @@ protected: DependentTemplateSpecializationTypeBitfields DependentTemplateSpecializationTypeBits; PackExpansionTypeBitfields PackExpansionTypeBits; + CountAttributedTypeBitfields CountAttributedTypeBits; }; private: @@ -2152,6 +2394,10 @@ public: /// 'riscv_rvv_vector_bits' type attribute as VectorType. QualType getRVVEltType(const ASTContext &Ctx) const; + /// Returns the representative type for the element of a sizeless vector + /// builtin type. + QualType getSizelessVectorEltType(const ASTContext &Ctx) const; + /// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// object types, function types, and incomplete types. @@ -2244,6 +2490,8 @@ public: bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isFloat32Type() const; + bool isDoubleType() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -2261,7 +2509,9 @@ public: bool isFunctionNoProtoType() const { return getAs(); } bool isFunctionProtoType() const { return getAs(); } bool isPointerType() const; + bool isSignableType() const; bool isAnyPointerType() const; // Any C pointer or ObjC object pointer + bool isCountAttributedType() const; bool isBlockPointerType() const; bool isVoidPointerType() const; bool isReferenceType() const; @@ -2277,10 +2527,12 @@ public: bool isConstantArrayType() const; bool isIncompleteArrayType() const; bool isVariableArrayType() const; + bool isArrayParameterType() const; bool isDependentSizedArrayType() const; bool isRecordType() const; bool isClassType() const; bool isStructureType() const; + bool isStructureTypeWithFlexibleArrayMember() const; bool isObjCBoxableRecordType() const; bool isInterfaceType() const; bool isStructureOrClassType() const; @@ -2289,6 +2541,7 @@ public: bool isVectorType() const; // GCC vector type. bool isExtVectorType() const; // Extended vector type. bool isExtVectorBoolType() const; // Extended vector type with bool element. + bool isSubscriptableVectorType() const; bool isMatrixType() const; // Matrix type. bool isConstantMatrixType() const; // Constant matrix type. bool isDependentAddressSpaceType() const; // value-dependent address space qualifier @@ -2613,6 +2866,9 @@ public: /// Return true if this is a fixed point or integer type. bool isFixedPointOrIntegerType() const; + /// Return true if this can be converted to (or from) a fixed point type. + bool isConvertibleToFixedPointType() const; + /// Return true if this is a saturated fixed point type according to /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned. bool isSaturatedFixedPointType() const; @@ -2719,6 +2975,14 @@ template <> const TemplateSpecializationType *Type::getAs() const; /// until it reaches an AttributedType or a non-sugared type. template <> const AttributedType *Type::getAs() const; +/// This will check for a BoundsAttributedType by removing any existing +/// sugar until it reaches an BoundsAttributedType or a non-sugared type. +template <> const BoundsAttributedType *Type::getAs() const; + +/// This will check for a CountAttributedType by removing any existing +/// sugar until it reaches an CountAttributedType or a non-sugared type. +template <> const CountAttributedType *Type::getAs() const; + // We can do canonical leaf types faster, because we don't have to // worry about preserving child type decoration. #define TYPE(Class, Base) @@ -2754,6 +3018,9 @@ public: // WebAssembly reference types #define WASM_TYPE(Name, Id, SingletonId) Id, #include "clang/Basic/WebAssemblyReferenceTypes.def" +// AMDGPU types +#define AMDGPU_TYPE(Name, Id, SingletonId) Id, +#include "clang/Basic/AMDGPUTypes.def" // All other builtin types #define BUILTIN_TYPE(Id, SingletonId) Id, #define LAST_BUILTIN_TYPE(Id) LastKind = Id @@ -2917,6 +3184,136 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } }; +/// [BoundsSafety] Represents information of declarations referenced by the +/// arguments of the `counted_by` attribute and the likes. +class TypeCoupledDeclRefInfo { +public: + using BaseTy = llvm::PointerIntPair; + +private: + enum { + DerefShift = 0, + DerefMask = 1, + }; + BaseTy Data; + +public: + /// \p D is to a declaration referenced by the argument of attribute. \p Deref + /// indicates whether \p D is referenced as a dereferenced form, e.g., \p + /// Deref is true for `*n` in `int *__counted_by(*n)`. + TypeCoupledDeclRefInfo(ValueDecl *D = nullptr, bool Deref = false); + + bool isDeref() const; + ValueDecl *getDecl() const; + unsigned getInt() const; + void *getOpaqueValue() const; + bool operator==(const TypeCoupledDeclRefInfo &Other) const; + void setFromOpaqueValue(void *V); +}; + +/// [BoundsSafety] Represents a parent type class for CountAttributedType and +/// similar sugar types that will be introduced to represent a type with a +/// bounds attribute. +/// +/// Provides a common interface to navigate declarations referred to by the +/// bounds expression. + +class BoundsAttributedType : public Type, public llvm::FoldingSetNode { + QualType WrappedTy; + +protected: + ArrayRef Decls; // stored in trailing objects + + BoundsAttributedType(TypeClass TC, QualType Wrapped, QualType Canon); + +public: + bool isSugared() const { return true; } + QualType desugar() const { return WrappedTy; } + + using decl_iterator = const TypeCoupledDeclRefInfo *; + using decl_range = llvm::iterator_range; + + decl_iterator dependent_decl_begin() const { return Decls.begin(); } + decl_iterator dependent_decl_end() const { return Decls.end(); } + + unsigned getNumCoupledDecls() const { return Decls.size(); } + + decl_range dependent_decls() const { + return decl_range(dependent_decl_begin(), dependent_decl_end()); + } + + ArrayRef getCoupledDecls() const { + return {dependent_decl_begin(), dependent_decl_end()}; + } + + bool referencesFieldDecls() const; + + static bool classof(const Type *T) { + // Currently, only `class CountAttributedType` inherits + // `BoundsAttributedType` but the subclass will grow as we add more bounds + // annotations. + switch (T->getTypeClass()) { + case CountAttributed: + return true; + default: + return false; + } + } +}; + +/// Represents a sugar type with `__counted_by` or `__sized_by` annotations, +/// including their `_or_null` variants. +class CountAttributedType final + : public BoundsAttributedType, + public llvm::TrailingObjects { + friend class ASTContext; + + Expr *CountExpr; + /// \p CountExpr represents the argument of __counted_by or the likes. \p + /// CountInBytes indicates that \p CountExpr is a byte count (i.e., + /// __sized_by(_or_null)) \p OrNull means it's an or_null variant (i.e., + /// __counted_by_or_null or __sized_by_or_null) \p CoupledDecls contains the + /// list of declarations referenced by \p CountExpr, which the type depends on + /// for the bounds information. + CountAttributedType(QualType Wrapped, QualType Canon, Expr *CountExpr, + bool CountInBytes, bool OrNull, + ArrayRef CoupledDecls); + + unsigned numTrailingObjects(OverloadToken) const { + return CountAttributedTypeBits.NumCoupledDecls; + } + +public: + enum DynamicCountPointerKind { + CountedBy = 0, + SizedBy, + CountedByOrNull, + SizedByOrNull, + }; + + Expr *getCountExpr() const { return CountExpr; } + bool isCountInBytes() const { return CountAttributedTypeBits.CountInBytes; } + bool isOrNull() const { return CountAttributedTypeBits.OrNull; } + + DynamicCountPointerKind getKind() const { + if (isOrNull()) + return isCountInBytes() ? SizedByOrNull : CountedByOrNull; + return isCountInBytes() ? SizedBy : CountedBy; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, desugar(), CountExpr, isCountInBytes(), isOrNull()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType WrappedTy, + Expr *CountExpr, bool CountInBytes, bool Nullable); + + static bool classof(const Type *T) { + return T->getTypeClass() == CountAttributed; + } +}; + /// Represents a type which was implicitly adjusted by the semantic /// engine for arbitrary reasons. For example, array and function types can /// decay, and function types can have their calling conventions adjusted. @@ -3170,42 +3567,114 @@ public: return T->getTypeClass() == ConstantArray || T->getTypeClass() == VariableArray || T->getTypeClass() == IncompleteArray || - T->getTypeClass() == DependentSizedArray; + T->getTypeClass() == DependentSizedArray || + T->getTypeClass() == ArrayParameter; } }; /// Represents the canonical version of C arrays with a specified constant size. /// For example, the canonical type for 'int A[4 + 4*100]' is a /// ConstantArrayType where the element type is 'int' and the size is 404. -class ConstantArrayType final - : public ArrayType, - private llvm::TrailingObjects { +class ConstantArrayType : public ArrayType { friend class ASTContext; // ASTContext creates these. - friend TrailingObjects; - llvm::APInt Size; // Allows us to unique the type. + struct ExternalSize { + ExternalSize(const llvm::APInt &Sz, const Expr *SE) + : Size(Sz), SizeExpr(SE) {} + llvm::APInt Size; // Allows us to unique the type. + const Expr *SizeExpr; + }; - ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, - const Expr *sz, ArraySizeModifier sm, unsigned tq) - : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) { - ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr; - if (ConstantArrayTypeBits.HasStoredSizeExpr) { - assert(!can.isNull() && "canonical constant array should not have size"); - *getTrailingObjects() = sz; - } + union { + uint64_t Size; + ExternalSize *SizePtr; + }; + + ConstantArrayType(QualType Et, QualType Can, uint64_t Width, uint64_t Sz, + ArraySizeModifier SM, unsigned TQ) + : ArrayType(ConstantArray, Et, Can, SM, TQ, nullptr), Size(Sz) { + ConstantArrayTypeBits.HasExternalSize = false; + ConstantArrayTypeBits.SizeWidth = Width / 8; + // The in-structure size stores the size in bytes rather than bits so we + // drop the three least significant bits since they're always zero anyways. + assert(Width < 0xFF && "Type width in bits must be less than 8 bits"); } - unsigned numTrailingObjects(OverloadToken) const { - return ConstantArrayTypeBits.HasStoredSizeExpr; + ConstantArrayType(QualType Et, QualType Can, ExternalSize *SzPtr, + ArraySizeModifier SM, unsigned TQ) + : ArrayType(ConstantArray, Et, Can, SM, TQ, SzPtr->SizeExpr), + SizePtr(SzPtr) { + ConstantArrayTypeBits.HasExternalSize = true; + ConstantArrayTypeBits.SizeWidth = 0; + + assert((SzPtr->SizeExpr == nullptr || !Can.isNull()) && + "canonical constant array should not have size expression"); + } + + static ConstantArrayType *Create(const ASTContext &Ctx, QualType ET, + QualType Can, const llvm::APInt &Sz, + const Expr *SzExpr, ArraySizeModifier SzMod, + unsigned Qual); + +protected: + ConstantArrayType(TypeClass Tc, const ConstantArrayType *ATy, QualType Can) + : ArrayType(Tc, ATy->getElementType(), Can, ATy->getSizeModifier(), + ATy->getIndexTypeQualifiers().getAsOpaqueValue(), nullptr) { + ConstantArrayTypeBits.HasExternalSize = + ATy->ConstantArrayTypeBits.HasExternalSize; + if (!ConstantArrayTypeBits.HasExternalSize) { + ConstantArrayTypeBits.SizeWidth = ATy->ConstantArrayTypeBits.SizeWidth; + Size = ATy->Size; + } else + SizePtr = ATy->SizePtr; } public: - const llvm::APInt &getSize() const { return Size; } - const Expr *getSizeExpr() const { - return ConstantArrayTypeBits.HasStoredSizeExpr - ? *getTrailingObjects() - : nullptr; + /// Return the constant array size as an APInt. + llvm::APInt getSize() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size + : llvm::APInt(ConstantArrayTypeBits.SizeWidth * 8, Size); } + + /// Return the bit width of the size type. + unsigned getSizeBitWidth() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size.getBitWidth() + : static_cast(ConstantArrayTypeBits.SizeWidth * 8); + } + + /// Return true if the size is zero. + bool isZeroSize() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.isZero() + : 0 == Size; + } + + /// Return the size zero-extended as a uint64_t. + uint64_t getZExtSize() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getZExtValue() + : Size; + } + + /// Return the size sign-extended as a uint64_t. + int64_t getSExtSize() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getSExtValue() + : static_cast(Size); + } + + /// Return the size zero-extended to uint64_t or UINT64_MAX if the value is + /// larger than UINT64_MAX. + uint64_t getLimitedSize() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size.getLimitedValue() + : Size; + } + + /// Return a pointer to the size expression. + const Expr *getSizeExpr() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->SizeExpr : nullptr; + } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -3222,17 +3691,31 @@ public: static unsigned getMaxSizeBits(const ASTContext &Context); void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { - Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(), + Profile(ID, Ctx, getElementType(), getZExtSize(), getSizeExpr(), getSizeModifier(), getIndexTypeCVRQualifiers()); } static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, - QualType ET, const llvm::APInt &ArraySize, - const Expr *SizeExpr, ArraySizeModifier SizeMod, - unsigned TypeQuals); + QualType ET, uint64_t ArraySize, const Expr *SizeExpr, + ArraySizeModifier SizeMod, unsigned TypeQuals); static bool classof(const Type *T) { - return T->getTypeClass() == ConstantArray; + return T->getTypeClass() == ConstantArray || + T->getTypeClass() == ArrayParameter; + } +}; + +/// Represents a constant array type that does not decay to a pointer when used +/// as a function parameter. +class ArrayParameterType : public ConstantArrayType { + friend class ASTContext; // ASTContext creates these. + + ArrayParameterType(const ConstantArrayType *ATy, QualType CanTy) + : ConstantArrayType(ArrayParameter, ATy, CanTy) {} + +public: + static bool classof(const Type *T) { + return T->getTypeClass() == ArrayParameter; } }; @@ -4044,8 +4527,13 @@ public: LLVM_PREFERRED_TYPE(bool) unsigned HasArmTypeAttributes : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned EffectsHaveConditions : 1; + unsigned NumFunctionEffects : 4; + FunctionTypeExtraBitfields() - : NumExceptionType(0), HasArmTypeAttributes(false) {} + : NumExceptionType(0), HasArmTypeAttributes(false), + EffectsHaveConditions(false), NumFunctionEffects(0) {} }; /// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number @@ -4178,6 +4666,295 @@ public: } }; +// ------------------------------------------------------------------------------ + +/// Represents an abstract function effect, using just an enumeration describing +/// its kind. +class FunctionEffect { +public: + /// Identifies the particular effect. + enum class Kind : uint8_t { + None = 0, + NonBlocking = 1, + NonAllocating = 2, + Blocking = 3, + Allocating = 4 + }; + + /// Flags describing some behaviors of the effect. + using Flags = unsigned; + enum FlagBit : Flags { + // Can verification inspect callees' implementations? (e.g. nonblocking: + // yes, tcb+types: no). This also implies the need for 2nd-pass + // verification. + FE_InferrableOnCallees = 0x1, + + // Language constructs which effects can diagnose as disallowed. + FE_ExcludeThrow = 0x2, + FE_ExcludeCatch = 0x4, + FE_ExcludeObjCMessageSend = 0x8, + FE_ExcludeStaticLocalVars = 0x10, + FE_ExcludeThreadLocalVars = 0x20 + }; + +private: + LLVM_PREFERRED_TYPE(Kind) + unsigned FKind : 3; + + // Expansion: for hypothetical TCB+types, there could be one Kind for TCB, + // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would + // be considered for uniqueness. + +public: + FunctionEffect() : FKind(unsigned(Kind::None)) {} + + explicit FunctionEffect(Kind K) : FKind(unsigned(K)) {} + + /// The kind of the effect. + Kind kind() const { return Kind(FKind); } + + /// Return the opposite kind, for effects which have opposites. + Kind oppositeKind() const; + + /// For serialization. + uint32_t toOpaqueInt32() const { return FKind; } + static FunctionEffect fromOpaqueInt32(uint32_t Value) { + return FunctionEffect(Kind(Value)); + } + + /// Flags describing some behaviors of the effect. + Flags flags() const { + switch (kind()) { + case Kind::NonBlocking: + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars | + FE_ExcludeThreadLocalVars; + case Kind::NonAllocating: + // Same as NonBlocking, except without FE_ExcludeStaticLocalVars. + return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch | + FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars; + case Kind::Blocking: + case Kind::Allocating: + return 0; + case Kind::None: + break; + } + llvm_unreachable("unknown effect kind"); + } + + /// The description printed in diagnostics, e.g. 'nonblocking'. + StringRef name() const; + + /// Return true if the effect is allowed to be inferred on the callee, + /// which is either a FunctionDecl or BlockDecl. + /// Example: This allows nonblocking(false) to prevent inference for the + /// function. + bool canInferOnFunction(const Decl &Callee) const; + + // Return false for success. When true is returned for a direct call, then the + // FE_InferrableOnCallees flag may trigger inference rather than an immediate + // diagnostic. Caller should be assumed to have the effect (it may not have it + // explicitly when inferring). + bool shouldDiagnoseFunctionCall(bool Direct, + ArrayRef CalleeFX) const; + + friend bool operator==(const FunctionEffect &LHS, const FunctionEffect &RHS) { + return LHS.FKind == RHS.FKind; + } + friend bool operator!=(const FunctionEffect &LHS, const FunctionEffect &RHS) { + return !(LHS == RHS); + } + friend bool operator<(const FunctionEffect &LHS, const FunctionEffect &RHS) { + return LHS.FKind < RHS.FKind; + } +}; + +/// Wrap a function effect's condition expression in another struct so +/// that FunctionProtoType's TrailingObjects can treat it separately. +class EffectConditionExpr { + Expr *Cond = nullptr; // if null, unconditional. + +public: + EffectConditionExpr() = default; + EffectConditionExpr(Expr *E) : Cond(E) {} + + Expr *getCondition() const { return Cond; } + + bool operator==(const EffectConditionExpr &RHS) const { + return Cond == RHS.Cond; + } +}; + +/// A FunctionEffect plus a potential boolean expression determining whether +/// the effect is declared (e.g. nonblocking(expr)). Generally the condition +/// expression when present, is dependent. +struct FunctionEffectWithCondition { + FunctionEffect Effect; + EffectConditionExpr Cond; + + FunctionEffectWithCondition() = default; + FunctionEffectWithCondition(const FunctionEffect &E, + const EffectConditionExpr &C) + : Effect(E), Cond(C) {} + + /// Return a textual description of the effect, and its condition, if any. + std::string description() const; +}; + +/// Support iteration in parallel through a pair of FunctionEffect and +/// EffectConditionExpr containers. +template class FunctionEffectIterator { + friend Container; + + const Container *Outer = nullptr; + size_t Idx = 0; + +public: + FunctionEffectIterator(); + FunctionEffectIterator(const Container &O, size_t I) : Outer(&O), Idx(I) {} + bool operator==(const FunctionEffectIterator &Other) const { + return Idx == Other.Idx; + } + bool operator!=(const FunctionEffectIterator &Other) const { + return Idx != Other.Idx; + } + + FunctionEffectIterator operator++() { + ++Idx; + return *this; + } + + FunctionEffectWithCondition operator*() const { + assert(Outer != nullptr && "invalid FunctionEffectIterator"); + bool HasConds = !Outer->Conditions.empty(); + return FunctionEffectWithCondition{Outer->Effects[Idx], + HasConds ? Outer->Conditions[Idx] + : EffectConditionExpr()}; + } +}; + +/// An immutable set of FunctionEffects and possibly conditions attached to +/// them. The effects and conditions reside in memory not managed by this object +/// (typically, trailing objects in FunctionProtoType, or borrowed references +/// from a FunctionEffectSet). +/// +/// Invariants: +/// - there is never more than one instance of any given effect. +/// - the array of conditions is either empty or has the same size as the +/// array of effects. +/// - some conditions may be null expressions; each condition pertains to +/// the effect at the same array index. +/// +/// Also, if there are any conditions, at least one of those expressions will be +/// dependent, but this is only asserted in the constructor of +/// FunctionProtoType. +/// +/// See also FunctionEffectSet, in Sema, which provides a mutable set. +class FunctionEffectsRef { + // Restrict classes which can call the private constructor -- these friends + // all maintain the required invariants. FunctionEffectSet is generally the + // only way in which the arrays are created; FunctionProtoType will not + // reorder them. + friend FunctionProtoType; + friend FunctionEffectSet; + + ArrayRef Effects; + ArrayRef Conditions; + + // The arrays are expected to have been sorted by the caller, with the + // effects in order. The conditions array must be empty or the same size + // as the effects array, since the conditions are associated with the effects + // at the same array indices. + FunctionEffectsRef(ArrayRef FX, + ArrayRef Conds) + : Effects(FX), Conditions(Conds) {} + +public: + /// Extract the effects from a Type if it is a function, block, or member + /// function pointer, or a reference or pointer to one. + static FunctionEffectsRef get(QualType QT); + + /// Asserts invariants. + static FunctionEffectsRef create(ArrayRef FX, + ArrayRef Conds); + + FunctionEffectsRef() = default; + + bool empty() const { return Effects.empty(); } + size_t size() const { return Effects.size(); } + + ArrayRef effects() const { return Effects; } + ArrayRef conditions() const { return Conditions; } + + using iterator = FunctionEffectIterator; + friend iterator; + iterator begin() const { return iterator(*this, 0); } + iterator end() const { return iterator(*this, size()); } + + friend bool operator==(const FunctionEffectsRef &LHS, + const FunctionEffectsRef &RHS) { + return LHS.Effects == RHS.Effects && LHS.Conditions == RHS.Conditions; + } + friend bool operator!=(const FunctionEffectsRef &LHS, + const FunctionEffectsRef &RHS) { + return !(LHS == RHS); + } + + void dump(llvm::raw_ostream &OS) const; +}; + +/// A mutable set of FunctionEffects and possibly conditions attached to them. +/// Used to compare and merge effects on declarations. +/// +/// Has the same invariants as FunctionEffectsRef. +class FunctionEffectSet { + SmallVector Effects; + SmallVector Conditions; + +public: + FunctionEffectSet() = default; + + explicit FunctionEffectSet(const FunctionEffectsRef &FX) + : Effects(FX.effects()), Conditions(FX.conditions()) {} + + bool empty() const { return Effects.empty(); } + size_t size() const { return Effects.size(); } + + using iterator = FunctionEffectIterator; + friend iterator; + iterator begin() const { return iterator(*this, 0); } + iterator end() const { return iterator(*this, size()); } + + operator FunctionEffectsRef() const { return {Effects, Conditions}; } + + void dump(llvm::raw_ostream &OS) const; + + // Mutators + + // On insertion, a conflict occurs when attempting to insert an + // effect which is opposite an effect already in the set, or attempting + // to insert an effect which is already in the set but with a condition + // which is not identical. + struct Conflict { + FunctionEffectWithCondition Kept; + FunctionEffectWithCondition Rejected; + }; + using Conflicts = SmallVector; + + // Returns true for success (obviating a check of Errs.empty()). + bool insert(const FunctionEffectWithCondition &NewEC, Conflicts &Errs); + + // Returns true for success (obviating a check of Errs.empty()). + bool insert(const FunctionEffectsRef &Set, Conflicts &Errs); + + // Set operations + + static FunctionEffectSet getUnion(FunctionEffectsRef LHS, + FunctionEffectsRef RHS, Conflicts &Errs); + static FunctionEffectSet getIntersection(FunctionEffectsRef LHS, + FunctionEffectsRef RHS); +}; + /// Represents a prototype with parameter type info, e.g. /// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no /// parameters, not as having a single void parameter. Such a type can have @@ -4192,7 +4969,8 @@ class FunctionProtoType final FunctionProtoType, QualType, SourceLocation, FunctionType::FunctionTypeExtraBitfields, FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType, - Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> { + Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers, + FunctionEffect, EffectConditionExpr> { friend class ASTContext; // ASTContext creates these. friend TrailingObjects; @@ -4224,14 +5002,20 @@ class FunctionProtoType final // only if hasExtParameterInfos() is true. // // * Optionally a Qualifiers object to represent extra qualifiers that can't - // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and only - // if hasExtQualifiers() is true. + // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and + // only if hasExtQualifiers() is true. + // + // * Optionally, an array of getNumFunctionEffects() FunctionEffect. + // Present only when getNumFunctionEffects() > 0 + // + // * Optionally, an array of getNumFunctionEffects() EffectConditionExpr. + // Present only when getNumFunctionEffectConditions() > 0. // // The optional FunctionTypeExtraBitfields has to be before the data // related to the exception specification since it contains the number // of exception types. // - // We put the ExtParameterInfos last. If all were equal, it would make + // We put the ExtParameterInfos later. If all were equal, it would make // more sense to put these before the exception specification, because // it's much easier to skip past them compared to the elaborate switch // required to skip the exception specification. However, all is not @@ -4281,6 +5065,7 @@ public: ExceptionSpecInfo ExceptionSpec; const ExtParameterInfo *ExtParameterInfos = nullptr; SourceLocation EllipsisLoc; + FunctionEffectsRef FunctionEffects; ExtProtoInfo() : Variadic(false), HasTrailingReturn(false), @@ -4298,7 +5083,8 @@ public: bool requiresFunctionProtoTypeExtraBitfields() const { return ExceptionSpec.Type == EST_Dynamic || - requiresFunctionProtoTypeArmAttributes(); + requiresFunctionProtoTypeArmAttributes() || + !FunctionEffects.empty(); } bool requiresFunctionProtoTypeArmAttributes() const { @@ -4346,6 +5132,18 @@ private: return hasExtParameterInfos() ? getNumParams() : 0; } + unsigned numTrailingObjects(OverloadToken) const { + return hasExtQualifiers() ? 1 : 0; + } + + unsigned numTrailingObjects(OverloadToken) const { + return getNumFunctionEffects(); + } + + unsigned numTrailingObjects(OverloadToken) const { + return getNumFunctionEffectConditions(); + } + /// Determine whether there are any argument types that /// contain an unexpanded parameter pack. static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, @@ -4447,6 +5245,7 @@ public: EPI.RefQualifier = getRefQualifier(); EPI.ExtParameterInfos = getExtParameterInfosOrNull(); EPI.AArch64SMEAttributes = getAArch64SMEAttributes(); + EPI.FunctionEffects = getFunctionEffects(); return EPI; } @@ -4658,6 +5457,62 @@ public: return false; } + unsigned getNumFunctionEffects() const { + return hasExtraBitfields() + ? getTrailingObjects() + ->NumFunctionEffects + : 0; + } + + // For serialization. + ArrayRef getFunctionEffectsWithoutConditions() const { + if (hasExtraBitfields()) { + const auto *Bitfields = getTrailingObjects(); + if (Bitfields->NumFunctionEffects > 0) + return {getTrailingObjects(), + Bitfields->NumFunctionEffects}; + } + return {}; + } + + unsigned getNumFunctionEffectConditions() const { + if (hasExtraBitfields()) { + const auto *Bitfields = getTrailingObjects(); + if (Bitfields->EffectsHaveConditions) + return Bitfields->NumFunctionEffects; + } + return 0; + } + + // For serialization. + ArrayRef getFunctionEffectConditions() const { + if (hasExtraBitfields()) { + const auto *Bitfields = getTrailingObjects(); + if (Bitfields->EffectsHaveConditions) + return {getTrailingObjects(), + Bitfields->NumFunctionEffects}; + } + return {}; + } + + // Combines effects with their conditions. + FunctionEffectsRef getFunctionEffects() const { + if (hasExtraBitfields()) { + const auto *Bitfields = getTrailingObjects(); + if (Bitfields->NumFunctionEffects > 0) { + const size_t NumConds = Bitfields->EffectsHaveConditions + ? Bitfields->NumFunctionEffects + : 0; + return FunctionEffectsRef( + {getTrailingObjects(), + Bitfields->NumFunctionEffects}, + {NumConds ? getTrailingObjects() : nullptr, + NumConds}); + } + } + return {}; + } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -4732,13 +5587,12 @@ public: bool typeMatchesDecl() const { return !UsingBits.hasTypeDifferentFromDecl; } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, Found, typeMatchesDecl() ? QualType() : getUnderlyingType()); + Profile(ID, Found, getUnderlyingType()); } static void Profile(llvm::FoldingSetNodeID &ID, const UsingShadowDecl *Found, QualType Underlying) { ID.AddPointer(Found); - if (!Underlying.isNull()) - Underlying.Profile(ID); + Underlying.Profile(ID); } static bool classof(const Type *T) { return T->getTypeClass() == Using; } }; @@ -4813,19 +5667,20 @@ public: /// extension) or a `typeof_unqual` expression (a C23 feature). class TypeOfExprType : public Type { Expr *TOExpr; + const ASTContext &Context; protected: friend class ASTContext; // ASTContext creates these. - TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can = QualType()); + TypeOfExprType(const ASTContext &Context, Expr *E, TypeOfKind Kind, + QualType Can = QualType()); public: Expr *getUnderlyingExpr() const { return TOExpr; } /// Returns the kind of 'typeof' type this is. TypeOfKind getKind() const { - return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified - : TypeOfKind::Qualified; + return static_cast(TypeOfBits.Kind); } /// Remove a single level of sugar. @@ -4846,7 +5701,8 @@ public: class DependentTypeOfExprType : public TypeOfExprType, public llvm::FoldingSetNode { public: - DependentTypeOfExprType(Expr *E, TypeOfKind Kind) : TypeOfExprType(E, Kind) {} + DependentTypeOfExprType(const ASTContext &Context, Expr *E, TypeOfKind Kind) + : TypeOfExprType(Context, E, Kind) {} void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { Profile(ID, Context, getUnderlyingExpr(), @@ -4863,32 +5719,23 @@ class TypeOfType : public Type { friend class ASTContext; // ASTContext creates these. QualType TOType; + const ASTContext &Context; - TypeOfType(QualType T, QualType Can, TypeOfKind Kind) - : Type(TypeOf, - Kind == TypeOfKind::Unqualified ? Can.getAtomicUnqualifiedType() - : Can, - T->getDependence()), - TOType(T) { - TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified; - } + TypeOfType(const ASTContext &Context, QualType T, QualType Can, + TypeOfKind Kind); public: QualType getUnmodifiedType() const { return TOType; } /// Remove a single level of sugar. - QualType desugar() const { - QualType QT = getUnmodifiedType(); - return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType() : QT; - } + QualType desugar() const; /// Returns whether this type directly provides sugar. bool isSugared() const { return true; } /// Returns the kind of 'typeof' type this is. TypeOfKind getKind() const { - return TypeOfBits.IsUnqual ? TypeOfKind::Unqualified - : TypeOfKind::Qualified; + return static_cast(TypeOfBits.Kind); } static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } @@ -4935,6 +5782,73 @@ public: Expr *E); }; +class PackIndexingType final + : public Type, + public llvm::FoldingSetNode, + private llvm::TrailingObjects { + friend TrailingObjects; + + const ASTContext &Context; + QualType Pattern; + Expr *IndexExpr; + + unsigned Size; + +protected: + friend class ASTContext; // ASTContext creates these. + PackIndexingType(const ASTContext &Context, QualType Canonical, + QualType Pattern, Expr *IndexExpr, + ArrayRef Expansions = {}); + +public: + Expr *getIndexExpr() const { return IndexExpr; } + QualType getPattern() const { return Pattern; } + + bool isSugared() const { return hasSelectedType(); } + + QualType desugar() const { + if (hasSelectedType()) + return getSelectedType(); + return QualType(this, 0); + } + + QualType getSelectedType() const { + assert(hasSelectedType() && "Type is dependant"); + return *(getExpansionsPtr() + *getSelectedIndex()); + } + + std::optional getSelectedIndex() const; + + bool hasSelectedType() const { return getSelectedIndex() != std::nullopt; } + + ArrayRef getExpansions() const { + return {getExpansionsPtr(), Size}; + } + + static bool classof(const Type *T) { + return T->getTypeClass() == PackIndexing; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + if (hasSelectedType()) + getSelectedType().Profile(ID); + else + Profile(ID, Context, getPattern(), getIndexExpr()); + } + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + QualType Pattern, Expr *E); + +private: + const QualType *getExpansionsPtr() const { + return getTrailingObjects(); + } + + static TypeDependence computeDependence(QualType Pattern, Expr *IndexExpr, + ArrayRef Expansions = {}); + + unsigned numTrailingObjects(OverloadToken) const { return Size; } +}; + /// A unary type transform, which is a type constructed from another. class UnaryTransformType : public Type { public: @@ -5507,30 +6421,27 @@ class DeducedTemplateSpecializationType : public DeducedType, DeducedTemplateSpecializationType(TemplateName Template, QualType DeducedAsType, - bool IsDeducedAsDependent) + bool IsDeducedAsDependent, QualType Canon) : DeducedType(DeducedTemplateSpecialization, DeducedAsType, toTypeDependence(Template.getDependence()) | (IsDeducedAsDependent ? TypeDependence::DependentInstantiation : TypeDependence::None), - DeducedAsType.isNull() ? QualType(this, 0) - : DeducedAsType.getCanonicalType()), + Canon), Template(Template) {} public: /// Retrieve the name of the template that we are deducing. TemplateName getTemplateName() const { return Template;} - void Profile(llvm::FoldingSetNodeID &ID) { + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, getTemplateName(), getDeducedType(), isDependentType()); } static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template, QualType Deduced, bool IsDependent) { Template.Profile(ID); - QualType CanonicalType = - Deduced.isNull() ? Deduced : Deduced.getCanonicalType(); - ID.AddPointer(CanonicalType.getAsOpaquePtr()); + Deduced.Profile(ID); ID.AddBoolean(IsDependent || Template.isDependent()); } @@ -6898,7 +7809,8 @@ inline bool QualType::isCanonicalAsParam() const { if (T->isVariablyModifiedType() && T->hasSizedVLAType()) return false; - return !isa(T) && !isa(T); + return !isa(T) && + (!isa(T) || isa(T)); } inline bool QualType::isConstQualified() const { @@ -7089,6 +8001,8 @@ inline bool Type::isAnyPointerType() const { return isPointerType() || isObjCObjectPointerType(); } +inline bool Type::isSignableType() const { return isPointerType(); } + inline bool Type::isBlockPointerType() const { return isa(CanonicalType); } @@ -7163,6 +8077,10 @@ inline bool Type::isVariableArrayType() const { return isa(CanonicalType); } +inline bool Type::isArrayParameterType() const { + return isa(CanonicalType); +} + inline bool Type::isDependentSizedArrayType() const { return isa(CanonicalType); } @@ -7197,6 +8115,10 @@ inline bool Type::isExtVectorBoolType() const { return cast(CanonicalType)->getElementType()->isBooleanType(); } +inline bool Type::isSubscriptableVectorType() const { + return isVectorType() || isSveVLSBuiltinType(); +} + inline bool Type::isMatrixType() const { return isa(CanonicalType); } @@ -7383,6 +8305,14 @@ inline bool Type::isFloat16Type() const { return isSpecificBuiltinType(BuiltinType::Float16); } +inline bool Type::isFloat32Type() const { + return isSpecificBuiltinType(BuiltinType::Float); +} + +inline bool Type::isDoubleType() const { + return isSpecificBuiltinType(BuiltinType::Double); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } @@ -7427,6 +8357,10 @@ inline bool Type::isFixedPointOrIntegerType() const { return isFixedPointType() || isIntegerType(); } +inline bool Type::isConvertibleToFixedPointType() const { + return isRealFloatingType() || isFixedPointOrIntegerType(); +} + inline bool Type::isSaturatedFixedPointType() const { if (const auto *BT = dyn_cast(CanonicalType)) { return BT->getKind() >= BuiltinType::SatShortAccum && @@ -7500,7 +8434,10 @@ inline bool Type::isUndeducedType() const { /// Determines whether this is a type for which one can define /// an overloaded operator. inline bool Type::isOverloadableType() const { - return isDependentType() || isRecordType() || isEnumeralType(); + if (!CanonicalType->isDependentType()) + return isRecordType() || isEnumeralType(); + return !isArrayType() && !isFunctionType() && !isAnyPointerType() && + !isMemberPointerType(); } /// Determines whether this type is written as a typedef-name. @@ -7514,7 +8451,7 @@ inline bool Type::isTypedefNameType() const { /// Determines whether this type can decay to a pointer type. inline bool Type::canDecayToPointerType() const { - return isFunctionType() || isArrayType(); + return isFunctionType() || (isArrayType() && !isArrayParameterType()); } inline bool Type::hasPointerRepresentation() const { @@ -7681,6 +8618,18 @@ QualType DecayedType::getPointeeType() const { void FixedPointValueToString(SmallVectorImpl &Str, llvm::APSInt Val, unsigned Scale); +inline FunctionEffectsRef FunctionEffectsRef::get(QualType QT) { + while (true) { + QualType Pointee = QT->getPointeeType(); + if (Pointee.isNull()) + break; + QT = Pointee; + } + if (const auto *FPT = QT->getAs()) + return FPT->getFunctionEffects(); + return {}; +} + } // namespace clang #endif // LLVM_CLANG_AST_TYPE_H diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h b/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h index 471deb14aba..9f2dff7a782 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h +++ b/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h @@ -189,6 +189,9 @@ public: /// pointer types, but not through decltype or typedefs. AutoTypeLoc getContainedAutoTypeLoc() const; + /// Get the SourceLocation of the template keyword (if any). + SourceLocation getTemplateKeywordLoc() const; + /// Initializes this to state that every location in this /// type is the given location. /// @@ -229,6 +232,9 @@ public: /// __nullable, or __null_unspecifier), if there is one. SourceLocation findNullabilityLoc() const; + void dump() const; + void dump(llvm::raw_ostream &, const ASTContext &) const; + private: static bool isKind(const TypeLoc&) { return true; @@ -884,6 +890,10 @@ public: return getInnerTypeLoc(); } + TypeLoc getEquivalentTypeLoc() const { + return TypeLoc(getTypePtr()->getEquivalentType(), getNonLocalData()); + } + /// The type attribute. const Attr *getAttr() const { return getLocalData()->TypeAttr; @@ -1110,6 +1120,32 @@ public: } }; +struct BoundsAttributedLocInfo {}; +class BoundsAttributedTypeLoc + : public ConcreteTypeLoc { +public: + TypeLoc getInnerLoc() const { return getInnerTypeLoc(); } + QualType getInnerType() const { return getTypePtr()->desugar(); } + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + // nothing to do + } + // LocalData is empty and TypeLocBuilder doesn't handle DataSize 1. + unsigned getLocalDataSize() const { return 0; } +}; + +class CountAttributedTypeLoc final + : public InheritingConcreteTypeLoc { +public: + Expr *getCountExpr() const { return getTypePtr()->getCountExpr(); } + bool isCountInBytes() const { return getTypePtr()->isCountInBytes(); } + bool isOrNull() const { return getTypePtr()->isOrNull(); } + + SourceRange getLocalSourceRange() const; +}; + struct MacroQualifiedLocInfo { SourceLocation ExpansionLoc; }; @@ -1575,6 +1611,11 @@ class ConstantArrayTypeLoc : ConstantArrayType> { }; +/// Wrapper for source info for array parameter types. +class ArrayParameterTypeLoc + : public InheritingConcreteTypeLoc< + ConstantArrayTypeLoc, ArrayParameterTypeLoc, ArrayParameterType> {}; + class IncompleteArrayTypeLoc : public InheritingConcreteTypeLoc { + +public: + Expr *getIndexExpr() const { return getTypePtr()->getIndexExpr(); } + QualType getPattern() const { return getTypePtr()->getPattern(); } + + SourceLocation getEllipsisLoc() const { return getLocalData()->EllipsisLoc; } + void setEllipsisLoc(SourceLocation Loc) { getLocalData()->EllipsisLoc = Loc; } + + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setEllipsisLoc(Loc); + } + + TypeLoc getPatternLoc() const { return getInnerTypeLoc(); } + + QualType getInnerType() const { return this->getTypePtr()->getPattern(); } + + SourceRange getLocalSourceRange() const { + return SourceRange(getEllipsisLoc(), getEllipsisLoc()); + } +}; + struct UnaryTransformTypeLocInfo { // FIXME: While there's only one unary transform right now, future ones may // need different representations diff --git a/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td b/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td index 682c869b0c5..7d4353c2773 100644 --- a/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td +++ b/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td @@ -25,6 +25,25 @@ let Class = PointerType in { def : Creator<[{ return ctx.getPointerType(pointeeType); }]>; } +let Class = CountAttributedType in { + def : Property<"WrappedTy", QualType> { + let Read = [{ node->desugar() }]; + } + def : Property<"CountExpr", ExprRef> { + let Read = [{ node->getCountExpr() }]; + } + def : Property<"CountInBytes", Bool> { + let Read = [{ node->isCountInBytes() }]; + } + def : Property<"OrNull", Bool> { + let Read = [{ node->isOrNull() }]; + } + def : Property<"CoupledDecls", Array> { + let Read = [{ node->getCoupledDecls() }]; + } + def : Creator<[{ return ctx.getCountAttributedType(WrappedTy, CountExpr, CountInBytes, OrNull, CoupledDecls); }]>; +} + let Class = AdjustedType in { def : Property<"originalType", QualType> { let Read = [{ node->getOriginalType() }]; @@ -117,6 +136,13 @@ let Class = ConstantArrayType in { }]>; } +let Class = ArrayParameterType in { + def : Creator<[{ return ctx.getAdjustedParameterType( + ctx.getConstantArrayType(elementType,sizeValue, + size,sizeModifier, + indexQualifiers.getCVRQualifiers())); }]>; +} + let Class = IncompleteArrayType in { def : Creator<[{ return ctx.getIncompleteArrayType(elementType, sizeModifier, @@ -326,6 +352,12 @@ let Class = FunctionProtoType in { def : Property<"AArch64SMEAttributes", UInt32> { let Read = [{ node->getAArch64SMEAttributes() }]; } + def : Property<"functionEffects", Array> { + let Read = [{ node->getFunctionEffectsWithoutConditions() }]; + } + def : Property<"functionEffectConds", Array> { + let Read = [{ node->getFunctionEffectConditions() }]; + } def : Creator<[{ auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm, @@ -342,6 +374,7 @@ let Class = FunctionProtoType in { epi.ExtParameterInfos = extParameterInfo.empty() ? nullptr : extParameterInfo.data(); epi.AArch64SMEAttributes = AArch64SMEAttributes; + epi.FunctionEffects = FunctionEffectsRef::create(functionEffects, functionEffectConds); return ctx.getFunctionType(returnType, parameters, epi); }]>; } @@ -433,6 +466,20 @@ let Class = DecltypeType in { }]>; } +let Class = PackIndexingType in { + def : Property<"pattern", QualType> { + let Read = [{ node->getPattern() }]; + } + def : Property<"indexExpression", ExprRef> { + let Read = [{ node->getIndexExpr() }]; + } + + def : Creator<[{ + return ctx.getPackIndexingType(pattern, indexExpression); + }]>; +} + + let Class = UnaryTransformType in { def : Property<"baseType", QualType> { let Read = [{ node->getBaseType() }]; @@ -821,6 +868,10 @@ let Class = BuiltinType in { case BuiltinType::ID: return ctx.SINGLETON_ID; #include "clang/Basic/WebAssemblyReferenceTypes.def" +#define AMDGPU_TYPE(NAME, ID, SINGLETON_ID) \ + case BuiltinType::ID: return ctx.SINGLETON_ID; +#include "clang/Basic/AMDGPUTypes.def" + #define BUILTIN_TYPE(ID, SINGLETON_ID) \ case BuiltinType::ID: return ctx.SINGLETON_ID; #include "clang/AST/BuiltinTypes.def" diff --git a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h b/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h index ee31be969b6..1369725ab4e 100644 --- a/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h +++ b/contrib/llvm-project/clang/include/clang/AST/UnresolvedSet.h @@ -47,6 +47,7 @@ public: // temporaries with defaulted ctors are not zero initialized. UnresolvedSetIterator() : iterator_adaptor_base(nullptr) {} + uint64_t getDeclID() const { return I->getDeclID(); } NamedDecl *getDecl() const { return I->getDecl(); } void setDecl(NamedDecl *ND) const { return I->setDecl(ND); } AccessSpecifier getAccess() const { return I->getAccess(); } diff --git a/contrib/llvm-project/clang/include/clang/AST/VTTBuilder.h b/contrib/llvm-project/clang/include/clang/AST/VTTBuilder.h index 4acbc1f9e96..3c19e61a870 100644 --- a/contrib/llvm-project/clang/include/clang/AST/VTTBuilder.h +++ b/contrib/llvm-project/clang/include/clang/AST/VTTBuilder.h @@ -92,7 +92,7 @@ class VTTBuilder { using AddressPointsMapTy = llvm::DenseMap; /// The sub-VTT indices for the bases of the most derived class. - llvm::DenseMap SubVTTIndicies; + llvm::DenseMap SubVTTIndices; /// The secondary virtual pointer indices of all subobjects of /// the most derived class. @@ -148,8 +148,8 @@ public: } /// Returns a reference to the sub-VTT indices. - const llvm::DenseMap &getSubVTTIndicies() const { - return SubVTTIndicies; + const llvm::DenseMap &getSubVTTIndices() const { + return SubVTTIndices; } /// Returns a reference to the secondary virtual pointer indices. diff --git a/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h index fbf6c041a1e..a5de41dbc22 100644 --- a/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h +++ b/contrib/llvm-project/clang/include/clang/AST/VTableBuilder.h @@ -361,6 +361,10 @@ public: }; class ItaniumVTableContext : public VTableContextBase { +public: + typedef llvm::DenseMap + OriginalMethodMapTy; + private: /// Contains the index (relative to the vtable address point) @@ -384,6 +388,10 @@ private: VirtualBaseClassOffsetOffsetsMapTy; VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets; + /// Map from a virtual method to the nearest method in the primary base class + /// chain that it overrides. + OriginalMethodMapTy OriginalMethodMap; + void computeVTableRelatedInformation(const CXXRecordDecl *RD) override; public: @@ -425,6 +433,27 @@ public: CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase); + /// Return the method that added the v-table slot that will be used to call + /// the given method. + /// + /// In the Itanium ABI, where overrides always cause methods to be added to + /// the primary v-table if they're not already there, this will be the first + /// declaration in the primary base class chain for which the return type + /// adjustment is trivial. + GlobalDecl findOriginalMethod(GlobalDecl GD); + + const CXXMethodDecl *findOriginalMethodInMap(const CXXMethodDecl *MD) const; + + void setOriginalMethod(const CXXMethodDecl *Key, const CXXMethodDecl *Val) { + OriginalMethodMap[Key] = Val; + } + + /// This method is reserved for the implementation and shouldn't be used + /// directly. + const OriginalMethodMapTy &getOriginalMethodMap() { + return OriginalMethodMap; + } + static bool classof(const VTableContextBase *VT) { return !VT->isMicrosoft(); } diff --git a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h index dc1f49525a0..ca44c3ee085 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -764,9 +764,9 @@ AST_POLYMORPHIC_MATCHER(isImplicit, return Node.isImplicit(); } -/// Matches classTemplateSpecializations, templateSpecializationType and -/// functionDecl that have at least one TemplateArgument matching the given -/// InnerMatcher. +/// Matches templateSpecializationTypes, class template specializations, +/// variable template specializations, and function template specializations +/// that have at least one TemplateArgument matching the given InnerMatcher. /// /// Given /// \code @@ -788,8 +788,8 @@ AST_POLYMORPHIC_MATCHER(isImplicit, AST_POLYMORPHIC_MATCHER_P( hasAnyTemplateArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, - TemplateSpecializationType, - FunctionDecl), + VarTemplateSpecializationDecl, FunctionDecl, + TemplateSpecializationType), internal::Matcher, InnerMatcher) { ArrayRef List = internal::getTemplateSpecializationArgs(Node); @@ -1047,8 +1047,9 @@ AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); } /// expr(isValueDependent()) matches return Size AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); } -/// Matches classTemplateSpecializations, templateSpecializationType and -/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher. +/// Matches templateSpecializationType, class template specializations, +/// variable template specializations, and function template specializations +/// where the n'th TemplateArgument matches the given InnerMatcher. /// /// Given /// \code @@ -1068,8 +1069,8 @@ AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); } AST_POLYMORPHIC_MATCHER_P2( hasTemplateArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, - TemplateSpecializationType, - FunctionDecl), + VarTemplateSpecializationDecl, FunctionDecl, + TemplateSpecializationType), unsigned, N, internal::Matcher, InnerMatcher) { ArrayRef List = internal::getTemplateSpecializationArgs(Node); @@ -4066,7 +4067,7 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// Matcher, Matcher, /// Matcher, Matcher, /// Matcher, -/// Matcher, Matcher, +/// Matcher, /// Matcher, Matcher, /// Matcher, Matcher, /// Matcher @@ -4075,9 +4076,8 @@ AST_POLYMORPHIC_MATCHER_P( AST_POLYMORPHIC_SUPPORTED_TYPES( BlockDecl, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr, CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr, - ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl, - ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc, - TypedefNameDecl), + CompoundLiteralExpr, DeclaratorDecl, ExplicitCastExpr, ObjCPropertyDecl, + TemplateArgumentLoc, TypedefNameDecl), internal::Matcher, Inner) { TypeSourceInfo *source = internal::GetTypeSourceInfo(Node); if (source == nullptr) { @@ -4580,8 +4580,7 @@ AST_POLYMORPHIC_MATCHER_P2(hasArgument, /// return (args * ... * 1); /// } /// \endcode -AST_MATCHER_P(CXXFoldExpr, hasFoldInit, ast_matchers::internal::Matcher, - InnerMacher) { +AST_MATCHER_P(CXXFoldExpr, hasFoldInit, internal::Matcher, InnerMacher) { const auto *const Init = Node.getInit(); return Init && InnerMacher.matches(*Init, Finder, Builder); } @@ -4603,8 +4602,7 @@ AST_MATCHER_P(CXXFoldExpr, hasFoldInit, ast_matchers::internal::Matcher, /// return (args * ... * 1); /// } /// \endcode -AST_MATCHER_P(CXXFoldExpr, hasPattern, ast_matchers::internal::Matcher, - InnerMacher) { +AST_MATCHER_P(CXXFoldExpr, hasPattern, internal::Matcher, InnerMacher) { const Expr *const Pattern = Node.getPattern(); return Pattern && InnerMacher.matches(*Pattern, Finder, Builder); } @@ -4685,8 +4683,8 @@ AST_MATCHER(CXXFoldExpr, isBinaryFold) { return Node.getInit() != nullptr; } /// \code /// int x{y}. /// \endcode -AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N, - ast_matchers::internal::Matcher, InnerMatcher) { +AST_MATCHER_P2(InitListExpr, hasInit, unsigned, N, internal::Matcher, + InnerMatcher) { return N < Node.getNumInits() && InnerMatcher.matches(*Node.getInit(N), Finder, Builder); } @@ -4963,6 +4961,8 @@ AST_MATCHER_P(LambdaExpr, hasAnyCapture, internal::Matcher, /// capturesVar(hasName("x")) matches `x` and `x = 1`. AST_MATCHER_P(LambdaCapture, capturesVar, internal::Matcher, InnerMatcher) { + if (!Node.capturesVariable()) + return false; auto *capturedVar = Node.getCapturedVar(); return capturedVar && InnerMatcher.matches(*capturedVar, Finder, Builder); } @@ -5034,6 +5034,25 @@ AST_POLYMORPHIC_MATCHER_P2(hasParameter, && InnerMatcher.matches(*Node.parameters()[N], Finder, Builder)); } +/// Matches if the given method declaration declares a member function with an +/// explicit object parameter. +/// +/// Given +/// \code +/// struct A { +/// int operator-(this A, int); +/// void fun(this A &&self); +/// static int operator()(int); +/// int operator+(int); +/// }; +/// \endcode +/// +/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two +/// methods but not the last two. +AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) { + return Node.isExplicitObjectMemberFunction(); +} + /// Matches all arguments and their respective ParmVarDecl. /// /// Given @@ -5062,10 +5081,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, // argument of the method which should not be matched against a parameter, so // we skip over it here. BoundNodesTreeBuilder Matches; - unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl())) - .matches(Node, Finder, &Matches) - ? 1 - : 0; + unsigned ArgIndex = + cxxOperatorCallExpr( + callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction())))) + .matches(Node, Finder, &Matches) + ? 1 + : 0; int ParamIndex = 0; bool Matched = false; for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) { @@ -5123,11 +5144,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType, // argument of the method which should not be matched against a parameter, so // we skip over it here. BoundNodesTreeBuilder Matches; - unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl())) - .matches(Node, Finder, &Matches) - ? 1 - : 0; - + unsigned ArgIndex = + cxxOperatorCallExpr( + callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction())))) + .matches(Node, Finder, &Matches) + ? 1 + : 0; const FunctionProtoType *FProto = nullptr; if (const auto *Call = dyn_cast(&Node)) { @@ -5282,9 +5304,10 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs, return Node.getNumParams() == N; } -/// Matches classTemplateSpecialization, templateSpecializationType and -/// functionDecl nodes where the template argument matches the inner matcher. -/// This matcher may produce multiple matches. +/// Matches templateSpecializationType, class template specialization, +/// variable template specialization, and function template specialization +/// nodes where the template argument matches the inner matcher. This matcher +/// may produce multiple matches. /// /// Given /// \code @@ -5308,8 +5331,9 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs, AST_POLYMORPHIC_MATCHER_P( forEachTemplateArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, - TemplateSpecializationType, FunctionDecl), - clang::ast_matchers::internal::Matcher, InnerMatcher) { + VarTemplateSpecializationDecl, FunctionDecl, + TemplateSpecializationType), + internal::Matcher, InnerMatcher) { ArrayRef TemplateArgs = clang::ast_matchers::internal::getTemplateSpecializationArgs(Node); clang::ast_matchers::internal::BoundNodesTreeBuilder Result; @@ -6883,8 +6907,10 @@ extern const internal::VariadicDynCastAllOfMatcher< TypeLoc, TemplateSpecializationTypeLoc> templateSpecializationTypeLoc; -/// Matches template specialization `TypeLoc`s that have at least one -/// `TemplateArgumentLoc` matching the given `InnerMatcher`. +/// Matches template specialization `TypeLoc`s, class template specializations, +/// variable template specializations, and function template specializations +/// that have at least one `TemplateArgumentLoc` matching the given +/// `InnerMatcher`. /// /// Given /// \code @@ -6894,20 +6920,21 @@ extern const internal::VariadicDynCastAllOfMatcher< /// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc( /// hasTypeLoc(loc(asString("int"))))))) /// matches `A a`. -AST_MATCHER_P(TemplateSpecializationTypeLoc, hasAnyTemplateArgumentLoc, - internal::Matcher, InnerMatcher) { - for (unsigned Index = 0, N = Node.getNumArgs(); Index < N; ++Index) { - clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); - if (InnerMatcher.matches(Node.getArgLoc(Index), Finder, &Result)) { - *Builder = std::move(Result); - return true; - } - } +AST_POLYMORPHIC_MATCHER_P( + hasAnyTemplateArgumentLoc, + AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, + VarTemplateSpecializationDecl, FunctionDecl, + DeclRefExpr, TemplateSpecializationTypeLoc), + internal::Matcher, InnerMatcher) { + auto Args = internal::getTemplateArgsWritten(Node); + return matchesFirstInRange(InnerMatcher, Args.begin(), Args.end(), Finder, + Builder) != Args.end(); return false; } -/// Matches template specialization `TypeLoc`s where the n'th -/// `TemplateArgumentLoc` matches the given `InnerMatcher`. +/// Matches template specialization `TypeLoc`s, class template specializations, +/// variable template specializations, and function template specializations +/// where the n'th `TemplateArgumentLoc` matches the given `InnerMatcher`. /// /// Given /// \code @@ -6920,10 +6947,13 @@ AST_MATCHER_P(TemplateSpecializationTypeLoc, hasAnyTemplateArgumentLoc, /// matches `A b`, but not `A c`. AST_POLYMORPHIC_MATCHER_P2( hasTemplateArgumentLoc, - AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, TemplateSpecializationTypeLoc), + AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, + VarTemplateSpecializationDecl, FunctionDecl, + DeclRefExpr, TemplateSpecializationTypeLoc), unsigned, Index, internal::Matcher, InnerMatcher) { - return internal::MatchTemplateArgLocAt(Node, Index, InnerMatcher, Finder, - Builder); + auto Args = internal::getTemplateArgsWritten(Node); + return Index < Args.size() && + InnerMatcher.matches(Args[Index], Finder, Builder); } /// Matches C or C++ elaborated `TypeLoc`s. @@ -8341,20 +8371,28 @@ AST_MATCHER_P(Stmt, forCallable, internal::Matcher, InnerMatcher) { const auto &CurNode = Stack.back(); Stack.pop_back(); if (const auto *FuncDeclNode = CurNode.get()) { - if (InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) { + BoundNodesTreeBuilder B = *Builder; + if (InnerMatcher.matches(*FuncDeclNode, Finder, &B)) { + *Builder = std::move(B); return true; } } else if (const auto *LambdaExprNode = CurNode.get()) { + BoundNodesTreeBuilder B = *Builder; if (InnerMatcher.matches(*LambdaExprNode->getCallOperator(), Finder, - Builder)) { + &B)) { + *Builder = std::move(B); return true; } } else if (const auto *ObjCMethodDeclNode = CurNode.get()) { - if (InnerMatcher.matches(*ObjCMethodDeclNode, Finder, Builder)) { + BoundNodesTreeBuilder B = *Builder; + if (InnerMatcher.matches(*ObjCMethodDeclNode, Finder, &B)) { + *Builder = std::move(B); return true; } } else if (const auto *BlockDeclNode = CurNode.get()) { - if (InnerMatcher.matches(*BlockDeclNode, Finder, Builder)) { + BoundNodesTreeBuilder B = *Builder; + if (InnerMatcher.matches(*BlockDeclNode, Finder, &B)) { + *Builder = std::move(B); return true; } } else { @@ -8525,8 +8563,8 @@ AST_MATCHER(FunctionDecl, hasTrailingReturn) { /// /// ``varDecl(hasInitializer(ignoringElidableConstructorCall(callExpr())))`` /// matches ``H D = G()`` in C++11 through C++17 (and beyond). -AST_MATCHER_P(Expr, ignoringElidableConstructorCall, - ast_matchers::internal::Matcher, InnerMatcher) { +AST_MATCHER_P(Expr, ignoringElidableConstructorCall, internal::Matcher, + InnerMatcher) { // E tracks the node that we are examining. const Expr *E = &Node; // If present, remove an outer `ExprWithCleanups` corresponding to the diff --git a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index 47d912c73dd..c1cc63fdb74 100644 --- a/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/contrib/llvm-project/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -186,10 +186,6 @@ inline TypeSourceInfo *GetTypeSourceInfo(const BlockDecl &Node) { inline TypeSourceInfo *GetTypeSourceInfo(const CXXNewExpr &Node) { return Node.getAllocatedTypeSourceInfo(); } -inline TypeSourceInfo * -GetTypeSourceInfo(const ClassTemplateSpecializationDecl &Node) { - return Node.getTypeAsWritten(); -} /// Unifies obtaining the FunctionProtoType pointer from both /// FunctionProtoType and FunctionDecl nodes.. @@ -1939,6 +1935,11 @@ getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) { return D.getTemplateArgs().asArray(); } +inline ArrayRef +getTemplateSpecializationArgs(const VarTemplateSpecializationDecl &D) { + return D.getTemplateArgs().asArray(); +} + inline ArrayRef getTemplateSpecializationArgs(const TemplateSpecializationType &T) { return T.template_arguments(); @@ -1948,7 +1949,46 @@ inline ArrayRef getTemplateSpecializationArgs(const FunctionDecl &FD) { if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs()) return TemplateArgs->asArray(); - return ArrayRef(); + return std::nullopt; +} + +inline ArrayRef +getTemplateArgsWritten(const ClassTemplateSpecializationDecl &D) { + if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten()) + return Args->arguments(); + return std::nullopt; +} + +inline ArrayRef +getTemplateArgsWritten(const VarTemplateSpecializationDecl &D) { + if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten()) + return Args->arguments(); + return std::nullopt; +} + +inline ArrayRef +getTemplateArgsWritten(const FunctionDecl &FD) { + if (const auto *Args = FD.getTemplateSpecializationArgsAsWritten()) + return Args->arguments(); + return std::nullopt; +} + +inline ArrayRef +getTemplateArgsWritten(const DeclRefExpr &DRE) { + if (const auto *Args = DRE.getTemplateArgs()) + return {Args, DRE.getNumTemplateArgs()}; + return std::nullopt; +} + +inline SmallVector +getTemplateArgsWritten(const TemplateSpecializationTypeLoc &T) { + SmallVector Args; + if (!T.isNull()) { + Args.reserve(T.getNumArgs()); + for (unsigned I = 0; I < T.getNumArgs(); ++I) + Args.emplace_back(T.getArgLoc(I)); + } + return Args; } struct NotEqualsBoundNodePredicate { diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h index 1ceef944fbc..117173ba9a0 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h @@ -8,11 +8,9 @@ #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H #define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H -#include - -#include "clang/AST/AST.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "llvm/ADT/DenseMap.h" +#include namespace clang { @@ -21,14 +19,74 @@ class FunctionParmMutationAnalyzer; /// Analyzes whether any mutative operations are applied to an expression within /// a given statement. class ExprMutationAnalyzer { + friend class FunctionParmMutationAnalyzer; + public: + struct Memoized { + using ResultMap = llvm::DenseMap; + using FunctionParaAnalyzerMap = + llvm::SmallDenseMap>; + + ResultMap Results; + ResultMap PointeeResults; + FunctionParaAnalyzerMap FuncParmAnalyzer; + + void clear() { + Results.clear(); + PointeeResults.clear(); + FuncParmAnalyzer.clear(); + } + }; + struct Analyzer { + Analyzer(const Stmt &Stm, ASTContext &Context, Memoized &Memorized) + : Stm(Stm), Context(Context), Memorized(Memorized) {} + + const Stmt *findMutation(const Expr *Exp); + const Stmt *findMutation(const Decl *Dec); + + const Stmt *findPointeeMutation(const Expr *Exp); + const Stmt *findPointeeMutation(const Decl *Dec); + static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm, + ASTContext &Context); + + private: + using MutationFinder = const Stmt *(Analyzer::*)(const Expr *); + + const Stmt *findMutationMemoized(const Expr *Exp, + llvm::ArrayRef Finders, + Memoized::ResultMap &MemoizedResults); + const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder); + + bool isUnevaluated(const Expr *Exp); + + const Stmt *findExprMutation(ArrayRef Matches); + const Stmt *findDeclMutation(ArrayRef Matches); + const Stmt * + findExprPointeeMutation(ArrayRef Matches); + const Stmt * + findDeclPointeeMutation(ArrayRef Matches); + + const Stmt *findDirectMutation(const Expr *Exp); + const Stmt *findMemberMutation(const Expr *Exp); + const Stmt *findArrayElementMutation(const Expr *Exp); + const Stmt *findCastMutation(const Expr *Exp); + const Stmt *findRangeLoopMutation(const Expr *Exp); + const Stmt *findReferenceMutation(const Expr *Exp); + const Stmt *findFunctionArgMutation(const Expr *Exp); + + const Stmt &Stm; + ASTContext &Context; + Memoized &Memorized; + }; + ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context) - : Stm(Stm), Context(Context) {} + : Memorized(), A(Stm, Context, Memorized) {} bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; } bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; } - const Stmt *findMutation(const Expr *Exp); - const Stmt *findMutation(const Decl *Dec); + const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); } + const Stmt *findMutation(const Decl *Dec) { return A.findMutation(Dec); } bool isPointeeMutated(const Expr *Exp) { return findPointeeMutation(Exp) != nullptr; @@ -36,51 +94,40 @@ public: bool isPointeeMutated(const Decl *Dec) { return findPointeeMutation(Dec) != nullptr; } - const Stmt *findPointeeMutation(const Expr *Exp); - const Stmt *findPointeeMutation(const Decl *Dec); + const Stmt *findPointeeMutation(const Expr *Exp) { + return A.findPointeeMutation(Exp); + } + const Stmt *findPointeeMutation(const Decl *Dec) { + return A.findPointeeMutation(Dec); + } + static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm, - ASTContext &Context); + ASTContext &Context) { + return Analyzer::isUnevaluated(Smt, Stm, Context); + } private: - using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *); - using ResultMap = llvm::DenseMap; - - const Stmt *findMutationMemoized(const Expr *Exp, - llvm::ArrayRef Finders, - ResultMap &MemoizedResults); - const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder); - - bool isUnevaluated(const Expr *Exp); - - const Stmt *findExprMutation(ArrayRef Matches); - const Stmt *findDeclMutation(ArrayRef Matches); - const Stmt * - findExprPointeeMutation(ArrayRef Matches); - const Stmt * - findDeclPointeeMutation(ArrayRef Matches); - - const Stmt *findDirectMutation(const Expr *Exp); - const Stmt *findMemberMutation(const Expr *Exp); - const Stmt *findArrayElementMutation(const Expr *Exp); - const Stmt *findCastMutation(const Expr *Exp); - const Stmt *findRangeLoopMutation(const Expr *Exp); - const Stmt *findReferenceMutation(const Expr *Exp); - const Stmt *findFunctionArgMutation(const Expr *Exp); - - const Stmt &Stm; - ASTContext &Context; - llvm::DenseMap> - FuncParmAnalyzer; - ResultMap Results; - ResultMap PointeeResults; + Memoized Memorized; + Analyzer A; }; // A convenient wrapper around ExprMutationAnalyzer for analyzing function // params. class FunctionParmMutationAnalyzer { public: - FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context); + static FunctionParmMutationAnalyzer * + getFunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context, + ExprMutationAnalyzer::Memoized &Memorized) { + auto it = Memorized.FuncParmAnalyzer.find(&Func); + if (it == Memorized.FuncParmAnalyzer.end()) + it = + Memorized.FuncParmAnalyzer + .try_emplace(&Func, std::unique_ptr( + new FunctionParmMutationAnalyzer( + Func, Context, Memorized))) + .first; + return it->getSecond().get(); + } bool isMutated(const ParmVarDecl *Parm) { return findMutation(Parm) != nullptr; @@ -88,8 +135,11 @@ public: const Stmt *findMutation(const ParmVarDecl *Parm); private: - ExprMutationAnalyzer BodyAnalyzer; + ExprMutationAnalyzer::Analyzer BodyAnalyzer; llvm::DenseMap Results; + + FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context, + ExprMutationAnalyzer::Memoized &Memorized); }; } // namespace clang diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h index 4356834adf7..c4998bb2285 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h @@ -70,7 +70,41 @@ public: }; private: - using po_iterator = llvm::po_iterator; + // The CFG orders the blocks of loop bodies before those of loop successors + // (both numerically, and in the successor order of the loop condition + // block). So, RPO necessarily reverses that order, placing the loop successor + // *before* the loop body. For many analyses, particularly those that converge + // to a fixpoint, this results in potentially significant extra work because + // loop successors will necessarily need to be reconsidered once the algorithm + // has reached a fixpoint on the loop body. + // + // This definition of CFG graph traits reverses the order of children, so that + // loop bodies will come first in an RPO. + struct CFGLoopBodyFirstTraits { + using NodeRef = const ::clang::CFGBlock *; + using ChildIteratorType = ::clang::CFGBlock::const_succ_reverse_iterator; + + static ChildIteratorType child_begin(NodeRef N) { return N->succ_rbegin(); } + static ChildIteratorType child_end(NodeRef N) { return N->succ_rend(); } + + using nodes_iterator = ::clang::CFG::const_iterator; + + static NodeRef getEntryNode(const ::clang::CFG *F) { + return &F->getEntry(); + } + + static nodes_iterator nodes_begin(const ::clang::CFG *F) { + return F->nodes_begin(); + } + + static nodes_iterator nodes_end(const ::clang::CFG *F) { + return F->nodes_end(); + } + + static unsigned size(const ::clang::CFG *F) { return F->size(); } + }; + using po_iterator = + llvm::po_iterator; std::vector Blocks; using BlockOrderTy = llvm::DenseMap; diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 13e37ac2b56..e99c5b24663 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -330,9 +330,9 @@ public: bool shouldIgnore() const { return sexpr() == nullptr; } - bool isInvalid() const { return sexpr() && isa(sexpr()); } + bool isInvalid() const { return isa_and_nonnull(sexpr()); } - bool isUniversal() const { return sexpr() && isa(sexpr()); } + bool isUniversal() const { return isa_and_nonnull(sexpr()); } }; // Translate clang::Expr to til::SExpr. @@ -527,8 +527,10 @@ private: BlockInfo *CurrentBlockInfo = nullptr; }; +#ifndef NDEBUG // Dump an SCFG to llvm::errs(). void printSCFG(CFGWalker &Walker); +#endif // NDEBUG } // namespace threadSafety } // namespace clang diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h index b28f2c6b99c..228b4ae1e3e 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h @@ -16,6 +16,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/Stmt.h" +#include "clang/Basic/SourceLocation.h" #include "llvm/Support/Debug.h" namespace clang { @@ -41,6 +42,43 @@ public: virtual VarGrpRef getGroupOfParms() const =0; }; +// FixitStrategy is a map from variables to the way we plan to emit fixes for +// these variables. It is figured out gradually by trying different fixes +// for different variables depending on gadgets in which these variables +// participate. +class FixitStrategy { +public: + enum class Kind { + Wontfix, // We don't plan to emit a fixit for this variable. + Span, // We recommend replacing the variable with std::span. + Iterator, // We recommend replacing the variable with std::span::iterator. + Array, // We recommend replacing the variable with std::array. + Vector // We recommend replacing the variable with std::vector. + }; + +private: + using MapTy = llvm::DenseMap; + + MapTy Map; + +public: + FixitStrategy() = default; + FixitStrategy(const FixitStrategy &) = delete; // Let's avoid copies. + FixitStrategy &operator=(const FixitStrategy &) = delete; + FixitStrategy(FixitStrategy &&) = default; + FixitStrategy &operator=(FixitStrategy &&) = default; + + void set(const VarDecl *VD, Kind K) { Map[VD] = K; } + + Kind lookup(const VarDecl *VD) const { + auto I = Map.find(VD); + if (I == Map.end()) + return Kind::Wontfix; + + return I->second; + } +}; + /// The interface that lets the caller handle unsafe buffer usage analysis /// results by overriding this class's handle... methods. class UnsafeBufferUsageHandler { @@ -68,15 +106,22 @@ public: virtual void handleUnsafeOperation(const Stmt *Operation, bool IsRelatedToDecl, ASTContext &Ctx) = 0; + /// Invoked when an unsafe operation with a std container is found. + virtual void handleUnsafeOperationInContainer(const Stmt *Operation, + bool IsRelatedToDecl, + ASTContext &Ctx) = 0; + /// Invoked when a fix is suggested against a variable. This function groups /// all variables that must be fixed together (i.e their types must be changed /// to the same target type to prevent type mismatches) into a single fixit. /// /// `D` is the declaration of the callable under analysis that owns `Variable` /// and all of its group mates. - virtual void handleUnsafeVariableGroup(const VarDecl *Variable, - const VariableGroupsManager &VarGrpMgr, - FixItList &&Fixes, const Decl *D) = 0; + virtual void + handleUnsafeVariableGroup(const VarDecl *Variable, + const VariableGroupsManager &VarGrpMgr, + FixItList &&Fixes, const Decl *D, + const FixitStrategy &VarTargetTypes) = 0; #ifndef NDEBUG public: @@ -98,9 +143,14 @@ public: #endif public: - /// Returns a reference to the `Preprocessor`: + /// \return true iff buffer safety is opt-out at `Loc`; false otherwise. virtual bool isSafeBufferOptOut(const SourceLocation &Loc) const = 0; + /// \return true iff unsafe uses in containers should NOT be reported at + /// `Loc`; false otherwise. + virtual bool + ignoreUnsafeBufferInContainer(const SourceLocation &Loc) const = 0; + virtual std::string getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc, StringRef WSSuffix = "") const = 0; diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def index c9766168836..242ad763ba6 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def +++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def @@ -18,6 +18,12 @@ #define WARNING_GADGET(name) GADGET(name) #endif +/// A `WARNING_GADGET` subset, where the code pattern of each gadget +/// corresponds uses of a (possibly hardened) contatiner (e.g., `std::span`). +#ifndef WARNING_CONTAINER_GADGET +#define WARNING_CONTAINER_GADGET(name) WARNING_GADGET(name) +#endif + /// Safe gadgets correspond to code patterns that aren't unsafe but need to be /// properly recognized in order to emit correct warnings and fixes over unsafe /// gadgets. @@ -30,7 +36,9 @@ WARNING_GADGET(Decrement) WARNING_GADGET(ArraySubscript) WARNING_GADGET(PointerArithmetic) WARNING_GADGET(UnsafeBufferUsageAttr) +WARNING_GADGET(UnsafeBufferUsageCtorAttr) WARNING_GADGET(DataInvocation) +WARNING_CONTAINER_GADGET(SpanTwoParamConstructor) // Uses of `std::span(arg0, arg1)` FIXABLE_GADGET(ULCArraySubscript) // `DRE[any]` in an Unspecified Lvalue Context FIXABLE_GADGET(DerefSimplePtrArithFixable) FIXABLE_GADGET(PointerDereference) @@ -38,9 +46,11 @@ FIXABLE_GADGET(UPCAddressofArraySubscript) // '&DRE[any]' in an Unspecified Poin FIXABLE_GADGET(UPCStandalonePointer) FIXABLE_GADGET(UPCPreIncrement) // '++Ptr' in an Unspecified Pointer Context FIXABLE_GADGET(UUCAddAssign) // 'Ptr += n' in an Unspecified Untyped Context -FIXABLE_GADGET(PointerAssignment) +FIXABLE_GADGET(PtrToPtrAssignment) +FIXABLE_GADGET(CArrayToPtrAssignment) FIXABLE_GADGET(PointerInit) #undef FIXABLE_GADGET #undef WARNING_GADGET +#undef WARNING_CONTAINER_GADGET #undef GADGET diff --git a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h b/contrib/llvm-project/clang/include/clang/Analysis/CFG.h index 9f776ca6cc2..a7ff38c786a 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/CFG.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/CFG.h @@ -879,6 +879,7 @@ private: /// /// Optimization Note: This bit could be profitably folded with Terminator's /// storage if the memory usage of CFGBlock becomes an issue. + LLVM_PREFERRED_TYPE(bool) unsigned HasNoReturnElement : 1; /// The parent CFG that owns this CFGBlock. @@ -1007,7 +1008,9 @@ public: class FilterOptions { public: + LLVM_PREFERRED_TYPE(bool) unsigned IgnoreNullPredecessors : 1; + LLVM_PREFERRED_TYPE(bool) unsigned IgnoreDefaultsWithCoveredEnums : 1; FilterOptions() diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ASTOps.h new file mode 100644 index 00000000000..f9c923a36ad --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ASTOps.h @@ -0,0 +1,156 @@ +//===-- ASTOps.h -------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Operations on AST nodes that are used in flow-sensitive analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H + +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Type.h" +#include "clang/Analysis/FlowSensitive/StorageLocation.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SetVector.h" + +namespace clang { +namespace dataflow { + +/// Skip past nodes that the CFG does not emit. These nodes are invisible to +/// flow-sensitive analysis, and should be ignored as they will effectively not +/// exist. +/// +/// * `ParenExpr` - The CFG takes the operator precedence into account, but +/// otherwise omits the node afterwards. +/// +/// * `ExprWithCleanups` - The CFG will generate the appropriate calls to +/// destructors and then omit the node. +/// +const Expr &ignoreCFGOmittedNodes(const Expr &E); +const Stmt &ignoreCFGOmittedNodes(const Stmt &S); + +/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic +/// iteration order. +using FieldSet = llvm::SmallSetVector; + +/// Returns the set of all fields in the type. +FieldSet getObjectFields(QualType Type); + +/// Returns whether `Fields` and `FieldLocs` contain the same fields. +bool containsSameFields(const FieldSet &Fields, + const RecordStorageLocation::FieldToLoc &FieldLocs); + +/// Helper class for initialization of a record with an `InitListExpr`. +/// `InitListExpr::inits()` contains the initializers for both the base classes +/// and the fields of the record; this helper class separates these out into two +/// different lists. In addition, it deals with special cases associated with +/// unions. +class RecordInitListHelper { +public: + // `InitList` must have record type. + RecordInitListHelper(const InitListExpr *InitList); + RecordInitListHelper(const CXXParenListInitExpr *ParenInitList); + + // Base classes with their associated initializer expressions. + ArrayRef> base_inits() const { + return BaseInits; + } + + // Fields with their associated initializer expressions. + ArrayRef> field_inits() const { + return FieldInits; + } + +private: + RecordInitListHelper(QualType Ty, std::vector Fields, + ArrayRef Inits); + + SmallVector> BaseInits; + SmallVector> FieldInits; + + // We potentially synthesize an `ImplicitValueInitExpr` for unions. It's a + // member variable because we store a pointer to it in `FieldInits`. + std::optional ImplicitValueInitForUnion; +}; + +/// Specialization of `RecursiveASTVisitor` that visits those nodes that are +/// relevant to the dataflow analysis; generally, these are the ones that also +/// appear in the CFG. +/// To start the traversal, call `TraverseStmt()` on the statement or body of +/// the function to analyze. Don't call `TraverseDecl()` on the function itself; +/// this won't work as `TraverseDecl()` contains code to avoid traversing nested +/// functions. +template +class AnalysisASTVisitor : public RecursiveASTVisitor { +public: + bool shouldVisitImplicitCode() { return true; } + + bool shouldVisitLambdaBody() const { return false; } + + bool TraverseDecl(Decl *D) { + // Don't traverse nested record or function declarations. + // - We won't be analyzing code contained in these anyway + // - We don't model fields that are used only in these nested declaration, + // so trying to propagate a result object to initializers of such fields + // would cause an error. + if (isa_and_nonnull(D) || isa_and_nonnull(D)) + return true; + + return RecursiveASTVisitor::TraverseDecl(D); + } + + // Don't traverse expressions in unevaluated contexts, as we don't model + // fields that are only used in these. + // Note: The operand of the `noexcept` operator is an unevaluated operand, but + // nevertheless it appears in the Clang CFG, so we don't exclude it here. + bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; } + bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; } + bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) { + if (TIE->isPotentiallyEvaluated()) + return RecursiveASTVisitor::TraverseCXXTypeidExpr(TIE); + return true; + } + bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) { + return true; + } + + bool TraverseBindingDecl(BindingDecl *BD) { + // `RecursiveASTVisitor` doesn't traverse holding variables for + // `BindingDecl`s by itself, so we need to tell it to. + if (VarDecl *HoldingVar = BD->getHoldingVar()) + TraverseDecl(HoldingVar); + return RecursiveASTVisitor::TraverseBindingDecl(BD); + } +}; + +/// A collection of several types of declarations, all referenced from the same +/// function. +struct ReferencedDecls { + /// Non-static member variables. + FieldSet Fields; + /// All variables with static storage duration, notably including static + /// member variables and static variables declared within a function. + llvm::DenseSet Globals; + /// Free functions and member functions which are referenced (but not + /// necessarily called). + llvm::DenseSet Functions; +}; + +/// Returns declarations that are declared in or referenced from `FD`. +ReferencedDecls getReferencedDecls(const FunctionDecl &FD); + +/// Returns declarations that are declared in or referenced from `S`. +ReferencedDecls getReferencedDecls(const Stmt &S); + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ASTOPS_H diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h new file mode 100644 index 00000000000..420f13ce11b --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h @@ -0,0 +1,96 @@ +//===-- AdornedCFG.h ------------------------------------*- 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 an AdornedCFG class that is used by dataflow analyses that +// run over Control-Flow Graphs (CFGs). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Stmt.h" +#include "clang/Analysis/CFG.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace clang { +namespace dataflow { + +/// Holds CFG with additional information derived from it that is needed to +/// perform dataflow analysis. +class AdornedCFG { +public: + /// Builds an `AdornedCFG` from a `FunctionDecl`. + /// `Func.doesThisDeclarationHaveABody()` must be true, and + /// `Func.isTemplated()` must be false. + static llvm::Expected build(const FunctionDecl &Func); + + /// Builds an `AdornedCFG` from an AST node. `D` is the function in which + /// `S` resides. `D.isTemplated()` must be false. + static llvm::Expected build(const Decl &D, Stmt &S, + ASTContext &C); + + /// Returns the `Decl` containing the statement used to construct the CFG, if + /// available. + const Decl &getDecl() const { return ContainingDecl; } + + /// Returns the CFG that is stored in this context. + const CFG &getCFG() const { return *Cfg; } + + /// Returns a mapping from statements to basic blocks that contain them. + const llvm::DenseMap &getStmtToBlock() const { + return StmtToBlock; + } + + /// Returns whether `B` is reachable from the entry block. + bool isBlockReachable(const CFGBlock &B) const { + return BlockReachable[B.getBlockID()]; + } + + /// Returns whether `B` contains an expression that is consumed in a + /// different block than `B` (i.e. the parent of the expression is in a + /// different block). + /// This happens if there is control flow within a full-expression (triggered + /// by `&&`, `||`, or the conditional operator). Note that the operands of + /// these operators are not the only expressions that can be consumed in a + /// different block. For example, in the function call + /// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`. + bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const { + return ContainsExprConsumedInDifferentBlock.contains(&B); + } + +private: + AdornedCFG( + const Decl &D, std::unique_ptr Cfg, + llvm::DenseMap StmtToBlock, + llvm::BitVector BlockReachable, + llvm::DenseSet ContainsExprConsumedInDifferentBlock) + : ContainingDecl(D), Cfg(std::move(Cfg)), + StmtToBlock(std::move(StmtToBlock)), + BlockReachable(std::move(BlockReachable)), + ContainsExprConsumedInDifferentBlock( + std::move(ContainsExprConsumedInDifferentBlock)) {} + + /// The `Decl` containing the statement used to construct the CFG. + const Decl &ContainingDecl; + std::unique_ptr Cfg; + llvm::DenseMap StmtToBlock; + llvm::BitVector BlockReachable; + llvm::DenseSet ContainsExprConsumedInDifferentBlock; +}; + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/CNFFormula.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/CNFFormula.h new file mode 100644 index 00000000000..fb13e774c67 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/CNFFormula.h @@ -0,0 +1,179 @@ +//===- CNFFormula.h ---------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +// A representation of a boolean formula in 3-CNF. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CNFFORMULA_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CNFFORMULA_H + +#include +#include + +#include "clang/Analysis/FlowSensitive/Formula.h" + +namespace clang { +namespace dataflow { + +/// Boolean variables are represented as positive integers. +using Variable = uint32_t; + +/// A null boolean variable is used as a placeholder in various data structures +/// and algorithms. +constexpr Variable NullVar = 0; + +/// Literals are represented as positive integers. Specifically, for a boolean +/// variable `V` that is represented as the positive integer `I`, the positive +/// literal `V` is represented as the integer `2*I` and the negative literal +/// `!V` is represented as the integer `2*I+1`. +using Literal = uint32_t; + +/// A null literal is used as a placeholder in various data structures and +/// algorithms. +constexpr Literal NullLit = 0; + +/// Clause identifiers are represented as positive integers. +using ClauseID = uint32_t; + +/// A null clause identifier is used as a placeholder in various data structures +/// and algorithms. +constexpr ClauseID NullClause = 0; + +/// Returns the positive literal `V`. +inline constexpr Literal posLit(Variable V) { return 2 * V; } + +/// Returns the negative literal `!V`. +inline constexpr Literal negLit(Variable V) { return 2 * V + 1; } + +/// Returns whether `L` is a positive literal. +inline constexpr bool isPosLit(Literal L) { return 0 == (L & 1); } + +/// Returns whether `L` is a negative literal. +inline constexpr bool isNegLit(Literal L) { return 1 == (L & 1); } + +/// Returns the negated literal `!L`. +inline constexpr Literal notLit(Literal L) { return L ^ 1; } + +/// Returns the variable of `L`. +inline constexpr Variable var(Literal L) { return L >> 1; } + +/// A boolean formula in 3-CNF (conjunctive normal form with at most 3 literals +/// per clause). +class CNFFormula { + /// `LargestVar` is equal to the largest positive integer that represents a + /// variable in the formula. + const Variable LargestVar; + + /// Literals of all clauses in the formula. + /// + /// The element at index 0 stands for the literal in the null clause. It is + /// set to 0 and isn't used. Literals of clauses in the formula start from the + /// element at index 1. + /// + /// For example, for the formula `(L1 v L2) ^ (L2 v L3 v L4)` the elements of + /// `Clauses` will be `[0, L1, L2, L2, L3, L4]`. + std::vector Clauses; + + /// Start indices of clauses of the formula in `Clauses`. + /// + /// The element at index 0 stands for the start index of the null clause. It + /// is set to 0 and isn't used. Start indices of clauses in the formula start + /// from the element at index 1. + /// + /// For example, for the formula `(L1 v L2) ^ (L2 v L3 v L4)` the elements of + /// `ClauseStarts` will be `[0, 1, 3]`. Note that the literals of the first + /// clause always start at index 1. The start index for the literals of the + /// second clause depends on the size of the first clause and so on. + std::vector ClauseStarts; + + /// Indicates that we already know the formula is unsatisfiable. + /// During construction, we catch simple cases of conflicting unit-clauses. + bool KnownContradictory; + +public: + explicit CNFFormula(Variable LargestVar); + + /// Adds the `L1 v ... v Ln` clause to the formula. + /// Requirements: + /// + /// `Li` must not be `NullLit`. + /// + /// All literals in the input that are not `NullLit` must be distinct. + void addClause(ArrayRef lits); + + /// Returns whether the formula is known to be contradictory. + /// This is the case if any of the clauses is empty. + bool knownContradictory() const { return KnownContradictory; } + + /// Returns the largest variable in the formula. + Variable largestVar() const { return LargestVar; } + + /// Returns the number of clauses in the formula. + /// Valid clause IDs are in the range [1, `numClauses()`]. + ClauseID numClauses() const { return ClauseStarts.size() - 1; } + + /// Returns the number of literals in clause `C`. + size_t clauseSize(ClauseID C) const { + return C == ClauseStarts.size() - 1 ? Clauses.size() - ClauseStarts[C] + : ClauseStarts[C + 1] - ClauseStarts[C]; + } + + /// Returns the literals of clause `C`. + /// If `knownContradictory()` is false, each clause has at least one literal. + llvm::ArrayRef clauseLiterals(ClauseID C) const { + size_t S = clauseSize(C); + if (S == 0) + return llvm::ArrayRef(); + return llvm::ArrayRef(&Clauses[ClauseStarts[C]], S); + } + + /// An iterator over all literals of all clauses in the formula. + /// The iterator allows mutation of the literal through the `*` operator. + /// This is to support solvers that mutate the formula during solving. + class Iterator { + friend class CNFFormula; + CNFFormula *CNF; + size_t Idx; + Iterator(CNFFormula *CNF, size_t Idx) : CNF(CNF), Idx(Idx) {} + + public: + Iterator(const Iterator &) = default; + Iterator &operator=(const Iterator &) = default; + + Iterator &operator++() { + ++Idx; + assert(Idx < CNF->Clauses.size() && "Iterator out of bounds"); + return *this; + } + + Iterator next() const { + Iterator I = *this; + ++I; + return I; + } + + Literal &operator*() const { return CNF->Clauses[Idx]; } + }; + friend class Iterator; + + /// Returns an iterator to the first literal of clause `C`. + Iterator startOfClause(ClauseID C) { return Iterator(this, ClauseStarts[C]); } +}; + +/// Converts the conjunction of `Vals` into a formula in conjunctive normal +/// form where each clause has at least one and at most three literals. +/// `Atomics` is populated with a mapping from `Variables` to the corresponding +/// `Atom`s for atomic booleans in the input formulas. +CNFFormula buildCNF(const llvm::ArrayRef &Formulas, + llvm::DenseMap &Atomics); + +} // namespace dataflow +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CNFFORMULA_H diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h deleted file mode 100644 index 405e93287a0..00000000000 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h +++ /dev/null @@ -1,79 +0,0 @@ -//===-- ControlFlowContext.h ------------------------------------*- 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 a ControlFlowContext class that is used by dataflow -// analyses that run over Control-Flow Graphs (CFGs). -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H -#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H - -#include "clang/AST/ASTContext.h" -#include "clang/AST/Decl.h" -#include "clang/AST/Stmt.h" -#include "clang/Analysis/CFG.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/Support/Error.h" -#include -#include - -namespace clang { -namespace dataflow { - -/// Holds CFG and other derived context that is needed to perform dataflow -/// analysis. -class ControlFlowContext { -public: - /// Builds a ControlFlowContext from a `FunctionDecl`. - /// `Func.doesThisDeclarationHaveABody()` must be true, and - /// `Func.isTemplated()` must be false. - static llvm::Expected build(const FunctionDecl &Func); - - /// Builds a ControlFlowContext from an AST node. `D` is the function in which - /// `S` resides. `D.isTemplated()` must be false. - static llvm::Expected build(const Decl &D, Stmt &S, - ASTContext &C); - - /// Returns the `Decl` containing the statement used to construct the CFG, if - /// available. - const Decl &getDecl() const { return ContainingDecl; } - - /// Returns the CFG that is stored in this context. - const CFG &getCFG() const { return *Cfg; } - - /// Returns a mapping from statements to basic blocks that contain them. - const llvm::DenseMap &getStmtToBlock() const { - return StmtToBlock; - } - - /// Returns whether `B` is reachable from the entry block. - bool isBlockReachable(const CFGBlock &B) const { - return BlockReachable[B.getBlockID()]; - } - -private: - ControlFlowContext(const Decl &D, std::unique_ptr Cfg, - llvm::DenseMap StmtToBlock, - llvm::BitVector BlockReachable) - : ContainingDecl(D), Cfg(std::move(Cfg)), - StmtToBlock(std::move(StmtToBlock)), - BlockReachable(std::move(BlockReachable)) {} - - /// The `Decl` containing the statement used to construct the CFG. - const Decl &ContainingDecl; - std::unique_ptr Cfg; - llvm::DenseMap StmtToBlock; - llvm::BitVector BlockReachable; -}; - -} // namespace dataflow -} // namespace clang - -#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h index b95095d2184..50a70188720 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -22,7 +22,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Analysis/CFG.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" #include "clang/Analysis/FlowSensitive/MatchSwitch.h" @@ -54,10 +54,9 @@ namespace dataflow { /// Environment &Env)` - applies the analysis transfer /// function for a given edge from a CFG block of a conditional statement. /// -/// `Derived` can optionally override the following members: -/// * `bool merge(QualType, const Value &, const Value &, Value &, -/// Environment &)` - joins distinct values. This could be a strict -/// lattice join or a more general widening operation. +/// `Derived` can optionally override the virtual functions in the +/// `Environment::ValueModel` interface (which is an indirect base class of +/// this class). /// /// `LatticeT` is a bounded join-semilattice that is used by `Derived` and must /// provide the following public members: @@ -179,13 +178,50 @@ template struct DataflowAnalysisState { Environment Env; }; +/// A callback to be called with the state before or after visiting a CFG +/// element. +template +using CFGEltCallback = std::function &)>; + +/// A pair of callbacks to be called with the state before and after visiting a +/// CFG element. +/// Either or both of the callbacks may be null. +template struct CFGEltCallbacks { + CFGEltCallback Before; + CFGEltCallback After; +}; + +/// A callback for performing diagnosis on a CFG element, called with the state +/// before or after visiting that CFG element. Returns a list of diagnostics +/// to emit (if any). +template +using DiagnosisCallback = llvm::function_ref( + const CFGElement &, ASTContext &, + const TransferStateForDiagnostics &)>; + +/// A pair of callbacks for performing diagnosis on a CFG element, called with +/// the state before and after visiting that CFG element. +/// Either or both of the callbacks may be null. +template struct DiagnosisCallbacks { + DiagnosisCallback Before; + DiagnosisCallback After; +}; + +/// Default for the maximum number of SAT solver iterations during analysis. +inline constexpr std::int64_t kDefaultMaxSATIterations = 1'000'000'000; + +/// Default for the maximum number of block visits during analysis. +inline constexpr std::int32_t kDefaultMaxBlockVisits = 20'000; + /// Performs dataflow analysis and returns a mapping from basic block IDs to /// dataflow analysis states that model the respective basic blocks. The /// returned vector, if any, will have the same size as the number of CFG /// blocks, with indices corresponding to basic block IDs. Returns an error if /// the dataflow analysis cannot be performed successfully. Otherwise, calls -/// `PostVisitCFG` on each CFG element with the final analysis results at that -/// program point. +/// `PostAnalysisCallbacks` on each CFG element with the final analysis results +/// before and after that program point. /// /// `MaxBlockVisits` caps the number of block visits during analysis. See /// `runTypeErasedDataflowAnalysis` for a full description. The default value is @@ -195,31 +231,40 @@ template struct DataflowAnalysisState { template llvm::Expected>>> -runDataflowAnalysis( - const ControlFlowContext &CFCtx, AnalysisT &Analysis, - const Environment &InitEnv, - std::function &)> - PostVisitCFG = nullptr, - std::int32_t MaxBlockVisits = 20'000) { - std::function - PostVisitCFGClosure = nullptr; - if (PostVisitCFG) { - PostVisitCFGClosure = [&PostVisitCFG]( - const CFGElement &Element, - const TypeErasedDataflowAnalysisState &State) { - auto *Lattice = - llvm::any_cast(&State.Lattice.Value); - // FIXME: we should not be copying the environment here! - // Ultimately the PostVisitCFG only gets a const reference anyway. - PostVisitCFG(Element, DataflowAnalysisState{ - *Lattice, State.Env.fork()}); - }; +runDataflowAnalysis(const AdornedCFG &ACFG, AnalysisT &Analysis, + const Environment &InitEnv, + CFGEltCallbacks PostAnalysisCallbacks, + std::int32_t MaxBlockVisits = kDefaultMaxBlockVisits) { + CFGEltCallbacksTypeErased TypeErasedCallbacks; + if (PostAnalysisCallbacks.Before) { + TypeErasedCallbacks.Before = + [&PostAnalysisCallbacks](const CFGElement &Element, + const TypeErasedDataflowAnalysisState &State) { + auto *Lattice = + llvm::any_cast(&State.Lattice.Value); + // FIXME: we should not be copying the environment here! + // Ultimately the `CFGEltCallback` only gets a const reference anyway. + PostAnalysisCallbacks.Before( + Element, DataflowAnalysisState{ + *Lattice, State.Env.fork()}); + }; + } + if (PostAnalysisCallbacks.After) { + TypeErasedCallbacks.After = + [&PostAnalysisCallbacks](const CFGElement &Element, + const TypeErasedDataflowAnalysisState &State) { + auto *Lattice = + llvm::any_cast(&State.Lattice.Value); + // FIXME: we should not be copying the environment here! + // Ultimately the `CFGEltCallback` only gets a const reference anyway. + PostAnalysisCallbacks.After( + Element, DataflowAnalysisState{ + *Lattice, State.Env.fork()}); + }; } auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis( - CFCtx, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits); + ACFG, Analysis, InitEnv, TypeErasedCallbacks, MaxBlockVisits); if (!TypeErasedBlockStates) return TypeErasedBlockStates.takeError(); @@ -241,6 +286,22 @@ runDataflowAnalysis( return std::move(BlockStates); } +/// Overload that takes only one post-analysis callback, which is run on the +/// state after visiting the `CFGElement`. This is provided for backwards +/// compatibility; new callers should call the overload taking `CFGEltCallbacks` +/// instead. +template +llvm::Expected>>> +runDataflowAnalysis( + const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv, + CFGEltCallback PostAnalysisCallbackAfterElt = nullptr, + std::int32_t MaxBlockVisits = kDefaultMaxBlockVisits) { + return runDataflowAnalysis(ACFG, Analysis, InitEnv, + {nullptr, PostAnalysisCallbackAfterElt}, + MaxBlockVisits); +} + // Create an analysis class that is derived from `DataflowAnalysis`. This is an // SFINAE adapter that allows us to call two different variants of constructor // (either with or without the optional `Environment` parameter). @@ -273,40 +334,52 @@ auto createAnalysis(ASTContext &ASTCtx, Environment &Env) /// `runDataflowAnalysis` for a full description and explanation of the default /// value. template -llvm::Expected> diagnoseFunction( - const FunctionDecl &FuncDecl, ASTContext &ASTCtx, - llvm::function_ref( - const CFGElement &, ASTContext &, - const TransferStateForDiagnostics &)> - Diagnoser, - std::int64_t MaxSATIterations = 1'000'000'000, - std::int32_t MaxBlockVisits = 20'000) { - llvm::Expected Context = - ControlFlowContext::build(FuncDecl); +llvm::Expected> +diagnoseFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx, + DiagnosisCallbacks Diagnoser, + std::int64_t MaxSATIterations = kDefaultMaxSATIterations, + std::int32_t MaxBlockVisits = kDefaultMaxBlockVisits) { + llvm::Expected Context = AdornedCFG::build(FuncDecl); if (!Context) return Context.takeError(); - auto OwnedSolver = std::make_unique(MaxSATIterations); - const WatchedLiteralsSolver *Solver = OwnedSolver.get(); - DataflowAnalysisContext AnalysisContext(std::move(OwnedSolver)); + auto Solver = std::make_unique(MaxSATIterations); + DataflowAnalysisContext AnalysisContext(*Solver); Environment Env(AnalysisContext, FuncDecl); AnalysisT Analysis = createAnalysis(ASTCtx, Env); llvm::SmallVector Diagnostics; + CFGEltCallbacksTypeErased PostAnalysisCallbacks; + if (Diagnoser.Before) { + PostAnalysisCallbacks.Before = + [&ASTCtx, &Diagnoser, + &Diagnostics](const CFGElement &Elt, + const TypeErasedDataflowAnalysisState &State) mutable { + auto EltDiagnostics = Diagnoser.Before( + Elt, ASTCtx, + TransferStateForDiagnostics( + llvm::any_cast( + State.Lattice.Value), + State.Env)); + llvm::move(EltDiagnostics, std::back_inserter(Diagnostics)); + }; + } + if (Diagnoser.After) { + PostAnalysisCallbacks.After = + [&ASTCtx, &Diagnoser, + &Diagnostics](const CFGElement &Elt, + const TypeErasedDataflowAnalysisState &State) mutable { + auto EltDiagnostics = Diagnoser.After( + Elt, ASTCtx, + TransferStateForDiagnostics( + llvm::any_cast( + State.Lattice.Value), + State.Env)); + llvm::move(EltDiagnostics, std::back_inserter(Diagnostics)); + }; + } if (llvm::Error Err = - runTypeErasedDataflowAnalysis( - *Context, Analysis, Env, - [&ASTCtx, &Diagnoser, &Diagnostics]( - const CFGElement &Elt, - const TypeErasedDataflowAnalysisState &State) mutable { - auto EltDiagnostics = Diagnoser( - Elt, ASTCtx, - TransferStateForDiagnostics( - llvm::any_cast( - State.Lattice.Value), - State.Env)); - llvm::move(EltDiagnostics, std::back_inserter(Diagnostics)); - }, - MaxBlockVisits) + runTypeErasedDataflowAnalysis(*Context, Analysis, Env, + PostAnalysisCallbacks, MaxBlockVisits) .takeError()) return std::move(Err); @@ -317,6 +390,21 @@ llvm::Expected> diagnoseFunction( return Diagnostics; } +/// Overload that takes only one diagnosis callback, which is run on the state +/// after visiting the `CFGElement`. This is provided for backwards +/// compatibility; new callers should call the overload taking +/// `DiagnosisCallbacks` instead. +template +llvm::Expected> +diagnoseFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx, + DiagnosisCallback Diagnoser, + std::int64_t MaxSATIterations = kDefaultMaxSATIterations, + std::int32_t MaxBlockVisits = kDefaultMaxBlockVisits) { + DiagnosisCallbacks Callbacks = {nullptr, Diagnoser}; + return diagnoseFunction(FuncDecl, ASTCtx, Callbacks, MaxSATIterations, + MaxBlockVisits); +} + /// Abstract base class for dataflow "models": reusable analysis components that /// model a particular aspect of program semantics in the `Environment`. For /// example, a model may capture a type and its related functions. diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h index 20e45cc27b0..5be4a1145f4 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h @@ -18,8 +18,9 @@ #include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/AST/TypeOrdering.h" +#include "clang/Analysis/FlowSensitive/ASTOps.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/Arena.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" #include "clang/Analysis/FlowSensitive/Solver.h" #include "clang/Analysis/FlowSensitive/StorageLocation.h" #include "clang/Analysis/FlowSensitive/Value.h" @@ -30,38 +31,11 @@ #include #include #include -#include -#include -#include namespace clang { namespace dataflow { class Logger; -/// Skip past nodes that the CFG does not emit. These nodes are invisible to -/// flow-sensitive analysis, and should be ignored as they will effectively not -/// exist. -/// -/// * `ParenExpr` - The CFG takes the operator precedence into account, but -/// otherwise omits the node afterwards. -/// -/// * `ExprWithCleanups` - The CFG will generate the appropriate calls to -/// destructors and then omit the node. -/// -const Expr &ignoreCFGOmittedNodes(const Expr &E); -const Stmt &ignoreCFGOmittedNodes(const Stmt &S); - -/// A set of `FieldDecl *`. Use `SmallSetVector` to guarantee deterministic -/// iteration order. -using FieldSet = llvm::SmallSetVector; - -/// Returns the set of all fields in the type. -FieldSet getObjectFields(QualType Type); - -/// Returns whether `Fields` and `FieldLocs` contain the same fields. -bool containsSameFields(const FieldSet &Fields, - const RecordStorageLocation::FieldToLoc &FieldLocs); - struct ContextSensitiveOptions { /// The maximum depth to analyze. A value of zero is equivalent to disabling /// context-sensitive analysis entirely. @@ -93,13 +67,27 @@ public: DataflowAnalysisContext(std::unique_ptr S, Options Opts = Options{ /*ContextSensitiveOpts=*/std::nullopt, - /*Logger=*/nullptr}); + /*Logger=*/nullptr}) + : DataflowAnalysisContext(*S, std::move(S), Opts) {} + + /// Constructs a dataflow analysis context. + /// + /// Requirements: + /// + /// `S` must outlive the `DataflowAnalysisContext`. + DataflowAnalysisContext(Solver &S, Options Opts = Options{ + /*ContextSensitiveOpts=*/std::nullopt, + /*Logger=*/nullptr}) + : DataflowAnalysisContext(S, nullptr, Opts) {} + ~DataflowAnalysisContext(); /// Sets a callback that returns the names and types of the synthetic fields /// to add to a `RecordStorageLocation` of a given type. /// Typically, this is called from the constructor of a `DataflowAnalysis` /// + /// The field types returned by the callback may not have reference type. + /// /// To maintain the invariant that all `RecordStorageLocation`s of a given /// type have the same fields: /// * The callback must always return the same result for a given type @@ -181,9 +169,9 @@ public: LLVM_DUMP_METHOD void dumpFlowCondition(Atom Token, llvm::raw_ostream &OS = llvm::dbgs()); - /// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise, + /// Returns the `AdornedCFG` registered for `F`, if any. Otherwise, /// returns null. - const ControlFlowContext *getControlFlowContext(const FunctionDecl *F); + const AdornedCFG *getAdornedCFG(const FunctionDecl *F); const Options &getOptions() { return Opts; } @@ -205,8 +193,17 @@ public: /// type. llvm::StringMap getSyntheticFields(QualType Type) { assert(Type->isRecordType()); - if (SyntheticFieldCallback) - return SyntheticFieldCallback(Type); + if (SyntheticFieldCallback) { + llvm::StringMap Result = SyntheticFieldCallback(Type); + // Synthetic fields are not allowed to have reference type. + assert([&Result] { + for (const auto &Entry : Result) + if (Entry.getValue()->isReferenceType()) + return false; + return true; + }()); + return Result; + } return {}; } @@ -224,6 +221,13 @@ private: using DenseMapInfo::isEqual; }; + /// `S` is the solver to use. `OwnedSolver` may be: + /// * Null (in which case `S` is non-onwed and must outlive this object), or + /// * Non-null (in which case it must refer to `S`, and the + /// `DataflowAnalysisContext will take ownership of `OwnedSolver`). + DataflowAnalysisContext(Solver &S, std::unique_ptr &&OwnedSolver, + Options Opts); + // Extends the set of modeled field declarations. void addModeledFields(const FieldSet &Fields); @@ -247,7 +251,8 @@ private: Solver::Result::Status::Unsatisfiable; } - std::unique_ptr S; + Solver &S; + std::unique_ptr OwnedSolver; std::unique_ptr A; // Maps from program declarations and statements to storage locations that are @@ -285,7 +290,7 @@ private: llvm::DenseMap FlowConditionConstraints; const Formula *Invariant = nullptr; - llvm::DenseMap FunctionContexts; + llvm::DenseMap FunctionContexts; // Fields modeled by environments covered by this context. FieldSet ModeledFields; diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index 1543f900e40..097ff2bdfe7 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -19,7 +19,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/Expr.h" #include "clang/AST/Type.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/ASTOps.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" #include "clang/Analysis/FlowSensitive/Formula.h" @@ -31,9 +31,11 @@ #include "llvm/ADT/MapVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include #include #include #include +#include namespace clang { namespace dataflow { @@ -45,6 +47,15 @@ enum class ComparisonResult { Unknown, }; +/// The result of a `widen` operation. +struct WidenResult { + /// Non-null pointer to a potentially widened version of the input value. + Value *V; + /// Whether `V` represents a "change" (that is, a different value) with + /// respect to the previous value in the sequence. + LatticeEffect Effect; +}; + /// Holds the state of the program (store and heap) at a given program point. /// /// WARNING: Symbolic values that are created by the environment for static @@ -76,16 +87,13 @@ public: virtual ComparisonResult compare(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2) { - // FIXME: Consider adding QualType to RecordValue and removing the Type + // FIXME: Consider adding `QualType` to `Value` and removing the `Type` // argument here. return ComparisonResult::Unknown; } - /// Modifies `MergedVal` to approximate both `Val1` and `Val2`. This could - /// be a strict lattice join or a more general widening operation. - /// - /// If this function returns true, `MergedVal` will be assigned to a storage - /// location of type `Type` in `MergedEnv`. + /// Modifies `JoinedVal` to approximate both `Val1` and `Val2`. This should + /// obey the properties of a lattice join. /// /// `Env1` and `Env2` can be used to query child values and path condition /// implications of `Val1` and `Val2` respectively. @@ -94,16 +102,13 @@ public: /// /// `Val1` and `Val2` must be distinct. /// - /// `Val1`, `Val2`, and `MergedVal` must model values of type `Type`. + /// `Val1`, `Val2`, and `JoinedVal` must model values of type `Type`. /// /// `Val1` and `Val2` must be assigned to the same storage location in /// `Env1` and `Env2` respectively. - virtual bool merge(QualType Type, const Value &Val1, - const Environment &Env1, const Value &Val2, - const Environment &Env2, Value &MergedVal, - Environment &MergedEnv) { - return true; - } + virtual void join(QualType Type, const Value &Val1, const Environment &Env1, + const Value &Val2, const Environment &Env2, + Value &JoinedVal, Environment &JoinedEnv) {} /// This function may widen the current value -- replace it with an /// approximation that can reach a fixed point more quickly than iterated @@ -112,14 +117,17 @@ public: /// serve as a comparison operation, by indicating whether the widened value /// is equivalent to the previous value. /// - /// Returns either: - /// - /// `nullptr`, if this value is not of interest to the model, or - /// - /// `&Prev`, if the widened value is equivalent to `Prev`, or - /// - /// A non-null value that approximates `Current`. `Prev` is available to - /// inform the chosen approximation. + /// Returns one of the folowing: + /// * `std::nullopt`, if this value is not of interest to the + /// model. + /// * A `WidenResult` with: + /// * A non-null `Value *` that points either to `Current` or a widened + /// version of `Current`. This value must be consistent with + /// the flow condition of `CurrentEnv`. We particularly caution + /// against using `Prev`, which is rarely consistent. + /// * A `LatticeEffect` indicating whether the value should be + /// considered a new value (`Changed`) or one *equivalent* (if not + /// necessarily equal) to `Prev` (`Unchanged`). /// /// `PrevEnv` and `CurrentEnv` can be used to query child values and path /// condition implications of `Prev` and `Current`, respectively. @@ -130,17 +138,19 @@ public: /// /// `Prev` and `Current` must be assigned to the same storage location in /// `PrevEnv` and `CurrentEnv`, respectively. - virtual Value *widen(QualType Type, Value &Prev, const Environment &PrevEnv, - Value &Current, Environment &CurrentEnv) { + virtual std::optional widen(QualType Type, Value &Prev, + const Environment &PrevEnv, + Value &Current, + Environment &CurrentEnv) { // The default implementation reduces to just comparison, since comparison // is required by the API, even if no widening is performed. switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) { - case ComparisonResult::Same: - return &Prev; - case ComparisonResult::Different: - return &Current; - case ComparisonResult::Unknown: - return nullptr; + case ComparisonResult::Unknown: + return std::nullopt; + case ComparisonResult::Same: + return WidenResult{&Current, LatticeEffect::Unchanged}; + case ComparisonResult::Different: + return WidenResult{&Current, LatticeEffect::Changed}; } llvm_unreachable("all cases in switch covered"); } @@ -148,7 +158,28 @@ public: /// Creates an environment that uses `DACtx` to store objects that encompass /// the state of a program. - explicit Environment(DataflowAnalysisContext &DACtx); + explicit Environment(DataflowAnalysisContext &DACtx) + : DACtx(&DACtx), + FlowConditionToken(DACtx.arena().makeFlowConditionToken()) {} + + /// Creates an environment that uses `DACtx` to store objects that encompass + /// the state of a program, with `S` as the statement to analyze. + Environment(DataflowAnalysisContext &DACtx, Stmt &S) : Environment(DACtx) { + InitialTargetStmt = &S; + } + + /// Creates an environment that uses `DACtx` to store objects that encompass + /// the state of a program, with `FD` as the function to analyze. + /// + /// Requirements: + /// + /// The function must have a body, i.e. + /// `FunctionDecl::doesThisDecalarationHaveABody()` must be true. + Environment(DataflowAnalysisContext &DACtx, const FunctionDecl &FD) + : Environment(DACtx, *FD.getBody()) { + assert(FD.doesThisDeclarationHaveABody()); + InitialTargetFunc = &FD; + } // Copy-constructor is private, Environments should not be copied. See fork(). Environment &operator=(const Environment &Other) = delete; @@ -156,24 +187,11 @@ public: Environment(Environment &&Other) = default; Environment &operator=(Environment &&Other) = default; - /// Creates an environment that uses `DACtx` to store objects that encompass - /// the state of a program. - /// - /// If `DeclCtx` is a function, initializes the environment with symbolic - /// representations of the function parameters. - /// - /// If `DeclCtx` is a non-static member function, initializes the environment - /// with a symbolic representation of the `this` pointee. - Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx); - /// Assigns storage locations and values to all parameters, captures, global - /// variables, fields and functions referenced in the function currently being - /// analyzed. + /// variables, fields and functions referenced in the `Stmt` or `FunctionDecl` + /// passed to the constructor. /// - /// Requirements: - /// - /// The function must have a body, i.e. - /// `FunctionDecl::doesThisDecalarationHaveABody()` must be true. + /// If no `Stmt` or `FunctionDecl` was supplied, this function does nothing. void initialize(); /// Returns a new environment that is a copy of this one. @@ -186,7 +204,7 @@ public: /// forked flow condition references the original). Environment fork() const; - /// Creates and returns an environment to use for an inline analysis of the + /// Creates and returns an environment to use for an inline analysis of the /// callee. Uses the storage location from each argument in the `Call` as the /// storage location for the corresponding parameter in the callee. /// @@ -218,6 +236,14 @@ public: bool equivalentTo(const Environment &Other, Environment::ValueModel &Model) const; + /// How to treat expression state (`ExprToLoc` and `ExprToVal`) in a join. + /// If the join happens within a full expression, expression state should be + /// kept; otherwise, we can discard it. + enum ExprJoinBehavior { + DiscardExprState, + KeepExprState, + }; + /// Joins two environments by taking the intersection of storage locations and /// values that are stored in them. Distinct values that are assigned to the /// same storage locations in `EnvA` and `EnvB` are merged using `Model`. @@ -226,7 +252,23 @@ public: /// /// `EnvA` and `EnvB` must use the same `DataflowAnalysisContext`. static Environment join(const Environment &EnvA, const Environment &EnvB, - Environment::ValueModel &Model); + Environment::ValueModel &Model, + ExprJoinBehavior ExprBehavior); + + /// Returns a value that approximates both `Val1` and `Val2`, or null if no + /// such value can be produced. + /// + /// `Env1` and `Env2` can be used to query child values and path condition + /// implications of `Val1` and `Val2` respectively. The joined value will be + /// produced in `JoinedEnv`. + /// + /// Requirements: + /// + /// `Val1` and `Val2` must model values of type `Type`. + static Value *joinValues(QualType Ty, Value *Val1, const Environment &Env1, + Value *Val2, const Environment &Env2, + Environment &JoinedEnv, + Environment::ValueModel &Model); /// Widens the environment point-wise, using `PrevEnv` as needed to inform the /// approximation. @@ -235,8 +277,8 @@ public: /// /// `PrevEnv` must be the immediate previous version of the environment. /// `PrevEnv` and `this` must use the same `DataflowAnalysisContext`. - LatticeJoinEffect widen(const Environment &PrevEnv, - Environment::ValueModel &Model); + LatticeEffect widen(const Environment &PrevEnv, + Environment::ValueModel &Model); // FIXME: Rename `createOrGetStorageLocation` to `getOrCreateStorageLocation`, // `getStableStorageLocation`, or something more appropriate. @@ -329,62 +371,56 @@ public: /// location of the result object to pass in `this`, even though prvalues are /// otherwise not associated with storage locations. /// - /// FIXME: Currently, this simply returns a stable storage location for `E`, - /// but this doesn't do the right thing in scenarios like the following: - /// ``` - /// MyClass c = some_condition()? MyClass(foo) : MyClass(bar); - /// ``` - /// Here, `MyClass(foo)` and `MyClass(bar)` will have two different storage - /// locations, when in fact their storage locations should be the same. - /// Eventually, we want to propagate storage locations from result objects - /// down to the prvalues that initialize them, similar to the way that this is - /// done in Clang's CodeGen. - /// /// Requirements: /// `E` must be a prvalue of record type. RecordStorageLocation & getResultObjectLocation(const Expr &RecordPRValue) const; - /// Returns the return value of the current function. This can be null if: + /// Returns the return value of the function currently being analyzed. + /// This can be null if: /// - The function has a void return type /// - No return value could be determined for the function, for example /// because it calls a function without a body. /// /// Requirements: - /// The current function must have a non-reference return type. + /// The current analysis target must be a function and must have a + /// non-reference return type. Value *getReturnValue() const { assert(getCurrentFunc() != nullptr && !getCurrentFunc()->getReturnType()->isReferenceType()); return ReturnVal; } - /// Returns the storage location for the reference returned by the current - /// function. This can be null if function doesn't return a single consistent - /// reference. + /// Returns the storage location for the reference returned by the function + /// currently being analyzed. This can be null if the function doesn't return + /// a single consistent reference. /// /// Requirements: - /// The current function must have a reference return type. + /// The current analysis target must be a function and must have a reference + /// return type. StorageLocation *getReturnStorageLocation() const { assert(getCurrentFunc() != nullptr && getCurrentFunc()->getReturnType()->isReferenceType()); return ReturnLoc; } - /// Sets the return value of the current function. + /// Sets the return value of the function currently being analyzed. /// /// Requirements: - /// The current function must have a non-reference return type. + /// The current analysis target must be a function and must have a + /// non-reference return type. void setReturnValue(Value *Val) { assert(getCurrentFunc() != nullptr && !getCurrentFunc()->getReturnType()->isReferenceType()); ReturnVal = Val; } - /// Sets the storage location for the reference returned by the current - /// function. + /// Sets the storage location for the reference returned by the function + /// currently being analyzed. /// /// Requirements: - /// The current function must have a reference return type. + /// The current analysis target must be a function and must have a reference + /// return type. void setReturnStorageLocation(StorageLocation *Loc) { assert(getCurrentFunc() != nullptr && getCurrentFunc()->getReturnType()->isReferenceType()); @@ -402,20 +438,15 @@ public: /// storage locations and values for indirections until it finds a /// non-pointer/non-reference type. /// - /// If `Type` is a class, struct, or union type, creates values for all - /// modeled fields (including synthetic fields) and calls `setValue()` to - /// associate the `RecordValue` with its storage location - /// (`RecordValue::getLoc()`). - /// /// If `Type` is one of the following types, this function will always return /// a non-null pointer: /// - `bool` /// - Any integer type - /// - Any class, struct, or union type /// /// Requirements: /// - /// `Type` must not be null. + /// - `Type` must not be null. + /// - `Type` must not be a reference type or record type. Value *createValue(QualType Type); /// Creates an object (i.e. a storage location with an associated value) of @@ -444,7 +475,23 @@ public: return createObjectInternal(&D, D.getType(), InitExpr); } + /// Initializes the fields (including synthetic fields) of `Loc` with values, + /// unless values of the field type are not supported or we hit one of the + /// limits at which we stop producing values. + /// If a field already has a value, that value is preserved. + /// If `Type` is provided, initializes only those fields that are modeled for + /// `Type`; this is intended for use in cases where `Loc` is a derived type + /// and we only want to initialize the fields of a base type. + void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type); + void initializeFieldsWithValues(RecordStorageLocation &Loc) { + initializeFieldsWithValues(Loc, Loc.getType()); + } + /// Assigns `Val` as the value of `Loc` in the environment. + /// + /// Requirements: + /// + /// `Loc` must not be a `RecordStorageLocation`. void setValue(const StorageLocation &Loc, Value &Val); /// Clears any association between `Loc` and a value in the environment. @@ -454,20 +501,24 @@ public: /// /// Requirements: /// - /// - `E` must be a prvalue - /// - If `Val` is a `RecordValue`, its `RecordStorageLocation` must be - /// `getResultObjectLocation(E)`. An exception to this is if `E` is an - /// expression that originally creates a `RecordValue` (such as a - /// `CXXConstructExpr` or `CallExpr`), as these establish the location of - /// the result object in the first place. + /// - `E` must be a prvalue. + /// - `E` must not have record type. void setValue(const Expr &E, Value &Val); /// Returns the value assigned to `Loc` in the environment or null if `Loc` /// isn't assigned a value in the environment. + /// + /// Requirements: + /// + /// `Loc` must not be a `RecordStorageLocation`. Value *getValue(const StorageLocation &Loc) const; /// Equivalent to `getValue(getStorageLocation(D))` if `D` is assigned a /// storage location in the environment, otherwise returns null. + /// + /// Requirements: + /// + /// `D` must not have record type. Value *getValue(const ValueDecl &D) const; /// Equivalent to `getValue(getStorageLocation(E, SP))` if `E` is assigned a @@ -606,23 +657,21 @@ public: /// (or the flow condition is overly constraining) or if the solver times out. bool allows(const Formula &) const; - /// Returns the `DeclContext` of the block being analysed, if any. Otherwise, - /// returns null. - const DeclContext *getDeclCtx() const { return CallStack.back(); } - /// Returns the function currently being analyzed, or null if the code being /// analyzed isn't part of a function. const FunctionDecl *getCurrentFunc() const { - return dyn_cast(getDeclCtx()); + return CallStack.empty() ? InitialTargetFunc : CallStack.back(); } - /// Returns the size of the call stack. + /// Returns the size of the call stack, not counting the initial analysis + /// target. size_t callStackSize() const { return CallStack.size(); } /// Returns whether this `Environment` can be extended to analyze the given - /// `Callee` (i.e. if `pushCall` can be used), with recursion disallowed and a - /// given `MaxDepth`. - bool canDescend(unsigned MaxDepth, const DeclContext *Callee) const; + /// `Callee` (i.e. if `pushCall` can be used). + /// Recursion is not allowed. `MaxDepth` is the maximum size of the call stack + /// (i.e. the maximum value that `callStackSize()` may assume after the call). + bool canDescend(unsigned MaxDepth, const FunctionDecl *Callee) const; /// Returns the `DataflowAnalysisContext` used by the environment. DataflowAnalysisContext &getDataflowAnalysisContext() const { return *DACtx; } @@ -633,6 +682,9 @@ public: LLVM_DUMP_METHOD void dump(raw_ostream &OS) const; private: + using PrValueToResultObject = + llvm::DenseMap; + // The copy-constructor is for use in fork() only. Environment(const Environment &) = default; @@ -659,6 +711,16 @@ private: llvm::DenseSet &Visited, int Depth, int &CreatedValuesCount); + /// Initializes the fields (including synthetic fields) of `Loc` with values, + /// unless values of the field type are not supported or we hit one of the + /// limits at which we stop producing values (controlled by `Visited`, + /// `Depth`, and `CreatedValuesCount`). If `Type` is different from + /// `Loc.getType()`, initializes only those fields that are modeled for + /// `Type`. + void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type, + llvm::DenseSet &Visited, int Depth, + int &CreatedValuesCount); + /// Shared implementation of `createObject()` overloads. /// `D` and `InitExpr` may be null. StorageLocation &createObjectInternal(const ValueDecl *D, QualType Ty, @@ -671,27 +733,64 @@ private: ArrayRef Args); /// Assigns storage locations and values to all global variables, fields - /// and functions referenced in `FuncDecl`. `FuncDecl` must have a body. - void initFieldsGlobalsAndFuncs(const FunctionDecl *FuncDecl); + /// and functions in `Referenced`. + void initFieldsGlobalsAndFuncs(const ReferencedDecls &Referenced); + + static PrValueToResultObject + buildResultObjectMap(DataflowAnalysisContext *DACtx, + const FunctionDecl *FuncDecl, + RecordStorageLocation *ThisPointeeLoc, + RecordStorageLocation *LocForRecordReturnVal); + + static PrValueToResultObject + buildResultObjectMap(DataflowAnalysisContext *DACtx, Stmt *S, + RecordStorageLocation *ThisPointeeLoc, + RecordStorageLocation *LocForRecordReturnVal); // `DACtx` is not null and not owned by this object. DataflowAnalysisContext *DACtx; - // FIXME: move the fields `CallStack`, `ReturnVal`, `ReturnLoc` and - // `ThisPointeeLoc` into a separate call-context object, shared between - // environments in the same call. + // FIXME: move the fields `CallStack`, `ResultObjectMap`, `ReturnVal`, + // `ReturnLoc` and `ThisPointeeLoc` into a separate call-context object, + // shared between environments in the same call. // https://github.com/llvm/llvm-project/issues/59005 - // `DeclContext` of the block being analysed if provided. - std::vector CallStack; + // The stack of functions called from the initial analysis target. + std::vector CallStack; - // Value returned by the function (if it has non-reference return type). + // Initial function to analyze, if a function was passed to the constructor. + // Null otherwise. + const FunctionDecl *InitialTargetFunc = nullptr; + // Top-level statement of the initial analysis target. + // If a function was passed to the constructor, this is its body. + // If a statement was passed to the constructor, this is that statement. + // Null if no analysis target was passed to the constructor. + Stmt *InitialTargetStmt = nullptr; + + // Maps from prvalues of record type to their result objects. Shared between + // all environments for the same analysis target. + // FIXME: It's somewhat unsatisfactory that we have to use a `shared_ptr` + // here, though the cost is acceptable: The overhead of a `shared_ptr` is + // incurred when it is copied, and this happens only relatively rarely (when + // we fork the environment). The need for a `shared_ptr` will go away once we + // introduce a shared call-context object (see above). + std::shared_ptr ResultObjectMap; + + // The following three member variables handle various different types of + // return values when the current analysis target is a function. + // - If the return type is not a reference and not a record: Value returned + // by the function. Value *ReturnVal = nullptr; - // Storage location of the reference returned by the function (if it has - // reference return type). + // - If the return type is a reference: Storage location of the reference + // returned by the function. StorageLocation *ReturnLoc = nullptr; + // - If the return type is a record or the function being analyzed is a + // constructor: Storage location into which the return value should be + // constructed. + RecordStorageLocation *LocForRecordReturnVal = nullptr; + // The storage location of the `this` pointee. Should only be null if the - // function being analyzed is only a function and not a method. + // analysis target is not a method. RecordStorageLocation *ThisPointeeLoc = nullptr; // Maps from declarations and glvalue expression to storage locations that are @@ -723,16 +822,6 @@ RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE, RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, const Environment &Env); -/// Returns the fields of `RD` that are initialized by an `InitListExpr`, in the -/// order in which they appear in `InitListExpr::inits()`. -std::vector getFieldsForInitListExpr(const RecordDecl *RD); - -/// Associates a new `RecordValue` with `Loc` and returns the new value. -RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env); - -/// Associates a new `RecordValue` with `Expr` and returns the new value. -RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env); - } // namespace dataflow } // namespace clang diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h index 0c81e2f078c..b262732804e 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h @@ -17,13 +17,13 @@ namespace clang { namespace dataflow { -/// Effect indicating whether a lattice join operation resulted in a new value. -// FIXME: Rename to `LatticeEffect` since `widen` uses it as well, and we are -// likely removing it from `join`. -enum class LatticeJoinEffect { +/// Effect indicating whether a lattice operation resulted in a new value. +enum class LatticeEffect { Unchanged, Changed, }; +// DEPRECATED. Use `LatticeEffect`. +using LatticeJoinEffect = LatticeEffect; } // namespace dataflow } // namespace clang diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h index 2248bcdf3a5..8e88f9c4d9c 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h @@ -45,12 +45,12 @@ class DataflowValues { //===--------------------------------------------------------------------===// public: - typedef typename ValueTypes::ValTy ValTy; - typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy; - typedef _AnalysisDirTag AnalysisDirTag; - typedef llvm::DenseMap EdgeDataMapTy; - typedef llvm::DenseMap BlockDataMapTy; - typedef llvm::DenseMap StmtDataMapTy; + using ValTy = typename ValueTypes::ValTy; + using AnalysisDataTy = typename ValueTypes::AnalysisDataTy; + using AnalysisDirTag = _AnalysisDirTag; + using EdgeDataMapTy = llvm::DenseMap; + using BlockDataMapTy = llvm::DenseMap; + using StmtDataMapTy = llvm::DenseMap; //===--------------------------------------------------------------------===// // Predicates. diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h index f4bd39f6ed4..f2e64810d00 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Logger.h @@ -15,7 +15,7 @@ namespace clang::dataflow { // Forward declarations so we can use Logger anywhere in the framework. -class ControlFlowContext; +class AdornedCFG; class TypeErasedDataflowAnalysis; struct TypeErasedDataflowAnalysisState; @@ -40,8 +40,8 @@ public: /// Called by the framework as we start analyzing a new function or statement. /// Forms a pair with endAnalysis(). - virtual void beginAnalysis(const ControlFlowContext &, - TypeErasedDataflowAnalysis &) {} + virtual void beginAnalysis(const AdornedCFG &, TypeErasedDataflowAnalysis &) { + } virtual void endAnalysis() {} // At any time during the analysis, we're computing the state for some target diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h index 783e53e980a..8fad45fc11d 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/RecordOps.h @@ -31,7 +31,11 @@ namespace dataflow { /// /// Requirements: /// -/// `Src` and `Dst` must have the same canonical unqualified type. +/// Either: +/// - `Src` and `Dest` must have the same canonical unqualified type, or +/// - The type of `Src` must be derived from `Dest`, or +/// - The type of `Dest` must be derived from `Src` (in this case, any fields +/// that are only present in `Dest` are not overwritten). void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env); diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h index 079f6802f24..6166a503ab4 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Solver.h @@ -87,6 +87,9 @@ public: /// /// All elements in `Vals` must not be null. virtual Result solve(llvm::ArrayRef Vals) = 0; + + // Did the solver reach its resource limit? + virtual bool reachedLimit() const = 0; }; llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Solver::Result &); diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h index 7713df747cb..940025e0210 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Transfer.h @@ -29,12 +29,12 @@ public: // `CurState` is the pending state currently associated with this block. These // are supplied separately as the pending state for the current block may not // yet be represented in `BlockToState`. - StmtToEnvMap(const ControlFlowContext &CFCtx, + StmtToEnvMap(const AdornedCFG &ACFG, llvm::ArrayRef> BlockToState, unsigned CurBlockID, const TypeErasedDataflowAnalysisState &CurState) - : CFCtx(CFCtx), BlockToState(BlockToState), CurBlockID(CurBlockID), + : ACFG(ACFG), BlockToState(BlockToState), CurBlockID(CurBlockID), CurState(CurState) {} /// Returns the environment of the basic block that contains `S`. @@ -42,7 +42,7 @@ public: const Environment *getEnvironment(const Stmt &S) const; private: - const ControlFlowContext &CFCtx; + const AdornedCFG &ACFG; llvm::ArrayRef> BlockToState; unsigned CurBlockID; const TypeErasedDataflowAnalysisState &CurState; @@ -53,7 +53,8 @@ private: /// Requirements: /// /// `S` must not be `ParenExpr` or `ExprWithCleanups`. -void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env); +void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, + Environment::ValueModel &Model); } // namespace dataflow } // namespace clang diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h index a0ca7440230..512453e2be6 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h @@ -21,7 +21,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" #include "clang/Analysis/CFG.h" -#include "clang/Analysis/FlowSensitive/ControlFlowContext.h" +#include "clang/Analysis/FlowSensitive/AdornedCFG.h" #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" @@ -132,12 +132,25 @@ struct TypeErasedDataflowAnalysisState { } }; +/// A callback to be called with the state before or after visiting a CFG +/// element. +using CFGEltCallbackTypeErased = std::function; + +/// A pair of callbacks to be called with the state before and after visiting a +/// CFG element. +/// Either or both of the callbacks may be null. +struct CFGEltCallbacksTypeErased { + CFGEltCallbackTypeErased Before; + CFGEltCallbackTypeErased After; +}; + /// Performs dataflow analysis and returns a mapping from basic block IDs to /// dataflow analysis states that model the respective basic blocks. Indices of /// the returned vector correspond to basic block IDs. Returns an error if the /// dataflow analysis cannot be performed successfully. Otherwise, calls -/// `PostVisitCFG` on each CFG element with the final analysis results at that -/// program point. +/// `PostAnalysisCallbacks` on each CFG element with the final analysis results +/// before and after that program point. /// /// `MaxBlockVisits` caps the number of block visits during analysis. It doesn't /// distinguish between repeat visits to the same block and visits to distinct @@ -146,11 +159,9 @@ struct TypeErasedDataflowAnalysisState { /// from converging. llvm::Expected>> runTypeErasedDataflowAnalysis( - const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis, + const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis, const Environment &InitEnv, - std::function - PostVisitCFG, + const CFGEltCallbacksTypeErased &PostAnalysisCallbacks, std::int32_t MaxBlockVisits); } // namespace dataflow diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h index be1bf9324c8..97efa3a93ce 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/Value.h @@ -35,7 +35,6 @@ public: enum class Kind { Integer, Pointer, - Record, // TODO: Top values should not be need to be type-specific. TopBool, @@ -67,7 +66,6 @@ public: /// Properties may not be set on `RecordValue`s; use synthetic fields instead /// (for details, see documentation for `RecordStorageLocation`). void setProperty(llvm::StringRef Name, Value &Val) { - assert(getKind() != Kind::Record); Properties.insert_or_assign(Name, &Val); } @@ -184,45 +182,6 @@ private: StorageLocation &PointeeLoc; }; -/// Models a value of `struct` or `class` type. -/// In C++, prvalues of class type serve only a limited purpose: They can only -/// be used to initialize a result object. It is not possible to access member -/// variables or call member functions on a prvalue of class type. -/// Correspondingly, `RecordValue` also serves only a limited purpose: It -/// conveys a prvalue of class type from the place where the object is -/// constructed to the result object that it initializes. -/// -/// When creating a prvalue of class type, we already need a storage location -/// for `this`, even though prvalues are otherwise not associated with storage -/// locations. `RecordValue` is therefore essentially a wrapper for a storage -/// location, which is then used to set the storage location for the result -/// object when we process the AST node for that result object. -/// -/// For example: -/// MyStruct S = MyStruct(3); -/// -/// In this example, `MyStruct(3) is a prvalue, which is modeled as a -/// `RecordValue` that wraps a `RecordStorageLocation`. This -/// `RecordStorageLocation` is then used as the storage location for `S`. -/// -/// Over time, we may eliminate `RecordValue` entirely. See also the discussion -/// here: https://reviews.llvm.org/D155204#inline-1503204 -class RecordValue final : public Value { -public: - explicit RecordValue(RecordStorageLocation &Loc) - : Value(Kind::Record), Loc(Loc) {} - - static bool classof(const Value *Val) { - return Val->getKind() == Kind::Record; - } - - /// Returns the storage location that this `RecordValue` is associated with. - RecordStorageLocation &getLoc() const { return Loc; } - -private: - RecordStorageLocation &Loc; -}; - raw_ostream &operator<<(raw_ostream &OS, const Value &Val); } // namespace dataflow diff --git a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h index 5448eecf6d4..d74380b78e9 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h @@ -17,16 +17,17 @@ #include "clang/Analysis/FlowSensitive/Formula.h" #include "clang/Analysis/FlowSensitive/Solver.h" #include "llvm/ADT/ArrayRef.h" -#include namespace clang { namespace dataflow { /// A SAT solver that is an implementation of Algorithm D from Knuth's The Art /// of Computer Programming Volume 4: Satisfiability, Fascicle 6. It is based on -/// the Davis-Putnam-Logemann-Loveland (DPLL) algorithm, keeps references to a -/// single "watched" literal per clause, and uses a set of "active" variables +/// the Davis-Putnam-Logemann-Loveland (DPLL) algorithm [1], keeps references to +/// a single "watched" literal per clause, and uses a set of "active" variables /// for unit propagation. +// +// [1] https://en.wikipedia.org/wiki/DPLL_algorithm class WatchedLiteralsSolver : public Solver { // Count of the iterations of the main loop of the solver. This spans *all* // calls to the underlying solver across the life of this object. It is @@ -48,8 +49,7 @@ public: Result solve(llvm::ArrayRef Vals) override; - // The solver reached its maximum number of iterations. - bool reachedLimit() const { return MaxIterations == 0; } + bool reachedLimit() const override { return MaxIterations == 0; } }; } // namespace dataflow diff --git a/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h b/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h index 90559e7efb0..5907df022e4 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/PathDiagnostic.h @@ -780,6 +780,9 @@ class PathDiagnostic : public llvm::FoldingSetNode { PathDiagnosticLocation UniqueingLoc; const Decl *UniqueingDecl; + /// The top-level entry point from which this issue was discovered. + const Decl *AnalysisEntryPoint = nullptr; + /// Lines executed in the path. std::unique_ptr ExecutedLines; @@ -788,7 +791,7 @@ public: PathDiagnostic(StringRef CheckerName, const Decl *DeclWithIssue, StringRef bugtype, StringRef verboseDesc, StringRef shortDesc, StringRef category, PathDiagnosticLocation LocationToUnique, - const Decl *DeclToUnique, + const Decl *DeclToUnique, const Decl *AnalysisEntryPoint, std::unique_ptr ExecutedLines); ~PathDiagnostic(); @@ -852,6 +855,9 @@ public: return *ExecutedLines; } + /// Get the top-level entry point from which this issue was discovered. + const Decl *getAnalysisEntryPoint() const { return AnalysisEntryPoint; } + /// Return the semantic context where an issue occurred. If the /// issue occurs along a path, this represents the "central" area /// where the bug manifests. diff --git a/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h b/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h index 1e1daf5706b..ac2c2519bea 100644 --- a/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h +++ b/contrib/llvm-project/clang/include/clang/Analysis/SelectorExtras.h @@ -15,10 +15,10 @@ namespace clang { template static inline Selector getKeywordSelector(ASTContext &Ctx, - IdentifierInfos *... IIs) { + const IdentifierInfos *...IIs) { static_assert(sizeof...(IdentifierInfos) > 0, "keyword selectors must have at least one argument"); - SmallVector II({&Ctx.Idents.get(IIs)...}); + SmallVector II({&Ctx.Idents.get(IIs)...}); return Ctx.Selectors.getSelector(II.size(), &II[0]); } diff --git a/contrib/llvm-project/clang/include/clang/Basic/AMDGPUTypes.def b/contrib/llvm-project/clang/include/clang/Basic/AMDGPUTypes.def new file mode 100644 index 00000000000..e0d7be470a3 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/AMDGPUTypes.def @@ -0,0 +1,21 @@ +//===-- AMDGPUTypes.def - Metadata about AMDGPU types -----------*- 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 various AMDGPU builtin types. +// +//===----------------------------------------------------------------------===// + +#ifndef AMDGPU_OPAQUE_PTR_TYPE +#define AMDGPU_OPAQUE_PTR_TYPE(Name, MangledName, AS, Width, Align, Id, SingletonId) \ + AMDGPU_TYPE(Name, Id, SingletonId) +#endif + +AMDGPU_OPAQUE_PTR_TYPE("__amdgpu_buffer_rsrc_t", "__amdgpu_buffer_rsrc_t", 8, 128, 128, AMDGPUBufferRsrc, AMDGPUBufferRsrcTy) + +#undef AMDGPU_TYPE +#undef AMDGPU_OPAQUE_PTR_TYPE diff --git a/contrib/llvm-project/clang/include/clang/Basic/ASTSourceDescriptor.h b/contrib/llvm-project/clang/include/clang/Basic/ASTSourceDescriptor.h new file mode 100644 index 00000000000..175e0551db7 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/ASTSourceDescriptor.h @@ -0,0 +1,52 @@ +//===- ASTSourceDescriptor.h -----------------------------*- 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 +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Defines the clang::ASTSourceDescriptor class, which abstracts clang modules +/// and precompiled header files +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H +#define LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H + +#include "clang/Basic/Module.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +namespace clang { + +/// Abstracts clang modules and precompiled header files and holds +/// everything needed to generate debug info for an imported module +/// or PCH. +class ASTSourceDescriptor { + StringRef PCHModuleName; + StringRef Path; + StringRef ASTFile; + ASTFileSignature Signature; + Module *ClangModule = nullptr; + +public: + ASTSourceDescriptor() = default; + ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, + ASTFileSignature Signature) + : PCHModuleName(std::move(Name)), Path(std::move(Path)), + ASTFile(std::move(ASTFile)), Signature(Signature) {} + ASTSourceDescriptor(Module &M); + + std::string getModuleName() const; + StringRef getPath() const { return Path; } + StringRef getASTFile() const { return ASTFile; } + ASTFileSignature getSignature() const { return Signature; } + Module *getModuleOrNull() const { return ClangModule; } +}; + +} // namespace clang + +#endif // LLVM_CLANG_BASIC_ASTSOURCEDESCRIPTOR_H diff --git a/contrib/llvm-project/clang/include/clang/Basic/AllDiagnostics.h b/contrib/llvm-project/clang/include/clang/Basic/AllDiagnostics.h index cc6aa631534..e64634cc138 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AllDiagnostics.h +++ b/contrib/llvm-project/clang/include/clang/Basic/AllDiagnostics.h @@ -20,6 +20,7 @@ #include "clang/Basic/DiagnosticCrossTU.h" #include "clang/Basic/DiagnosticDriver.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/DiagnosticInstallAPI.h" #include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/DiagnosticSema.h" diff --git a/contrib/llvm-project/clang/include/clang/Basic/Attr.td b/contrib/llvm-project/clang/include/clang/Basic/Attr.td index dbf2dd2120f..4825979a974 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Attr.td +++ b/contrib/llvm-project/clang/include/clang/Basic/Attr.td @@ -284,26 +284,39 @@ class DefaultIntArgument : IntArgument { // This argument is more complex, it includes the enumerator type // name, whether the enum type is externally defined, a list of -// strings to accept, and a list of enumerators to map them to. -class EnumArgument values, +// possible values, and a list of enumerators to map them to. +class EnumArgument values, list enums, bit opt = 0, bit fake = 0, - bit isExternalType = 0> + bit isExternalType = 0, bit isCovered = 1> : Argument { string Type = type; + // When true, the argument will be parsed as an unevaluated string literal + // and otherwise as an identifier. + bit IsString = is_string; list Values = values; list Enums = enums; bit IsExternalType = isExternalType; + // We need to know whether an external enum is fully covered by the options + // in order to decide whether to emit unreachable default labels in a switch. + bit IsCovered = isCovered; } // FIXME: There should be a VariadicArgument type that takes any other type // of argument and generates the appropriate type. -class VariadicEnumArgument values, - list enums, bit isExternalType = 0> +class VariadicEnumArgument values, list enums, + bit isExternalType = 0, bit isCovered = 1> : Argument { string Type = type; + // When true, the argument will be parsed as an unevaluated string literal + // and otherwise as an identifier. + bit IsString = is_string; list Values = values; list Enums = enums; bit IsExternalType = isExternalType; + // We need to know whether an external enum is fully covered by the options + // in order to decide whether to emit unreachable default labels in a switch. + bit IsCovered = isCovered; } // Represents an attribute wrapped by another attribute. @@ -317,13 +330,10 @@ class Spelling { } class GNU : Spelling; -class Declspec : Spelling { - bit PrintOnLeft = 1; -} +class Declspec : Spelling; class Microsoft : Spelling; class CXX11 : Spelling { - bit CanPrintOnLeft = 0; string Namespace = namespace; } class C23 @@ -364,8 +374,8 @@ class Clang bit AllowInC = allowInC; } -// HLSL Semantic spellings -class HLSLSemantic : Spelling; +// HLSL Annotation spellings +class HLSLAnnotation : Spelling; class Accessor spellings> { string Name = name; @@ -588,13 +598,50 @@ class AttrSubjectMatcherAggregateRule { def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule; +// Enumeration specifying what kind of behavior should be used for late +// parsing of attributes. +class LateAttrParseKind { + int Kind = val; +} + +// Never late parsed +def LateAttrParseNever : LateAttrParseKind<0>; + +// Standard late attribute parsing +// +// This is language dependent. For example: +// +// * For C++ enables late parsing of a declaration attributes +// * For C does not enable late parsing of attributes +// +def LateAttrParseStandard : LateAttrParseKind<1>; + +// Experimental extension to standard late attribute parsing +// +// This extension behaves like `LateAttrParseStandard` but allows +// late parsing attributes in more contexts. +// +// In contexts where `LateAttrParseStandard` attributes are late +// parsed, `LateAttrParseExperimentalExt` attributes will also +// be late parsed. +// +// In contexts that only late parse `LateAttrParseExperimentalExt` attributes +// (see `LateParsedAttrList::lateAttrParseExperimentalExtOnly()`) +// +// * If `-fexperimental-late-parse-attributes` +// (`LangOpts.ExperimentalLateParseAttributes`) is enabled the attribute +// will be late parsed. +// * If `-fexperimental-late-parse-attributes` +// (`LangOpts.ExperimentalLateParseAttributes`) is disabled the attribute +// will **not** be late parsed (i.e parsed immediately). +// +// The following contexts are supported: +// +// * TODO: Add contexts here when they are implemented. +// +def LateAttrParseExperimentalExt : LateAttrParseKind<2>; + class Attr { - // Specifies that when printed, this attribute is meaningful on the - // 'left side' of the declaration. - bit CanPrintOnLeft = 1; - // Specifies that when printed, this attribute is required to be printed on - // the 'left side' of the declaration. - bit PrintOnLeft = 0; // The various ways in which an attribute can be spelled in source list Spellings; // The things to which an attribute can appertain @@ -605,8 +652,8 @@ class Attr { list Accessors = []; // Specify targets for spellings. list TargetSpecificSpellings = []; - // Set to true for attributes with arguments which require delayed parsing. - bit LateParsed = 0; + // Specifies the late parsing kind. + LateAttrParseKind LateParsed = LateAttrParseNever; // Set to false to prevent an attribute from being propagated from a template // to the instantiation. bit Clone = 1; @@ -639,6 +686,10 @@ class Attr { bit PragmaAttributeSupport; // Set to true if this attribute accepts parameter pack expansion expressions. bit AcceptsExprPack = 0; + // To support multiple enum parameters to an attribute without breaking + // our existing general parsing we need to have a separate flag that + // opts an attribute into strict parsing of attribute parameters + bit StrictEnumParameters = 0; // Lists language options, one of which is required to be true for the // attribute to be applicable. If empty, no language options are required. list LangOpts = []; @@ -851,7 +902,7 @@ def PatchableFunctionEntry : InheritableAttr, TargetSpecificAttr> { + "riscv64", "x86", "x86_64", "ppc", "ppc64"]>> { let Spellings = [GCC<"patchable_function_entry">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>]; @@ -907,7 +958,7 @@ def ARMInterrupt : InheritableAttr, TargetSpecificAttr { // MSP430Interrupt's, MipsInterrupt's and AnyX86Interrupt's spellings // must match. let Spellings = [GCC<"interrupt">]; - let Args = [EnumArgument<"Interrupt", "InterruptType", + let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true, ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"], 1>]; @@ -930,7 +981,6 @@ def AVRSignal : InheritableAttr, TargetSpecificAttr { } def AsmLabel : InheritableAttr { - let CanPrintOnLeft = 0; let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">]; let Args = [ // Label specifies the mangled name for the decl. @@ -959,7 +1009,7 @@ def Availability : InheritableAttr { VersionArgument<"deprecated">, VersionArgument<"obsoleted">, BoolArgument<"unavailable">, StringArgument<"message">, BoolArgument<"strict">, StringArgument<"replacement">, - IntArgument<"priority">]; + IntArgument<"priority">, IdentifierArgument<"environment">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) @@ -976,8 +1026,10 @@ def Availability : InheritableAttr { .Case("watchos_app_extension", "watchOS (App Extension)") .Case("maccatalyst", "macCatalyst") .Case("maccatalyst_app_extension", "macCatalyst (App Extension)") + .Case("xros", "visionOS") + .Case("xros_app_extension", "visionOS (App Extension)") .Case("swift", "Swift") - .Case("shadermodel", "HLSL ShaderModel") + .Case("shadermodel", "Shader Model") .Case("ohos", "OpenHarmony OS") .Default(llvm::StringRef()); } @@ -993,6 +1045,8 @@ static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) { .Case("watchos_app_extension", "watchOSApplicationExtension") .Case("maccatalyst", "macCatalyst") .Case("maccatalyst_app_extension", "macCatalystApplicationExtension") + .Case("xros", "visionOS") + .Case("xros_app_extension", "visionOSApplicationExtension") .Case("zos", "z/OS") .Case("shadermodel", "ShaderModel") .Default(Platform); @@ -1009,9 +1063,33 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) { .Case("watchOSApplicationExtension", "watchos_app_extension") .Case("macCatalyst", "maccatalyst") .Case("macCatalystApplicationExtension", "maccatalyst_app_extension") + .Case("visionOS", "xros") + .Case("visionOSApplicationExtension", "xros_app_extension") + .Case("visionos", "xros") + .Case("visionos_app_extension", "xros_app_extension") .Case("ShaderModel", "shadermodel") .Default(Platform); -} }]; +} +static llvm::Triple::EnvironmentType getEnvironmentType(llvm::StringRef Environment) { + return llvm::StringSwitch(Environment) + .Case("pixel", llvm::Triple::Pixel) + .Case("vertex", llvm::Triple::Vertex) + .Case("geometry", llvm::Triple::Geometry) + .Case("hull", llvm::Triple::Hull) + .Case("domain", llvm::Triple::Domain) + .Case("compute", llvm::Triple::Compute) + .Case("raygeneration", llvm::Triple::RayGeneration) + .Case("intersection", llvm::Triple::Intersection) + .Case("anyhit", llvm::Triple::AnyHit) + .Case("closesthit", llvm::Triple::ClosestHit) + .Case("miss", llvm::Triple::Miss) + .Case("callable", llvm::Triple::Callable) + .Case("mesh", llvm::Triple::Mesh) + .Case("amplification", llvm::Triple::Amplification) + .Case("library", llvm::Triple::Library) + .Default(llvm::Triple::UnknownEnvironment); +} +}]; let HasCustomParsing = 1; let InheritEvenIfAlreadyPresent = 1; let Subjects = SubjectList<[Named]>; @@ -1032,7 +1110,8 @@ def ExternalSourceSymbol : InheritableAttr { def Blocks : InheritableAttr { let Spellings = [Clang<"blocks">]; - let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>]; + let Args = [EnumArgument<"Type", "BlockType", /*is_string=*/true, + ["byref"], ["ByRef"]>]; let Documentation = [Undocumented]; } @@ -1386,6 +1465,28 @@ def CXX11NoReturn : InheritableAttr { let Documentation = [CXX11NoReturnDocs]; } +def NonBlocking : TypeAttr { + let Spellings = [Clang<"nonblocking">]; + let Args = [ExprArgument<"Cond", /*optional*/1>]; + let Documentation = [NonBlockingDocs]; +} + +def NonAllocating : TypeAttr { + let Spellings = [Clang<"nonallocating">]; + let Args = [ExprArgument<"Cond", /*optional*/1>]; + let Documentation = [NonAllocatingDocs]; +} + +def Blocking : TypeAttr { + let Spellings = [Clang<"blocking">]; + let Documentation = [BlockingDocs]; +} + +def Allocating : TypeAttr { + let Spellings = [Clang<"allocating">]; + let Documentation = [AllocatingDocs]; +} + // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because // the specification does not expose them with one currently. def OpenCLKernel : InheritableAttr { @@ -1518,7 +1619,6 @@ def AllocSize : InheritableAttr { } def EnableIf : InheritableAttr { - let CanPrintOnLeft = 0; // Does not have a [[]] spelling because this attribute requires the ability // to parse function arguments but the attribute is not written in the type // position. @@ -1564,6 +1664,14 @@ def Unlikely : StmtAttr { } def : MutualExclusions<[Likely, Unlikely]>; +def CXXAssume : StmtAttr { + let Spellings = [CXX11<"", "assume", 202207>, Clang<"assume">]; + let Subjects = SubjectList<[NullStmt], ErrorDiag, "empty statements">; + let Args = [ExprArgument<"Assumption">]; + let Documentation = [CXXAssumeDocs]; + let HasCustomParsing = 1; +} + def NoMerge : DeclOrStmtAttr { let Spellings = [Clang<"nomerge">]; let Documentation = [NoMergeDocs]; @@ -1590,7 +1698,6 @@ def RegCall : DeclOrTypeAttr { } def Final : InheritableAttr { - let CanPrintOnLeft = 0; let Spellings = [CustomKeyword<"final">, CustomKeyword<"sealed">]; let Accessors = [Accessor<"isSpelledAsSealed", [CustomKeyword<"sealed">]>]; let SemaHandler = 0; @@ -1615,7 +1722,7 @@ def FlagEnum : InheritableAttr { def EnumExtensibility : InheritableAttr { let Spellings = [Clang<"enum_extensibility">]; let Subjects = SubjectList<[Enum]>; - let Args = [EnumArgument<"Extensibility", "Kind", + let Args = [EnumArgument<"Extensibility", "Kind", /*is_string=*/false, ["closed", "open"], ["Closed", "Open"]>]; let Documentation = [EnumExtensibilityDocs]; } @@ -1781,7 +1888,7 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr { // must match. let Spellings = [GCC<"interrupt">]; let Subjects = SubjectList<[Function]>; - let Args = [EnumArgument<"Interrupt", "InterruptType", + let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true, ["vector=sw0", "vector=sw1", "vector=hw0", "vector=hw1", "vector=hw2", "vector=hw3", "vector=hw4", "vector=hw5", "eic", ""], @@ -1943,9 +2050,12 @@ def Convergent : InheritableAttr { def NoInline : DeclOrStmtAttr { let Spellings = [CustomKeyword<"__noinline__">, GCC<"noinline">, CXX11<"clang", "noinline">, C23<"clang", "noinline">, + CXX11<"msvc", "noinline">, C23<"msvc", "noinline">, Declspec<"noinline">]; - let Accessors = [Accessor<"isClangNoInline", [CXX11<"clang", "noinline">, - C23<"clang", "noinline">]>]; + let Accessors = [Accessor<"isStmtNoInline", [CXX11<"clang", "noinline">, + C23<"clang", "noinline">, + CXX11<"msvc", "noinline">, + C23<"msvc", "noinline">]>]; let Documentation = [NoInlineDocs]; let Subjects = SubjectList<[Function, Stmt], WarnDiag, "functions and statements">; @@ -1969,7 +2079,7 @@ def NoMicroMips : InheritableAttr, TargetSpecificAttr { def RISCVInterrupt : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"interrupt">]; let Subjects = SubjectList<[Function]>; - let Args = [EnumArgument<"Interrupt", "InterruptType", + let Args = [EnumArgument<"Interrupt", "InterruptType", /*is_string=*/true, ["supervisor", "machine"], ["supervisor", "machine"], 1>]; @@ -2032,6 +2142,13 @@ def AMDGPUNumVGPR : InheritableAttr { let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; } +def AMDGPUMaxNumWorkGroups : InheritableAttr { + let Spellings = [Clang<"amdgpu_max_num_work_groups", 0>]; + let Args = [ExprArgument<"MaxNumWorkGroupsX">, ExprArgument<"MaxNumWorkGroupsY", 1>, ExprArgument<"MaxNumWorkGroupsZ", 1>]; + let Documentation = [AMDGPUMaxNumWorkGroupsDocs]; + let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">; +} + def AMDGPUKernelCall : DeclOrTypeAttr { let Spellings = [Clang<"amdgpu_kernel">]; let Documentation = [Undocumented]; @@ -2149,9 +2266,10 @@ def TypeNonNull : TypeAttr { let Documentation = [TypeNonNullDocs]; } -def TypeNullable : TypeAttr { +def TypeNullable : DeclOrTypeAttr { let Spellings = [CustomKeyword<"_Nullable">]; let Documentation = [TypeNullableDocs]; +// let Subjects = SubjectList<[CXXRecord], ErrorDiag>; } def TypeNullableResult : TypeAttr { @@ -2164,6 +2282,46 @@ def TypeNullUnspecified : TypeAttr { let Documentation = [TypeNullUnspecifiedDocs]; } +def CountedBy : DeclOrTypeAttr { + let Spellings = [Clang<"counted_by">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel", 1>]; + let LateParsed = LateAttrParseExperimentalExt; + let ParseArgumentsAsUnevaluated = 1; + let Documentation = [CountedByDocs]; + let LangOpts = [COnly]; +} + +def CountedByOrNull : DeclOrTypeAttr { + let Spellings = [Clang<"counted_by_or_null">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Args = [ExprArgument<"Count">, IntArgument<"NestedLevel", 1>]; + let LateParsed = LateAttrParseExperimentalExt; + let ParseArgumentsAsUnevaluated = 1; + let Documentation = [CountedByDocs]; + let LangOpts = [COnly]; +} + +def SizedBy : DeclOrTypeAttr { + let Spellings = [Clang<"sized_by">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Args = [ExprArgument<"Size">, IntArgument<"NestedLevel", 1>]; + let LateParsed = LateAttrParseExperimentalExt; + let ParseArgumentsAsUnevaluated = 1; + let Documentation = [CountedByDocs]; + let LangOpts = [COnly]; +} + +def SizedByOrNull : DeclOrTypeAttr { + let Spellings = [Clang<"sized_by_or_null">]; + let Subjects = SubjectList<[Field], ErrorDiag>; + let Args = [ExprArgument<"Size">, IntArgument<"NestedLevel", 1>]; + let LateParsed = LateAttrParseExperimentalExt; + let ParseArgumentsAsUnevaluated = 1; + let Documentation = [CountedByDocs]; + let LangOpts = [COnly]; +} + // This is a marker used to indicate that an __unsafe_unretained qualifier was // ignored because ARC is not enabled. The usual representation for this // qualifier is as an ObjCOwnership attribute with Kind == "none". @@ -2340,7 +2498,7 @@ def ObjCException : InheritableAttr { def ObjCMethodFamily : InheritableAttr { let Spellings = [Clang<"objc_method_family">]; let Subjects = SubjectList<[ObjCMethod], ErrorDiag>; - let Args = [EnumArgument<"Family", "FamilyKind", + let Args = [EnumArgument<"Family", "FamilyKind", /*is_string=*/false, ["none", "alloc", "copy", "init", "mutableCopy", "new"], ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init", "OMF_mutableCopy", "OMF_new"]>]; @@ -2473,7 +2631,6 @@ def Overloadable : Attr { } def Override : InheritableAttr { - let CanPrintOnLeft = 0; let Spellings = [CustomKeyword<"override">]; let SemaHandler = 0; // Omitted from docs, since this is language syntax, not an attribute, as far @@ -2515,7 +2672,7 @@ def IntelOclBicc : DeclOrTypeAttr { def Pcs : DeclOrTypeAttr { let Spellings = [GCC<"pcs">]; - let Args = [EnumArgument<"PCS", "PCSType", + let Args = [EnumArgument<"PCS", "PCSType", /*is_string=*/true, ["aapcs", "aapcs-vfp"], ["AAPCS", "AAPCS_VFP"]>]; // let Subjects = [Function, ObjCMethod]; @@ -2648,7 +2805,7 @@ def SwiftObjCMembers : Attr { def SwiftError : InheritableAttr { let Spellings = [GNU<"swift_error">]; let Args = [ - EnumArgument<"Convention", "ConventionKind", + EnumArgument<"Convention", "ConventionKind", /*is_string=*/false, ["none", "nonnull_error", "null_result", "zero_result", "nonzero_result"], ["None", "NonNullError", "NullResult", "ZeroResult", "NonZeroResult"]> ]; @@ -2680,7 +2837,7 @@ def SwiftName : InheritableAttr { def SwiftNewType : InheritableAttr { let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">]; - let Args = [EnumArgument<"NewtypeKind", "NewtypeKind", + let Args = [EnumArgument<"NewtypeKind", "NewtypeKind", /*is_string=*/false, ["struct", "enum"], ["NK_Struct", "NK_Enum"]>]; let Subjects = SubjectList<[TypedefName], ErrorDiag>; let Documentation = [SwiftNewTypeDocs]; @@ -2816,9 +2973,9 @@ def PragmaClangTextSection : InheritableAttr { def CodeModel : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"model">]; - let Args = [EnumArgument<"Model", "llvm::CodeModel::Model", + let Args = [EnumArgument<"Model", "llvm::CodeModel::Model", /*is_string=*/1, ["normal", "medium", "extreme"], ["Small", "Medium", "Large"], - /*opt=*/0, /*fake=*/0, /*isExternalType=*/1>]; + /*opt=*/0, /*fake=*/0, /*isExternalType=*/1, /*isCovered=*/0>]; let Subjects = SubjectList<[NonTLSGlobalVar], ErrorDiag>; let Documentation = [CodeModelDocs]; } @@ -2872,7 +3029,7 @@ def SwiftIndirectResult : ParameterABIAttr { def SwiftAsync : InheritableAttr { let Spellings = [Clang<"swift_async">]; let Subjects = SubjectList<[Function, ObjCMethod]>; - let Args = [EnumArgument<"Kind", "Kind", + let Args = [EnumArgument<"Kind", "Kind", /*is_string=*/false, ["none", "swift_private", "not_swift_private"], ["None", "SwiftPrivate", "NotSwiftPrivate"]>, ParamIdxArgument<"CompletionHandlerIndex", /*opt=*/1>]; @@ -2882,7 +3039,7 @@ def SwiftAsync : InheritableAttr { def SwiftAsyncError : InheritableAttr { let Spellings = [Clang<"swift_async_error">]; let Subjects = SubjectList<[Function, ObjCMethod]>; - let Args = [EnumArgument<"Convention", "ConventionKind", + let Args = [EnumArgument<"Convention", "ConventionKind", /*is_string=*/false, ["none", "nonnull_error", "zero_argument", "nonzero_argument"], ["None", "NonNullError", "ZeroArgument", "NonZeroArgument"]>, UnsignedArgument<"HandlerParamIdx", /*opt=*/1>]; @@ -2893,13 +3050,20 @@ def Suppress : DeclOrStmtAttr { let Spellings = [CXX11<"gsl", "suppress">, Clang<"suppress">]; let Args = [VariadicStringArgument<"DiagnosticIdentifiers">]; let Accessors = [Accessor<"isGSL", [CXX11<"gsl", "suppress">]>]; + // There's no fundamental reason why we can't simply accept all Decls + // but let's make a short list so that to avoid supporting something weird + // by accident. We can always expand the list later. + let Subjects = SubjectList<[ + Stmt, Var, Field, ObjCProperty, Function, ObjCMethod, Record, ObjCInterface, + ObjCImplementation, Namespace, Empty + ], ErrorDiag, "variables, functions, structs, interfaces, and namespaces">; let Documentation = [SuppressDocs]; } def SysVABI : DeclOrTypeAttr { let Spellings = [GCC<"sysv_abi">]; // let Subjects = [Function, ObjCMethod]; - let Documentation = [Undocumented]; + let Documentation = [SysVABIDocs]; } def ThisCall : DeclOrTypeAttr { @@ -2920,7 +3084,7 @@ def ZeroCallUsedRegs : InheritableAttr { let Spellings = [GCC<"zero_call_used_regs">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Args = [ - EnumArgument<"ZeroCallUsedRegs", "ZeroCallUsedRegsKind", + EnumArgument<"ZeroCallUsedRegs", "ZeroCallUsedRegsKind", /*is_string=*/true, ["skip", "used-gpr-arg", "used-gpr", "used-arg", "used", "all-gpr-arg", "all-gpr", "all-arg", "all"], ["Skip", "UsedGPRArg", "UsedGPR", "UsedArg", "Used", @@ -2961,6 +3125,20 @@ def M68kRTD: DeclOrTypeAttr { let Documentation = [M68kRTDDocs]; } +def PreserveNone : DeclOrTypeAttr, + TargetSpecificAttr> { + let Spellings = [Clang<"preserve_none">]; + let Subjects = SubjectList<[FunctionLike]>; + let Documentation = [PreserveNoneDocs]; +} + +def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr { + let Spellings = [CXX11<"riscv", "vector_cc">, + C23<"riscv", "vector_cc">, + Clang<"riscv_vector_cc">]; + let Documentation = [RISCVVectorCCDocs]; +} + def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; @@ -3038,6 +3216,20 @@ def TargetClones : InheritableAttr { StringRef getFeatureStr(unsigned Index) const { return *(featuresStrs_begin() + Index); } + bool isDefaultVersion(unsigned Index) const { + return getFeatureStr(Index) == "default"; + } + void getFeatures(llvm::SmallVectorImpl &Out, + unsigned Index) const { + if (isDefaultVersion(Index)) return; + StringRef Features = getFeatureStr(Index); + SmallVector AttrFeatures; + Features.split(AttrFeatures, "+"); + for (auto &Feature : AttrFeatures) { + Feature = Feature.trim(); + Out.push_back(Feature); + } + } // Given an index into the 'featuresStrs' sequence, compute a unique // ID to be used with function name mangling for the associated variant. // This mapping is necessary due to a requirement that the mangling ID @@ -3086,7 +3278,7 @@ def TransparentUnion : InheritableAttr { def Unavailable : InheritableAttr { let Spellings = [Clang<"unavailable">]; let Args = [StringArgument<"Message", 1>, - EnumArgument<"ImplicitReason", "ImplicitReason", + EnumArgument<"ImplicitReason", "ImplicitReason", /*is_string=*/0, // FIXME ["", "", "", ""], ["IR_None", "IR_ARCForbiddenType", @@ -3099,21 +3291,20 @@ def Unavailable : InheritableAttr { } def DiagnoseIf : InheritableAttr { - let CanPrintOnLeft = 0; // Does not have a [[]] spelling because this attribute requires the ability // to parse function arguments but the attribute is not written in the type // position. let Spellings = [GNU<"diagnose_if">]; let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>; let Args = [ExprArgument<"Cond">, StringArgument<"Message">, - EnumArgument<"DiagnosticType", - "DiagnosticType", + EnumArgument<"DiagnosticType", "DiagnosticType", + /*is_string=*/true, ["error", "warning"], ["DT_Error", "DT_Warning"]>, BoolArgument<"ArgDependent", 0, /*fake*/ 1>, DeclArgument]; let InheritEvenIfAlreadyPresent = 1; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let AdditionalMembers = [{ bool isError() const { return diagnosticType == DT_Error; } bool isWarning() const { return diagnosticType == DT_Warning; } @@ -3151,7 +3342,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr { def Unused : InheritableAttr { let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">, C23<"", "maybe_unused", 202106>]; - let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label, + let Subjects = SubjectList<[Var, Binding, ObjCIvar, Type, Enum, EnumConstant, Label, Field, ObjCMethod, FunctionLike]>; let Documentation = [WarnMaybeUnusedDocs]; } @@ -3209,7 +3400,7 @@ def MatrixType : TypeAttr { def Visibility : InheritableAttr { let Clone = 0; let Spellings = [GCC<"visibility">]; - let Args = [EnumArgument<"Visibility", "VisibilityType", + let Args = [EnumArgument<"Visibility", "VisibilityType", /*is_string=*/true, ["default", "hidden", "internal", "protected"], ["Default", "Hidden", "Hidden", "Protected"]>]; let MeaningfulToClassTemplateDefinition = 1; @@ -3219,11 +3410,11 @@ def Visibility : InheritableAttr { def TypeVisibility : InheritableAttr { let Clone = 0; let Spellings = [Clang<"type_visibility">]; - let Args = [EnumArgument<"Visibility", "VisibilityType", + let Args = [EnumArgument<"Visibility", "VisibilityType", /*is_string=*/true, ["default", "hidden", "internal", "protected"], ["Default", "Hidden", "Hidden", "Protected"]>]; -// let Subjects = [Tag, ObjCInterface, Namespace]; - let Documentation = [Undocumented]; + // let Subjects = SubjectList<[Tag, ObjCInterface, Namespace], ErrorDiag>; + let Documentation = [TypeVisibilityDocs]; } def VecReturn : InheritableAttr { @@ -3412,7 +3603,7 @@ def AssertCapability : InheritableAttr { let Spellings = [Clang<"assert_capability", 0>, Clang<"assert_shared_capability", 0>]; let Subjects = SubjectList<[Function]>; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3428,7 +3619,7 @@ def AcquireCapability : InheritableAttr { GNU<"exclusive_lock_function">, GNU<"shared_lock_function">]; let Subjects = SubjectList<[Function]>; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3444,7 +3635,7 @@ def TryAcquireCapability : InheritableAttr { Clang<"try_acquire_shared_capability", 0>]; let Subjects = SubjectList<[Function], ErrorDiag>; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3460,7 +3651,7 @@ def ReleaseCapability : InheritableAttr { Clang<"release_generic_capability", 0>, Clang<"unlock_function", 0>]; let Subjects = SubjectList<[Function]>; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3479,7 +3670,7 @@ def RequiresCapability : InheritableAttr { Clang<"requires_shared_capability", 0>, Clang<"shared_locks_required", 0>]; let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3499,7 +3690,7 @@ def NoThreadSafetyAnalysis : InheritableAttr { def GuardedBy : InheritableAttr { let Spellings = [GNU<"guarded_by">]; let Args = [ExprArgument<"Arg">]; - let LateParsed = 1; + let LateParsed = LateAttrParseExperimentalExt; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3510,7 +3701,7 @@ def GuardedBy : InheritableAttr { def PtGuardedBy : InheritableAttr { let Spellings = [GNU<"pt_guarded_by">]; let Args = [ExprArgument<"Arg">]; - let LateParsed = 1; + let LateParsed = LateAttrParseExperimentalExt; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3521,7 +3712,7 @@ def PtGuardedBy : InheritableAttr { def AcquiredAfter : InheritableAttr { let Spellings = [GNU<"acquired_after">]; let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseExperimentalExt; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3532,7 +3723,7 @@ def AcquiredAfter : InheritableAttr { def AcquiredBefore : InheritableAttr { let Spellings = [GNU<"acquired_before">]; let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseExperimentalExt; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3543,7 +3734,7 @@ def AcquiredBefore : InheritableAttr { def AssertExclusiveLock : InheritableAttr { let Spellings = [GNU<"assert_exclusive_lock">]; let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3554,7 +3745,7 @@ def AssertExclusiveLock : InheritableAttr { def AssertSharedLock : InheritableAttr { let Spellings = [GNU<"assert_shared_lock">]; let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3567,7 +3758,7 @@ def AssertSharedLock : InheritableAttr { def ExclusiveTrylockFunction : InheritableAttr { let Spellings = [GNU<"exclusive_trylock_function">]; let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3580,7 +3771,7 @@ def ExclusiveTrylockFunction : InheritableAttr { def SharedTrylockFunction : InheritableAttr { let Spellings = [GNU<"shared_trylock_function">]; let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3591,7 +3782,7 @@ def SharedTrylockFunction : InheritableAttr { def LockReturned : InheritableAttr { let Spellings = [GNU<"lock_returned">]; let Args = [ExprArgument<"Arg">]; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let Subjects = SubjectList<[Function]>; @@ -3601,7 +3792,7 @@ def LockReturned : InheritableAttr { def LocksExcluded : InheritableAttr { let Spellings = [GNU<"locks_excluded">]; let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; + let LateParsed = LateAttrParseStandard; let TemplateDependent = 1; let ParseArgumentsAsUnevaluated = 1; let InheritEvenIfAlreadyPresent = 1; @@ -3617,7 +3808,7 @@ def Consumable : InheritableAttr { // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"consumable", 0>]; let Subjects = SubjectList<[CXXRecord]>; - let Args = [EnumArgument<"DefaultState", "ConsumedState", + let Args = [EnumArgument<"DefaultState", "ConsumedState", /*is_string=*/false, ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ConsumableDocs]; @@ -3650,6 +3841,7 @@ def CallableWhen : InheritableAttr { let Spellings = [Clang<"callable_when", 0>]; let Subjects = SubjectList<[CXXMethod]>; let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState", + /*is_string=*/true, ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [CallableWhenDocs]; @@ -3661,7 +3853,7 @@ def ParamTypestate : InheritableAttr { // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"param_typestate", 0>]; let Subjects = SubjectList<[ParmVar]>; - let Args = [EnumArgument<"ParamState", "ConsumedState", + let Args = [EnumArgument<"ParamState", "ConsumedState", /*is_string=*/false, ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ParamTypestateDocs]; @@ -3673,7 +3865,7 @@ def ReturnTypestate : InheritableAttr { // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"return_typestate", 0>]; let Subjects = SubjectList<[Function, ParmVar]>; - let Args = [EnumArgument<"State", "ConsumedState", + let Args = [EnumArgument<"State", "ConsumedState", /*is_string=*/false, ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [ReturnTypestateDocs]; @@ -3685,7 +3877,7 @@ def SetTypestate : InheritableAttr { // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"set_typestate", 0>]; let Subjects = SubjectList<[CXXMethod]>; - let Args = [EnumArgument<"NewState", "ConsumedState", + let Args = [EnumArgument<"NewState", "ConsumedState", /*is_string=*/false, ["unknown", "consumed", "unconsumed"], ["Unknown", "Consumed", "Unconsumed"]>]; let Documentation = [SetTypestateDocs]; @@ -3697,7 +3889,7 @@ def TestTypestate : InheritableAttr { // FIXME: should this attribute have a CPlusPlus language option? let Spellings = [Clang<"test_typestate", 0>]; let Subjects = SubjectList<[CXXMethod]>; - let Args = [EnumArgument<"TestState", "ConsumedState", + let Args = [EnumArgument<"TestState", "ConsumedState", /*is_string=*/false, ["consumed", "unconsumed"], ["Consumed", "Unconsumed"]>]; let Documentation = [TestTypestateDocs]; @@ -3774,7 +3966,8 @@ def CFGuard : InheritableAttr, TargetSpecificAttr { // we might also want to support __declspec(guard(suppress)). let Spellings = [Declspec<"guard">, Clang<"guard">]; let Subjects = SubjectList<[Function]>; - let Args = [EnumArgument<"Guard", "GuardArg", ["nocf"], ["nocf"]>]; + let Args = [EnumArgument<"Guard", "GuardArg", /*is_string=*/false, + ["nocf"], ["nocf"]>]; let Documentation = [CFGuardDocs]; } @@ -3930,7 +4123,7 @@ def LoopHint : Attr { Pragma<"", "nounroll_and_jam">]; /// State of the loop optimization specified by the spelling. - let Args = [EnumArgument<"Option", "OptionType", + let Args = [EnumArgument<"Option", "OptionType", /*is_string=*/false, ["vectorize", "vectorize_width", "interleave", "interleave_count", "unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count", "pipeline", "pipeline_initiation_interval", "distribute", @@ -3939,7 +4132,7 @@ def LoopHint : Attr { "Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount", "PipelineDisabled", "PipelineInitiationInterval", "Distribute", "VectorizePredicate"]>, - EnumArgument<"State", "LoopHintState", + EnumArgument<"State", "LoopHintState", /*is_string=*/false, ["enable", "disable", "numeric", "fixed_width", "scalable_width", "assume_safety", "full"], ["Enable", "Disable", "Numeric", "FixedWidth", @@ -3979,6 +4172,18 @@ def LoopHint : Attr { let HasCustomParsing = 1; } +/// The HLSL loop attributes +def HLSLLoopHint: StmtAttr { + /// [unroll(directive)] + /// [loop] + let Spellings = [Microsoft<"unroll">, Microsoft<"loop">]; + let Args = [UnsignedArgument<"directive", /*opt*/1>]; + let Subjects = SubjectList<[ForStmt, WhileStmt, DoStmt], + ErrorDiag, "'for', 'while', and 'do' statements">; + let LangOpts = [HLSL]; + let Documentation = [HLSLLoopHintDocs, HLSLUnrollHintDocs]; +} + def CapturedRecord : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; @@ -4028,7 +4233,7 @@ def OMPDeclareSimdDecl : Attr { let HasCustomParsing = 1; let Documentation = [OMPDeclareSimdDocs]; let Args = [ - EnumArgument<"BranchState", "BranchStateTy", + EnumArgument<"BranchState", "BranchStateTy", /*is_string=*/false, [ "", "inbranch", "notinbranch" ], [ "BS_Undefined", "BS_Inbranch", "BS_Notinbranch" ]>, ExprArgument<"Simdlen">, VariadicExprArgument<"Uniforms">, @@ -4048,10 +4253,10 @@ def OMPDeclareTargetDecl : InheritableAttr { let Subjects = SubjectList<[Function, SharedVar]>; let Documentation = [OMPDeclareTargetDocs]; let Args = [ - EnumArgument<"MapType", "MapTypeTy", + EnumArgument<"MapType", "MapTypeTy", /*is_string=*/false, [ "to", "enter", "link" ], [ "MT_To", "MT_Enter", "MT_Link" ]>, - EnumArgument<"DevType", "DevTypeTy", + EnumArgument<"DevType", "DevTypeTy", /*is_string=*/false, [ "host", "nohost", "any" ], [ "DT_Host", "DT_NoHost", "DT_Any" ]>, ExprArgument<"IndirectExpr">, @@ -4073,7 +4278,7 @@ def OMPAllocateDecl : InheritableAttr { let Spellings = []; let SemaHandler = 0; let Args = [ - EnumArgument<"AllocatorType", "AllocatorTypeTy", + EnumArgument<"AllocatorType", "AllocatorTypeTy", /*is_string=*/false, [ "omp_null_allocator", "omp_default_mem_alloc", "omp_large_cap_mem_alloc", "omp_const_mem_alloc", @@ -4122,11 +4327,11 @@ def OMPDeclareVariant : InheritableAttr { }]; } -def Assumption : InheritableAttr { - let Spellings = [Clang<"assume">]; +def OMPAssume : InheritableAttr { + let Spellings = [CXX11<"omp", "assume">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let InheritEvenIfAlreadyPresent = 1; - let Documentation = [AssumptionDocs]; + let Documentation = [OMPAssumeDocs]; let Args = [StringArgument<"Assumption">]; } @@ -4296,22 +4501,34 @@ def HLSLNumThreads: InheritableAttr { } def HLSLSV_GroupIndex: HLSLAnnotationAttr { - let Spellings = [HLSLSemantic<"SV_GroupIndex">]; + let Spellings = [HLSLAnnotation<"SV_GroupIndex">]; let Subjects = SubjectList<[ParmVar, GlobalVar]>; let LangOpts = [HLSL]; let Documentation = [HLSLSV_GroupIndexDocs]; } def HLSLResourceBinding: InheritableAttr { - let Spellings = [HLSLSemantic<"register">]; + let Spellings = [HLSLAnnotation<"register">]; let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar]>; let LangOpts = [HLSL]; let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>]; let Documentation = [HLSLResourceBindingDocs]; } +def HLSLPackOffset: HLSLAnnotationAttr { + let Spellings = [HLSLAnnotation<"packoffset">]; + let LangOpts = [HLSL]; + let Args = [IntArgument<"Subcomponent">, IntArgument<"Component">]; + let Documentation = [HLSLPackOffsetDocs]; + let AdditionalMembers = [{ + unsigned getOffset() { + return subcomponent * 4 + component; + } + }]; +} + def HLSLSV_DispatchThreadID: HLSLAnnotationAttr { - let Spellings = [HLSLSemantic<"SV_DispatchThreadID">]; + let Spellings = [HLSLAnnotation<"SV_DispatchThreadID">]; let Subjects = SubjectList<[ParmVar, Field]>; let LangOpts = [HLSL]; let Documentation = [HLSLSV_DispatchThreadIDDocs]; @@ -4322,43 +4539,62 @@ def HLSLShader : InheritableAttr { let Subjects = SubjectList<[HLSLEntry]>; let LangOpts = [HLSL]; let Args = [ - EnumArgument<"Type", "ShaderType", + EnumArgument<"Type", "llvm::Triple::EnvironmentType", /*is_string=*/true, ["pixel", "vertex", "geometry", "hull", "domain", "compute", "raygeneration", "intersection", "anyhit", "closesthit", "miss", "callable", "mesh", "amplification"], ["Pixel", "Vertex", "Geometry", "Hull", "Domain", "Compute", "RayGeneration", "Intersection", "AnyHit", "ClosestHit", - "Miss", "Callable", "Mesh", "Amplification"]> + "Miss", "Callable", "Mesh", "Amplification"], + /*opt=*/0, /*fake=*/0, /*isExternalType=*/1, /*isCovered=*/0> ]; let Documentation = [HLSLSV_ShaderTypeAttrDocs]; + let AdditionalMembers = +[{ + static bool isValidShaderType(llvm::Triple::EnvironmentType ShaderType) { + return ShaderType >= llvm::Triple::Pixel && ShaderType <= llvm::Triple::Amplification; + } +}]; } def HLSLResource : InheritableAttr { let Spellings = []; let Subjects = SubjectList<[Struct]>; let LangOpts = [HLSL]; - let Args = [EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass", - ["SRV", "UAV", "CBuffer", "Sampler"], - ["SRV", "UAV", "CBuffer", "Sampler"], - /*opt=*/0, /*fake=*/0, /*isExternalType=*/1>, - EnumArgument<"ResourceKind", "llvm::hlsl::ResourceKind", - ["Texture1D", "Texture2D", "Texture2DMS", - "Texture3D", "TextureCube", "Texture1DArray", - "Texture2DArray", "Texture2DMSArray", - "TextureCubeArray", "TypedBuffer", "RawBuffer", - "StructuredBuffer", "CBuffer", "Sampler", - "TBuffer", "RTAccelerationStructure", - "FeedbackTexture2D", "FeedbackTexture2DArray"], - ["Texture1D", "Texture2D", "Texture2DMS", - "Texture3D", "TextureCube", "Texture1DArray", - "Texture2DArray", "Texture2DMSArray", - "TextureCubeArray", "TypedBuffer", "RawBuffer", - "StructuredBuffer", "CBuffer", "Sampler", - "TBuffer", "RTAccelerationStructure", - "FeedbackTexture2D", "FeedbackTexture2DArray"], - /*opt=*/0, /*fake=*/0, /*isExternalType=*/1>, - DefaultBoolArgument<"isROV", /*default=*/0> - ]; + let Args = [ + EnumArgument< + "ResourceKind", "llvm::hlsl::ResourceKind", + /*is_string=*/0, + [ + "Texture1D", "Texture2D", "Texture2DMS", "Texture3D", "TextureCube", + "Texture1DArray", "Texture2DArray", "Texture2DMSArray", + "TextureCubeArray", "TypedBuffer", "RawBuffer", "StructuredBuffer", + "CBuffer", "Sampler", "TBuffer", "RTAccelerationStructure", + "FeedbackTexture2D", "FeedbackTexture2DArray" + ], + [ + "Texture1D", "Texture2D", "Texture2DMS", "Texture3D", "TextureCube", + "Texture1DArray", "Texture2DArray", "Texture2DMSArray", + "TextureCubeArray", "TypedBuffer", "RawBuffer", "StructuredBuffer", + "CBuffer", "Sampler", "TBuffer", "RTAccelerationStructure", + "FeedbackTexture2D", "FeedbackTexture2DArray" + ], + /*opt=*/0, /*fake=*/0, /*isExternalType=*/1, /*isCovered=*/0>, + DefaultBoolArgument<"isROV", /*default=*/0> + ]; + let Documentation = [InternalOnly]; +} + +def HLSLResourceClass : InheritableAttr { + let Spellings = [CXX11<"hlsl", "resource_class">]; + let Subjects = SubjectList<[Struct]>; + let LangOpts = [HLSL]; + let Args = [ + EnumArgument<"ResourceClass", "llvm::hlsl::ResourceClass", + /*is_string=*/true, ["SRV", "UAV", "CBuffer", "Sampler"], + ["SRV", "UAV", "CBuffer", "Sampler"], + /*opt=*/0, /*fake=*/0, /*isExternalType=*/1> + ]; let Documentation = [InternalOnly]; } @@ -4395,10 +4631,35 @@ def NoRandomizeLayout : InheritableAttr { } def : MutualExclusions<[RandomizeLayout, NoRandomizeLayout]>; +def VTablePointerAuthentication : InheritableAttr { + let Spellings = [Clang<"ptrauth_vtable_pointer">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [Undocumented]; + let StrictEnumParameters = 1; + let Args = [EnumArgument<"Key", "VPtrAuthKeyType", /*is_string=*/ true, + ["default_key", "no_authentication", "process_dependent", + "process_independent"], + ["DefaultKey", "NoKey", "ProcessDependent", + "ProcessIndependent"]>, + EnumArgument<"AddressDiscrimination", "AddressDiscriminationMode", + /*is_string=*/ true, + ["default_address_discrimination", "no_address_discrimination", + "address_discrimination"], + ["DefaultAddressDiscrimination", "NoAddressDiscrimination", + "AddressDiscrimination"]>, + EnumArgument<"ExtraDiscrimination", "ExtraDiscrimination", + /*is_string=*/ true, + ["default_extra_discrimination", "no_extra_discrimination", + "type_discrimination", "custom_discrimination"], + ["DefaultExtraDiscrimination", "NoExtraDiscrimination", + "TypeDiscrimination", "CustomDiscrimination"]>, + IntArgument<"CustomDiscriminationValue", 1>]; +} + def FunctionReturnThunks : InheritableAttr, TargetSpecificAttr { let Spellings = [GCC<"function_return">]; - let Args = [EnumArgument<"ThunkType", "Kind", + let Args = [EnumArgument<"ThunkType", "Kind", /*is_string=*/true, ["keep", "thunk-extern"], ["Keep", "Extern"] >]; @@ -4443,20 +4704,9 @@ def CodeAlign: StmtAttr { }]; } -def CountedBy : InheritableAttr { - let Spellings = [Clang<"counted_by">]; - let Subjects = SubjectList<[Field]>; - let Args = [IdentifierArgument<"CountedByField">]; - let Documentation = [CountedByDocs]; - let LangOpts = [COnly]; - // FIXME: This is ugly. Let using a DeclArgument would be nice, but a Decl - // isn't yet available due to the fact that we're still parsing the - // structure. Maybe that code could be changed sometime in the future. - code AdditionalMembers = [{ - private: - SourceRange CountedByFieldLoc; - public: - SourceRange getCountedByFieldLoc() const { return CountedByFieldLoc; } - void setCountedByFieldLoc(SourceRange Loc) { CountedByFieldLoc = Loc; } - }]; +def ClspvLibclcBuiltin: InheritableAttr { + let Spellings = [Clang<"clspv_libclc_builtin">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [ClspvLibclcBuiltinDoc]; + let SimpleHandler = 1; } diff --git a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td index e02a1201e2a..99738812c81 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td +++ b/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td @@ -1593,6 +1593,11 @@ replacement=\ *string-literal* a warning about use of a deprecated declaration. The Fix-It will replace the deprecated declaration with the new declaration specified. +environment=\ *identifier* + Target environment in which this declaration is available. If present, + the availability attribute applies only to targets with the same platform + and environment. The parameter is currently supported only in HLSL. + Multiple availability attributes can be placed on a declaration, which may correspond to different platforms. For most platforms, the availability attribute with the platform corresponding to the target platform will be used; @@ -1604,27 +1609,40 @@ specifies availability for the current target platform, the availability attributes are ignored. Supported platforms are: ``ios`` - Apple's iOS operating system. The minimum deployment target is specified by - the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` - command-line arguments. + Apple's iOS operating system. The minimum deployment target is specified + as part of the ``-target *arch*-apple-ios*version*`` command line argument. + Alternatively, it can be specified by the ``-mtargetos=ios*version*`` + command-line argument. ``macos`` - Apple's macOS operating system. The minimum deployment target is - specified by the ``-mmacosx-version-min=*version*`` command-line argument. - ``macosx`` is supported for backward-compatibility reasons, but it is - deprecated. + Apple's macOS operating system. The minimum deployment target is specified + as part of the ``-target *arch*-apple-macos*version*`` command line argument. + Alternatively, it can be specified by the ``-mtargetos=macos*version*`` + command-line argument. ``macosx`` is supported for + backward-compatibility reasons, but it is deprecated. ``tvos`` - Apple's tvOS operating system. The minimum deployment target is specified by - the ``-mtvos-version-min=*version*`` command-line argument. + Apple's tvOS operating system. The minimum deployment target is specified + as part of the ``-target *arch*-apple-tvos*version*`` command line argument. + Alternatively, it can be specified by the ``-mtargetos=tvos*version*`` + command-line argument. ``watchos`` - Apple's watchOS operating system. The minimum deployment target is specified by - the ``-mwatchos-version-min=*version*`` command-line argument. + Apple's watchOS operating system. The minimum deployment target is specified + as part of the ``-target *arch*-apple-watchos*version*`` command line argument. + Alternatively, it can be specified by the ``-mtargetos=watchos*version*`` + command-line argument. + +``visionos`` + Apple's visionOS operating system. The minimum deployment target is specified + as part of the ``-target *arch*-apple-visionos*version*`` command line argument. + Alternatively, it can be specified by the ``-mtargetos=visionos*version*`` + command-line argument. ``driverkit`` Apple's DriverKit userspace kernel extensions. The minimum deployment target - is specified as part of the triple. + is specified as part of the ``-target *arch*-apple-driverkit*version*`` + command line argument. A declaration can typically be used even when deploying back to a platform version prior to when the declaration was introduced. When this happens, the @@ -1996,6 +2014,31 @@ Here is an example: }]; } +def CXXAssumeDocs : Documentation { + let Category = DocCatStmt; + let Heading = "assume"; + let Content = [{ +The ``assume`` attribute is used to indicate to the optimizer that a +certain condition is assumed to be true at a certain point in the +program. If this condition is violated at runtime, the behavior is +undefined. ``assume`` can only be applied to a null statement. + +Different optimisers are likely to react differently to the presence of +this attribute; in some cases, adding ``assume`` may affect performance +negatively. It should be used with parsimony and care. + +Example: + +.. code-block:: c++ + + int f(int x, int y) { + [[assume(x == 27)]]; + [[assume(x == y)]]; + return y + 1; // May be optimised to `return 28`. + } + }]; +} + def LikelihoodDocs : Documentation { let Category = DocCatStmt; let Heading = "likely and unlikely"; @@ -2486,6 +2529,9 @@ Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2 "avx", "xop" and largely correspond to the machine specific options handled by the front end. +Note that this attribute does not apply transitively to nested functions such +as blocks or C++ lambdas. + Additionally, this attribute supports function multiversioning for ELF based x86/x86-64 targets, which can be used to create multiple implementations of the same function that will be resolved at runtime based on the priority of their @@ -2517,6 +2563,14 @@ function it instructs compiler to emit multiple function versions based on priority and target features availability. One of the versions is always ( implicitly or explicitly ) the ``default`` (fallback). Attribute strings can contain dependent features names joined by the "+" sign. + +For targets that support the GNU indirect function (IFUNC) feature, dispatch +is performed by emitting an indirect function that is resolved to the appropriate +target clone at load time. The indirect function is given the name the +multiversioned function would have if it had been declared without the attribute. +For backward compatibility with earlier Clang releases, a function alias with an +``.ifunc`` suffix is also emitted. The ``.ifunc`` suffixed symbol is a deprecated +feature and support for it may be removed in the future. }]; } @@ -2705,6 +2759,33 @@ An error will be given if: }]; } +def AMDGPUMaxNumWorkGroupsDocs : Documentation { + let Category = DocCatAMDGPUAttributes; + let Content = [{ +This attribute specifies the max number of work groups when the kernel +is dispatched. + +Clang supports the +``__attribute__((amdgpu_max_num_work_groups(, , )))`` or +``[[clang::amdgpu_max_num_work_groups(, , )]]`` attribute for the +AMDGPU target. This attribute may be attached to HIP or OpenCL kernel function +definitions and is an optimization hint. + +The ```` parameter specifies the maximum number of work groups in the x dimension. +Similarly ```` and ```` are for the y and z dimensions respectively. +Each of the three values must be greater than 0 when provided. The ```` parameter +is required, while ```` and ```` are optional with default value of 1. + +If specified, the AMDGPU target backend might be able to produce better machine +code. + +An error will be given if: + - Specified values violate subtarget specifications; + - Specified values are not compatible with values provided through other + attributes. + }]; +} + def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> { let Content = [{ Clang supports several different calling conventions, depending on the target @@ -3706,6 +3787,12 @@ for that function. This attribute is incompatible with the ``always_inline`` and ``minsize`` attributes. + +Note that this attribute does not apply recursively to nested functions such as +lambdas or blocks when using declaration-specific attribute syntaxes such as double +square brackets (``[[]]``) or ``__attribute__``. The ``#pragma`` syntax can be +used to apply the attribute to all functions, including nested functions, in a +range of source code. }]; } @@ -4088,6 +4175,20 @@ non-underscored keywords. For example: @property (assign, nullable) NSView *superview; @property (readonly, nonnull) NSArray *subviews; @end + +As well as built-in pointer types, the nullability attributes can be attached +to C++ classes marked with the ``_Nullable`` attribute. + +The following C++ standard library types are considered nullable: +``unique_ptr``, ``shared_ptr``, ``auto_ptr``, ``exception_ptr``, ``function``, +``move_only_function`` and ``coroutine_handle``. + +Types should be marked nullable only where the type itself leaves nullability +ambiguous. For example, ``std::optional`` is not marked ``_Nullable``, because +``optional _Nullable`` is redundant and ``optional _Nonnull`` is +not a useful type. ``std::weak_ptr`` is not nullable, because its nullability +can change with no visible modification, so static annotation is unlikely to be +unhelpful. }]; } @@ -4122,6 +4223,17 @@ The ``_Nullable`` nullability qualifier indicates that a value of the int fetch_or_zero(int * _Nullable ptr); a caller of ``fetch_or_zero`` can provide null. + +The ``_Nullable`` attribute on classes indicates that the given class can +represent null values, and so the ``_Nullable``, ``_Nonnull`` etc qualifiers +make sense for this type. For example: + + .. code-block:: c + + class _Nullable ArenaPointer { ... }; + + ArenaPointer _Nonnull x = ...; + ArenaPointer _Nullable y = nullptr; }]; } @@ -4621,11 +4733,11 @@ For more information see }]; } -def AssumptionDocs : Documentation { +def OMPAssumeDocs : Documentation { let Category = DocCatFunction; let Heading = "assume"; let Content = [{ -Clang supports the ``__attribute__((assume("assumption")))`` attribute to +Clang supports the ``[[omp::assume("assumption")]]`` attribute to provide additional information to the optimizer. The string-literal, here "assumption", will be attached to the function declaration such that later analysis and optimization passes can assume the "assumption" to hold. @@ -4637,7 +4749,7 @@ A function can have multiple assume attributes and they propagate from prior declarations to later definitions. Multiple assumptions are aggregated into a single comma separated string. Thus, one can provide multiple assumptions via a comma separated string, i.a., -``__attribute__((assume("assumption1,assumption2")))``. +``[[omp::assume("assumption1,assumption2")]]``. While LLVM plugins might provide more assumption strings, the default LLVM optimization passes are aware of the following assumptions: @@ -5074,10 +5186,11 @@ that does not. A single parameter may not have multiple ABI treatment attributes. Support for this feature is target-dependent, although it should be -supported on every target that Swift supports. Query for this support -with ``__has_attribute(swiftcall)``. This implies support for the -``swift_context``, ``swift_error_result``, and ``swift_indirect_result`` -attributes. +supported on every target that Swift supports. Query for this attribute +with ``__has_attribute(swiftcall)``. Query if the target supports the +calling convention with ``__has_extension(swiftcc)``. This implies +support for the ``swift_context``, ``swift_error_result``, and +``swift_indirect_result`` attributes. }]; } @@ -5124,6 +5237,10 @@ the following: semantically be performed after a guaranteed tail call, such as the non-trivial destruction of a local variable or temporary, then the program is ill-formed. + +Query for this attribute with ``__has_attribute(swiftasynccall)``. Query if +the target supports the calling convention with +``__has_extension(swiftasynccc)``. }]; } @@ -5313,6 +5430,29 @@ Putting the attribute on a compound statement suppresses all warnings in scope: } } +The attribute can also be placed on entire declarations of functions, classes, +variables, member variables, and so on, to suppress warnings related +to the declarations themselves. When used this way, the attribute additionally +suppresses all warnings in the lexical scope of the declaration: + +.. code-block:: c++ + + class [[clang::suppress]] C { + int foo() { + int *x = nullptr; + ... + return *x; // warnings suppressed in the entire class scope + } + + int bar(); + }; + + int C::bar() { + int *x = nullptr; + ... + return *x; // warning NOT suppressed! - not lexically nested in 'class C{}' + } + Some static analysis warnings are accompanied by one or more notes, and the line of code against which the warning is emitted isn't necessarily the best for suppression purposes. In such cases the tools are allowed to implement @@ -5403,6 +5543,17 @@ for clang builtin functions. }]; } +def RISCVVectorCCDocs : Documentation { + let Category = DocCatCallingConvs; + let Heading = "riscv::vector_cc, riscv_vector_cc, clang::riscv_vector_cc"; + let Content = [{ +The ``riscv_vector_cc`` attribute can be applied to a function. It preserves 15 +registers namely, v1-v7 and v24-v31 as callee-saved. Callers thus don't need +to save these registers before function calls, and callees only need to save +them if they use them. + }]; +} + def PreferredNameDocs : Documentation { let Category = DocCatDecl; let Content = [{ @@ -5506,6 +5657,28 @@ experimental at this time. }]; } +def PreserveNoneDocs : Documentation { + let Category = DocCatCallingConvs; + let Content = [{ +On X86-64 and AArch64 targets, this attribute changes the calling convention of a function. +The ``preserve_none`` calling convention tries to preserve as few general +registers as possible. So all general registers are caller saved registers. It +also uses more general registers to pass arguments. This attribute doesn't +impact floating-point registers. ``preserve_none``'s ABI is still unstable, and +may be changed in the future. + +- On X86-64, only RSP and RBP are preserved by the callee. + Registers R12, R13, R14, R15, RDI, RSI, RDX, RCX, R8, R9, R11, and RAX now can + be used to pass function arguments. Floating-point registers (XMMs/YMMs) still + follow the C calling convention. +- On AArch64, only LR and FP are preserved by the callee. + Registers X20-X28, X0-X7, and X9-X14 are used to pass function arguments. + X8, X16-X19, SIMD and floating-point registers follow the AAPCS calling + convention. X15 is not available for argument passing on Windows, but is + used to pass arguments on other platforms. + }]; +} + def DeprecatedDocs : Documentation { let Category = DocCatDecl; let Content = [{ @@ -5560,6 +5733,25 @@ See :doc:`LTOVisibility`. }]; } +def TypeVisibilityDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The ``type_visibility`` attribute allows the visibility of a type and its vague +linkage objects (vtable, typeinfo, typeinfo name) to be controlled separately from +the visibility of functions and data members of the type. + +For example, this can be used to give default visibility to the typeinfo and the vtable +of a type while still keeping hidden visibility on its member functions and static data +members. + +This attribute can only be applied to types and namespaces. + +If both ``visibility`` and ``type_visibility`` are applied to a type or a namespace, the +visibility specified with the ``type_visibility`` attribute overrides the visibility +provided with the regular ``visibility`` attribute. + }]; +} + def RenderScriptKernelAttributeDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -5608,7 +5800,8 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M`` ``M`` defaults to 0 if omitted. This attribute is only supported on -aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64 targets. +aarch64/aarch64-be/loongarch32/loongarch64/riscv32/riscv64/i386/x86-64/ppc/ppc64 targets. +For ppc/ppc64 targets, AIX is still not supported. }]; } @@ -5942,6 +6135,9 @@ def AlwaysDestroyDocs : Documentation { The ``always_destroy`` attribute specifies that a variable with static or thread storage duration should have its exit-time destructor run. This attribute is the default unless clang was invoked with -fno-c++-static-destructors. + +If a variable is explicitly declared with this attribute, Clang will silence +otherwise applicable ``-Wexit-time-destructors`` warnings. }]; } @@ -6390,7 +6586,8 @@ like pointers to an object of type ``T``: private: int *valuePointer; public: - int *getInt() { return &valuePointer; } + IntPointer(const IntOwner&); + int *getInt() { return valuePointer; } }; The argument ``T`` is optional and is ignored. @@ -6406,12 +6603,8 @@ When the Owner's lifetime ends, it will consider the Pointer to be dangling. .. code-block:: c++ int f() { - IntPointer P; - if (true) { - IntOwner O(7); - P = IntPointer(O); // P "points into" O - } // P is dangling - return P.get(); // error: Using a dangling Pointer. + IntPointer P(IntOwner{}); // P "points into" a temporary IntOwner object + P.getInt(); // P is dangling } }]; @@ -7151,6 +7344,100 @@ where shaders must be compiled into a library and linked at runtime. }]; } +def HLSLLoopHintDocs : Documentation { + let Category = DocCatStmt; + let Heading = "[loop]"; + let Content = [{ +The ``[loop]`` directive allows loop optimization hints to be +specified for the subsequent loop. The directive allows unrolling to +be disabled and is not compatible with [unroll(x)]. + +Specifying the parameter, ``[loop]``, directs the +unroller to not unroll the loop. + +.. code-block:: hlsl + + [loop] + for (...) { + ... + } + +.. code-block:: hlsl + + [loop] + while (...) { + ... + } + +.. code-block:: hlsl + + [loop] + do { + ... + } while (...) + +See `hlsl loop extensions `_ +for details. + }]; +} + +def HLSLUnrollHintDocs : Documentation { + let Category = DocCatStmt; + let Heading = "[unroll(x)], [unroll]"; + let Content = [{ +Loop unrolling optimization hints can be specified with ``[unroll(x)]`` +. The attribute is placed immediately before a for, while, +or do-while. +Specifying the parameter, ``[unroll(_value_)]``, directs the +unroller to unroll the loop ``_value_`` times. Note: [unroll(x)] is not compatible with [loop]. + +.. code-block:: hlsl + + [unroll(4)] + for (...) { + ... + } + +.. code-block:: hlsl + + [unroll] + for (...) { + ... + } + +.. code-block:: hlsl + + [unroll(4)] + while (...) { + ... + } + +.. code-block:: hlsl + + [unroll] + while (...) { + ... + } + +.. code-block:: hlsl + + [unroll(4)] + do { + ... + } while (...) + +.. code-block:: hlsl + + [unroll] + do { + ... + } while (...) + +See `hlsl loop extensions `_ +for details. + }]; +} + def ClangRandomizeLayoutDocs : Documentation { let Category = DocCatDecl; let Heading = "randomize_layout, no_randomize_layout"; @@ -7210,7 +7497,8 @@ b for constant buffer views (CBV). Register space is specified in the format ``space[number]`` and defaults to ``space0`` if omitted. Here're resource binding examples with and without space: -.. code-block:: c++ + +.. code-block:: hlsl RWBuffer Uav : register(u3, space1); Buffer Buf : register(t1); @@ -7219,6 +7507,26 @@ The full documentation is available here: https://docs.microsoft.com/en-us/windo }]; } +def HLSLPackOffsetDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The packoffset attribute is used to change the layout of a cbuffer. +Attribute spelling in HLSL is: ``packoffset( c[Subcomponent][.component] )``. +A subcomponent is a register number, which is an integer. A component is in the form of [.xyzw]. + +Examples: + +.. code-block:: hlsl + + cbuffer A { + float3 a : packoffset(c0.y); + float4 b : packoffset(c4); + } + +The full documentation is available here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-packoffset + }]; +} + def HLSLSV_DispatchThreadIDDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -7343,7 +7651,7 @@ means that it can e.g no longer be part of an initializer expression. /* This may print something else than "6 * 7 = 42", if there is a non-weak definition of "ANSWER" in - an object linked in */ + an object linked in */ printf("6 * 7 = %d\n", ANSWER); return 0; @@ -7878,3 +8186,86 @@ requirement: } }]; } + +def ClspvLibclcBuiltinDoc : Documentation { + let Category = DocCatFunction; + let Content = [{ +Attribute used by `clspv`_ (OpenCL-C to Vulkan SPIR-V compiler) to identify functions coming from `libclc`_ (OpenCL-C builtin library). + +.. code-block:: c + + void __attribute__((clspv_libclc_builtin)) libclc_builtin() {} + +.. _`clspv`: https://github.com/google/clspv +.. _`libclc`: https://libclc.llvm.org +}]; +} + +def DocCatNonBlockingNonAllocating : DocumentationCategory<"Performance Constraint Attributes"> { + let Content = [{ +The ``nonblocking``, ``blocking``, ``nonallocating`` and ``allocating`` attributes can be attached +to function types, including blocks, C++ lambdas, and member functions. The attributes declare +constraints about a function's behavior pertaining to blocking and heap memory allocation. + +There are several rules for function types with these attributes, enforced with +compiler warnings: + +- When assigning or otherwise converting to a function pointer of ``nonblocking`` or + ``nonallocating`` type, the source must also be a function or function pointer of + that type, unless it is a null pointer, i.e. the attributes should not be "spoofed". Conversions + that remove the attributes are transparent and valid. + +- An override of a ``nonblocking`` or ``nonallocating`` virtual method must also be declared + with that same attribute (or a stronger one.) An overriding method may add an attribute. + +- A redeclaration of a ``nonblocking`` or ``nonallocating`` function must also be declared with + the same attribute (or a stronger one). A redeclaration may add an attribute. + +The warnings are controlled by ``-Wfunction-effects``, which is enabled by default. + +In a future commit, the compiler will diagnose function calls from ``nonblocking`` and ``nonallocating`` +functions to other functions which lack the appropriate attribute. + }]; +} + +def NonBlockingDocs : Documentation { + let Category = DocCatNonBlockingNonAllocating; + let Heading = "nonblocking"; + let Content = [{ +Declares that a function or function type either does or does not block in any way, according +to the optional, compile-time constant boolean argument, which defaults to true. When the argument +is false, the attribute is equivalent to ``blocking``. + +For the purposes of diagnostics, ``nonblocking`` is considered to include the +``nonallocating`` guarantee and is therefore a "stronger" constraint or attribute. + }]; +} + +def NonAllocatingDocs : Documentation { + let Category = DocCatNonBlockingNonAllocating; + let Heading = "nonallocating"; + let Content = [{ +Declares that a function or function type either does or does not allocate heap memory, according +to the optional, compile-time constant boolean argument, which defaults to true. When the argument +is false, the attribute is equivalent to ``allocating``. + }]; +} + +def BlockingDocs : Documentation { + let Category = DocCatNonBlockingNonAllocating; + let Heading = "blocking"; + let Content = [{ +Declares that a function potentially blocks, and prevents any potential inference of ``nonblocking`` +by the compiler. + }]; +} + +def AllocatingDocs : Documentation { + let Category = DocCatNonBlockingNonAllocating; + let Heading = "allocating"; + let Content = [{ +Declares that a function potentially allocates heap memory, and prevents any potential inference +of ``nonallocating`` by the compiler. + }]; +} + diff --git a/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h b/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h index ef2ddf525c9..5f024b4b5fd 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h +++ b/contrib/llvm-project/clang/include/clang/Basic/AttributeCommonInfo.h @@ -52,8 +52,8 @@ public: /// Context-sensitive version of a keyword attribute. AS_ContextSensitiveKeyword, - /// : - AS_HLSLSemantic, + /// : + AS_HLSLAnnotation, /// The attibute has no source code manifestation and is only created /// implicitly. @@ -120,7 +120,7 @@ public: } static Form Pragma() { return AS_Pragma; } static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; } - static Form HLSLSemantic() { return AS_HLSLSemantic; } + static Form HLSLAnnotation() { return AS_HLSLAnnotation; } static Form Implicit() { return AS_Implicit; } private: diff --git a/contrib/llvm-project/clang/include/clang/Basic/Builtins.def b/contrib/llvm-project/clang/include/clang/Basic/Builtins.def index 4dcbaf8a7be..48437c93975 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Builtins.def +++ b/contrib/llvm-project/clang/include/clang/Basic/Builtins.def @@ -5,17 +5,9 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// -// This file defines the standard builtin function database. Users of this file -// must define the BUILTIN macro to make use of this information. -// -//===----------------------------------------------------------------------===// -// FIXME: This should really be a .td file, but that requires modifying tblgen. -// Perhaps tblgen should have plugins. - -// The first value provided to the macro specifies the function name of the -// builtin, and results in a clang::builtin::BIXX enum value for XX. +// This is only documentation for the database layout. This will be removed once +// all builtin databases are converted to tablegen files // The second value provided to the macro specifies the type of the function // (result value, then each argument) as follows: @@ -41,6 +33,7 @@ // q -> Scalable vector, followed by the number of elements and the base type. // Q -> target builtin type, followed by a character to distinguish the builtin type // Qa -> AArch64 svcount_t builtin type. +// Qb -> AMDGPU __amdgpu_buffer_rsrc_t builtin type. // E -> ext_vector, followed by the number of elements and the base type. // X -> _Complex, followed by the base type. // Y -> ptrdiff_t @@ -108,1694 +101,4 @@ // M_0, ..., M_k as payload // z -> this is a function in (possibly-versioned) namespace std // E -> this function can be constant evaluated by Clang frontend -// FIXME: gcc has nonnull - -#if defined(BUILTIN) && !defined(LIBBUILTIN) -# define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) -#endif - -#if defined(BUILTIN) && !defined(LANGBUILTIN) -# define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS) -#endif - -// Standard libc/libm functions: -BUILTIN(__builtin_atan2 , "ddd" , "Fne") -BUILTIN(__builtin_atan2f, "fff" , "Fne") -BUILTIN(__builtin_atan2l, "LdLdLd", "Fne") -BUILTIN(__builtin_atan2f128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_abs , "ii" , "ncF") -BUILTIN(__builtin_copysign, "ddd", "ncFE") -BUILTIN(__builtin_copysignf, "fff", "ncFE") -BUILTIN(__builtin_copysignf16, "hhh", "ncF") -BUILTIN(__builtin_copysignl, "LdLdLd", "ncFE") -BUILTIN(__builtin_copysignf128, "LLdLLdLLd", "ncFE") -BUILTIN(__builtin_fabs , "dd" , "ncFE") -BUILTIN(__builtin_fabsf, "ff" , "ncFE") -BUILTIN(__builtin_fabsl, "LdLd", "ncFE") -BUILTIN(__builtin_fabsf16, "hh" , "ncF") -BUILTIN(__builtin_fabsf128, "LLdLLd", "ncFE") -BUILTIN(__builtin_fmod , "ddd" , "Fne") -BUILTIN(__builtin_fmodf, "fff" , "Fne") -BUILTIN(__builtin_fmodf16, "hhh" , "Fne") -BUILTIN(__builtin_fmodl, "LdLdLd", "Fne") -BUILTIN(__builtin_fmodf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_frexp , "ddi*" , "Fn") -BUILTIN(__builtin_frexpf, "ffi*" , "Fn") -BUILTIN(__builtin_frexpl, "LdLdi*", "Fn") -BUILTIN(__builtin_frexpf128, "LLdLLdi*", "Fn") -BUILTIN(__builtin_frexpf16, "hhi*" , "Fn") -BUILTIN(__builtin_huge_val, "d", "ncE") -BUILTIN(__builtin_huge_valf, "f", "ncE") -BUILTIN(__builtin_huge_vall, "Ld", "ncE") -BUILTIN(__builtin_huge_valf16, "x", "ncE") -BUILTIN(__builtin_huge_valf128, "LLd", "ncE") -BUILTIN(__builtin_inf , "d" , "ncE") -BUILTIN(__builtin_inff , "f" , "ncE") -BUILTIN(__builtin_infl , "Ld" , "ncE") -BUILTIN(__builtin_inff16 , "x" , "ncE") -BUILTIN(__builtin_inff128 , "LLd" , "ncE") -BUILTIN(__builtin_labs , "LiLi" , "Fnc") -BUILTIN(__builtin_llabs, "LLiLLi", "Fnc") -BUILTIN(__builtin_ldexp , "ddi" , "Fne") -BUILTIN(__builtin_ldexpf, "ffi" , "Fne") -BUILTIN(__builtin_ldexpl, "LdLdi", "Fne") -BUILTIN(__builtin_ldexpf128, "LLdLLdi", "Fne") -BUILTIN(__builtin_ldexpf16, "hhi", "Fne") -BUILTIN(__builtin_modf , "ddd*" , "Fn") -BUILTIN(__builtin_modff, "fff*" , "Fn") -BUILTIN(__builtin_modfl, "LdLdLd*", "Fn") -BUILTIN(__builtin_modff128, "LLdLLdLLd*", "Fn") -BUILTIN(__builtin_nan, "dcC*" , "FnUE") -BUILTIN(__builtin_nanf, "fcC*" , "FnUE") -BUILTIN(__builtin_nanl, "LdcC*", "FnUE") -BUILTIN(__builtin_nanf16, "xcC*", "FnUE") -BUILTIN(__builtin_nanf128, "LLdcC*", "FnUE") -BUILTIN(__builtin_nans, "dcC*" , "FnUE") -BUILTIN(__builtin_nansf, "fcC*" , "FnUE") -BUILTIN(__builtin_nansl, "LdcC*", "FnUE") -BUILTIN(__builtin_nansf16, "xcC*", "FnUE") -BUILTIN(__builtin_nansf128, "LLdcC*", "FnUE") -BUILTIN(__builtin_powi , "ddi" , "Fnc") -BUILTIN(__builtin_powif, "ffi" , "Fnc") -BUILTIN(__builtin_powil, "LdLdi", "Fnc") -BUILTIN(__builtin_pow , "ddd" , "Fne") -BUILTIN(__builtin_powf, "fff" , "Fne") -BUILTIN(__builtin_powf16, "hhh" , "Fne") -BUILTIN(__builtin_powl, "LdLdLd", "Fne") -BUILTIN(__builtin_powf128, "LLdLLdLLd", "Fne") - -// Standard unary libc/libm functions with double/float/long double variants: -BUILTIN(__builtin_acos , "dd" , "Fne") -BUILTIN(__builtin_acosf, "ff" , "Fne") -BUILTIN(__builtin_acosl, "LdLd", "Fne") -BUILTIN(__builtin_acosf128, "LLdLLd", "Fne") -BUILTIN(__builtin_acosh , "dd" , "Fne") -BUILTIN(__builtin_acoshf, "ff" , "Fne") -BUILTIN(__builtin_acoshl, "LdLd", "Fne") -BUILTIN(__builtin_acoshf128, "LLdLLd", "Fne") -BUILTIN(__builtin_asin , "dd" , "Fne") -BUILTIN(__builtin_asinf, "ff" , "Fne") -BUILTIN(__builtin_asinl, "LdLd", "Fne") -BUILTIN(__builtin_asinf128, "LLdLLd", "Fne") -BUILTIN(__builtin_asinh , "dd" , "Fne") -BUILTIN(__builtin_asinhf, "ff" , "Fne") -BUILTIN(__builtin_asinhl, "LdLd", "Fne") -BUILTIN(__builtin_asinhf128, "LLdLLd", "Fne") -BUILTIN(__builtin_atan , "dd" , "Fne") -BUILTIN(__builtin_atanf, "ff" , "Fne") -BUILTIN(__builtin_atanl, "LdLd", "Fne") -BUILTIN(__builtin_atanf128, "LLdLLd", "Fne") -BUILTIN(__builtin_atanh , "dd", "Fne") -BUILTIN(__builtin_atanhf, "ff", "Fne") -BUILTIN(__builtin_atanhl, "LdLd", "Fne") -BUILTIN(__builtin_atanhf128, "LLdLLd", "Fne") -BUILTIN(__builtin_cbrt , "dd", "Fnc") -BUILTIN(__builtin_cbrtf, "ff", "Fnc") -BUILTIN(__builtin_cbrtl, "LdLd", "Fnc") -BUILTIN(__builtin_cbrtf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_ceil , "dd" , "Fnc") -BUILTIN(__builtin_ceilf, "ff" , "Fnc") -BUILTIN(__builtin_ceilf16, "hh" , "Fnc") -BUILTIN(__builtin_ceill, "LdLd", "Fnc") -BUILTIN(__builtin_ceilf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_cos , "dd" , "Fne") -BUILTIN(__builtin_cosf, "ff" , "Fne") -BUILTIN(__builtin_cosf16, "hh" , "Fne") -BUILTIN(__builtin_cosh , "dd" , "Fne") -BUILTIN(__builtin_coshf, "ff" , "Fne") -BUILTIN(__builtin_coshl, "LdLd", "Fne") -BUILTIN(__builtin_coshf128, "LLdLLd", "Fne") -BUILTIN(__builtin_cosl, "LdLd", "Fne") -BUILTIN(__builtin_cosf128, "LLdLLd" , "Fne") -BUILTIN(__builtin_erf , "dd", "Fne") -BUILTIN(__builtin_erff, "ff", "Fne") -BUILTIN(__builtin_erfl, "LdLd", "Fne") -BUILTIN(__builtin_erff128, "LLdLLd", "Fne") -BUILTIN(__builtin_erfc , "dd", "Fne") -BUILTIN(__builtin_erfcf, "ff", "Fne") -BUILTIN(__builtin_erfcl, "LdLd", "Fne") -BUILTIN(__builtin_erfcf128, "LLdLLd", "Fne") -BUILTIN(__builtin_exp , "dd" , "Fne") -BUILTIN(__builtin_expf, "ff" , "Fne") -BUILTIN(__builtin_expf16, "hh" , "Fne") -BUILTIN(__builtin_expl, "LdLd", "Fne") -BUILTIN(__builtin_expf128, "LLdLLd", "Fne") -BUILTIN(__builtin_exp2 , "dd" , "Fne") -BUILTIN(__builtin_exp2f, "ff" , "Fne") -BUILTIN(__builtin_exp2f16, "hh" , "Fne") -BUILTIN(__builtin_exp2l, "LdLd", "Fne") -BUILTIN(__builtin_exp2f128, "LLdLLd" , "Fne") -BUILTIN(__builtin_exp10 , "dd" , "Fne") -BUILTIN(__builtin_exp10f, "ff" , "Fne") -BUILTIN(__builtin_exp10f16, "hh" , "Fne") -BUILTIN(__builtin_exp10l, "LdLd", "Fne") -BUILTIN(__builtin_exp10f128, "LLdLLd" , "Fne") -BUILTIN(__builtin_expm1 , "dd", "Fne") -BUILTIN(__builtin_expm1f, "ff", "Fne") -BUILTIN(__builtin_expm1l, "LdLd", "Fne") -BUILTIN(__builtin_expm1f128, "LLdLLd", "Fne") -BUILTIN(__builtin_fdim, "ddd", "Fne") -BUILTIN(__builtin_fdimf, "fff", "Fne") -BUILTIN(__builtin_fdiml, "LdLdLd", "Fne") -BUILTIN(__builtin_fdimf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_floor , "dd" , "Fnc") -BUILTIN(__builtin_floorf, "ff" , "Fnc") -BUILTIN(__builtin_floorf16, "hh" , "Fnc") -BUILTIN(__builtin_floorl, "LdLd", "Fnc") -BUILTIN(__builtin_floorf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_fma, "dddd", "Fne") -BUILTIN(__builtin_fmaf, "ffff", "Fne") -BUILTIN(__builtin_fmaf16, "hhhh", "Fne") -BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne") -BUILTIN(__builtin_fmaf128, "LLdLLdLLdLLd", "Fne") -BUILTIN(__builtin_fmax, "ddd", "FncE") -BUILTIN(__builtin_fmaxf, "fff", "FncE") -BUILTIN(__builtin_fmaxf16, "hhh", "FncE") -BUILTIN(__builtin_fmaxl, "LdLdLd", "FncE") -BUILTIN(__builtin_fmaxf128, "LLdLLdLLd", "FncE") -BUILTIN(__builtin_fmin, "ddd", "FncE") -BUILTIN(__builtin_fminf, "fff", "FncE") -BUILTIN(__builtin_fminf16, "hhh", "FncE") -BUILTIN(__builtin_fminl, "LdLdLd", "FncE") -BUILTIN(__builtin_fminf128, "LLdLLdLLd", "FncE") -BUILTIN(__builtin_hypot , "ddd" , "Fne") -BUILTIN(__builtin_hypotf, "fff" , "Fne") -BUILTIN(__builtin_hypotl, "LdLdLd", "Fne") -BUILTIN(__builtin_hypotf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_ilogb , "id", "Fne") -BUILTIN(__builtin_ilogbf, "if", "Fne") -BUILTIN(__builtin_ilogbl, "iLd", "Fne") -BUILTIN(__builtin_ilogbf128, "iLLd", "Fne") -BUILTIN(__builtin_lgamma , "dd", "Fn") -BUILTIN(__builtin_lgammaf, "ff", "Fn") -BUILTIN(__builtin_lgammal, "LdLd", "Fn") -BUILTIN(__builtin_lgammaf128, "LLdLLd", "Fn") -BUILTIN(__builtin_llrint, "LLid", "Fne") -BUILTIN(__builtin_llrintf, "LLif", "Fne") -BUILTIN(__builtin_llrintl, "LLiLd", "Fne") -BUILTIN(__builtin_llrintf128, "LLiLLd", "Fne") -BUILTIN(__builtin_llround , "LLid", "Fne") -BUILTIN(__builtin_llroundf, "LLif", "Fne") -BUILTIN(__builtin_llroundl, "LLiLd", "Fne") -BUILTIN(__builtin_llroundf128, "LLiLLd", "Fne") -BUILTIN(__builtin_log , "dd" , "Fne") -BUILTIN(__builtin_log10 , "dd" , "Fne") -BUILTIN(__builtin_log10f, "ff" , "Fne") -BUILTIN(__builtin_log10f16, "hh" , "Fne") -BUILTIN(__builtin_log10l, "LdLd", "Fne") -BUILTIN(__builtin_log10f128, "LLdLLd" , "Fne") -BUILTIN(__builtin_log1p , "dd" , "Fne") -BUILTIN(__builtin_log1pf, "ff" , "Fne") -BUILTIN(__builtin_log1pl, "LdLd", "Fne") -BUILTIN(__builtin_log1pf128, "LLdLLd", "Fne") -BUILTIN(__builtin_log2, "dd" , "Fne") -BUILTIN(__builtin_log2f, "ff" , "Fne") -BUILTIN(__builtin_log2f16, "hh" , "Fne") -BUILTIN(__builtin_log2l, "LdLd" , "Fne") -BUILTIN(__builtin_log2f128, "LLdLLd" , "Fne") -BUILTIN(__builtin_logb , "dd", "Fne") -BUILTIN(__builtin_logbf, "ff", "Fne") -BUILTIN(__builtin_logbl, "LdLd", "Fne") -BUILTIN(__builtin_logbf128, "LLdLLd", "Fne") -BUILTIN(__builtin_logf, "ff" , "Fne") -BUILTIN(__builtin_logf16, "hh" , "Fne") -BUILTIN(__builtin_logl, "LdLd", "Fne") -BUILTIN(__builtin_logf128, "LLdLLd", "Fne") -BUILTIN(__builtin_lrint , "Lid", "Fne") -BUILTIN(__builtin_lrintf, "Lif", "Fne") -BUILTIN(__builtin_lrintl, "LiLd", "Fne") -BUILTIN(__builtin_lrintf128, "LiLLd", "Fne") -BUILTIN(__builtin_lround , "Lid", "Fne") -BUILTIN(__builtin_lroundf, "Lif", "Fne") -BUILTIN(__builtin_lroundl, "LiLd", "Fne") -BUILTIN(__builtin_lroundf128, "LiLLd", "Fne") -BUILTIN(__builtin_nearbyint , "dd", "Fnc") -BUILTIN(__builtin_nearbyintf, "ff", "Fnc") -BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc") -BUILTIN(__builtin_nearbyintf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_nextafter , "ddd", "Fne") -BUILTIN(__builtin_nextafterf, "fff", "Fne") -BUILTIN(__builtin_nextafterl, "LdLdLd", "Fne") -BUILTIN(__builtin_nextafterf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_nexttoward , "ddLd", "Fne") -BUILTIN(__builtin_nexttowardf, "ffLd", "Fne") -BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fne") -BUILTIN(__builtin_nexttowardf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_remainder , "ddd", "Fne") -BUILTIN(__builtin_remainderf, "fff", "Fne") -BUILTIN(__builtin_remainderl, "LdLdLd", "Fne") -BUILTIN(__builtin_remainderf128, "LLdLLdLLd", "Fne") -BUILTIN(__builtin_remquo , "dddi*", "Fn") -BUILTIN(__builtin_remquof, "fffi*", "Fn") -BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn") -BUILTIN(__builtin_remquof128, "LLdLLdLLdi*", "Fn") -BUILTIN(__builtin_rint , "dd", "Fnc") -BUILTIN(__builtin_rintf, "ff", "Fnc") -BUILTIN(__builtin_rintf16, "hh", "Fnc") -BUILTIN(__builtin_rintl, "LdLd", "Fnc") -BUILTIN(__builtin_rintf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_round, "dd" , "Fnc") -BUILTIN(__builtin_roundf, "ff" , "Fnc") -BUILTIN(__builtin_roundf16, "hh" , "Fnc") -BUILTIN(__builtin_roundl, "LdLd" , "Fnc") -BUILTIN(__builtin_roundf128, "LLdLLd" , "Fnc") -BUILTIN(__builtin_roundeven, "dd" , "Fnc") -BUILTIN(__builtin_roundevenf, "ff" , "Fnc") -BUILTIN(__builtin_roundevenf16, "hh" , "Fnc") -BUILTIN(__builtin_roundevenl, "LdLd" , "Fnc") -BUILTIN(__builtin_roundevenf128, "LLdLLd" , "Fnc") -BUILTIN(__builtin_scalbln , "ddLi", "Fne") -BUILTIN(__builtin_scalblnf, "ffLi", "Fne") -BUILTIN(__builtin_scalblnl, "LdLdLi", "Fne") -BUILTIN(__builtin_scalblnf128, "LLdLLdLi", "Fne") -BUILTIN(__builtin_scalbn , "ddi", "Fne") -BUILTIN(__builtin_scalbnf, "ffi", "Fne") -BUILTIN(__builtin_scalbnl, "LdLdi", "Fne") -BUILTIN(__builtin_scalbnf128, "LLdLLdi", "Fne") -BUILTIN(__builtin_sin , "dd" , "Fne") -BUILTIN(__builtin_sinf, "ff" , "Fne") -BUILTIN(__builtin_sinf16, "hh" , "Fne") -BUILTIN(__builtin_sinh , "dd" , "Fne") -BUILTIN(__builtin_sinhf, "ff" , "Fne") -BUILTIN(__builtin_sinhl, "LdLd", "Fne") -BUILTIN(__builtin_sinhf128, "LLdLLd", "Fne") -BUILTIN(__builtin_sinl, "LdLd", "Fne") -BUILTIN(__builtin_sinf128, "LLdLLd" , "Fne") -BUILTIN(__builtin_sqrt , "dd" , "Fne") -BUILTIN(__builtin_sqrtf, "ff" , "Fne") -BUILTIN(__builtin_sqrtf16, "hh" , "Fne") -BUILTIN(__builtin_sqrtl, "LdLd", "Fne") -BUILTIN(__builtin_sqrtf128, "LLdLLd", "Fne") -BUILTIN(__builtin_tan , "dd" , "Fne") -BUILTIN(__builtin_tanf, "ff" , "Fne") -BUILTIN(__builtin_tanh , "dd" , "Fne") -BUILTIN(__builtin_tanhf, "ff" , "Fne") -BUILTIN(__builtin_tanhl, "LdLd", "Fne") -BUILTIN(__builtin_tanhf128, "LLdLLd", "Fne") -BUILTIN(__builtin_tanl, "LdLd", "Fne") -BUILTIN(__builtin_tanf128, "LLdLLd" , "Fne") -BUILTIN(__builtin_tgamma , "dd", "Fne") -BUILTIN(__builtin_tgammaf, "ff", "Fne") -BUILTIN(__builtin_tgammal, "LdLd", "Fne") -BUILTIN(__builtin_tgammaf128, "LLdLLd", "Fne") -BUILTIN(__builtin_trunc , "dd", "Fnc") -BUILTIN(__builtin_truncf, "ff", "Fnc") -BUILTIN(__builtin_truncl, "LdLd", "Fnc") -BUILTIN(__builtin_truncf128, "LLdLLd", "Fnc") -BUILTIN(__builtin_truncf16, "hh", "Fnc") - -// Access to floating point environment -BUILTIN(__builtin_flt_rounds, "i", "n") -BUILTIN(__builtin_set_flt_rounds, "vi", "n") - -// C99 complex builtins -BUILTIN(__builtin_cabs, "dXd", "Fne") -BUILTIN(__builtin_cabsf, "fXf", "Fne") -BUILTIN(__builtin_cabsl, "LdXLd", "Fne") -BUILTIN(__builtin_cacos, "XdXd", "Fne") -BUILTIN(__builtin_cacosf, "XfXf", "Fne") -BUILTIN(__builtin_cacosh, "XdXd", "Fne") -BUILTIN(__builtin_cacoshf, "XfXf", "Fne") -BUILTIN(__builtin_cacoshl, "XLdXLd", "Fne") -BUILTIN(__builtin_cacosl, "XLdXLd", "Fne") -BUILTIN(__builtin_carg, "dXd", "Fne") -BUILTIN(__builtin_cargf, "fXf", "Fne") -BUILTIN(__builtin_cargl, "LdXLd", "Fne") -BUILTIN(__builtin_casin, "XdXd", "Fne") -BUILTIN(__builtin_casinf, "XfXf", "Fne") -BUILTIN(__builtin_casinh, "XdXd", "Fne") -BUILTIN(__builtin_casinhf, "XfXf", "Fne") -BUILTIN(__builtin_casinhl, "XLdXLd", "Fne") -BUILTIN(__builtin_casinl, "XLdXLd", "Fne") -BUILTIN(__builtin_catan, "XdXd", "Fne") -BUILTIN(__builtin_catanf, "XfXf", "Fne") -BUILTIN(__builtin_catanh, "XdXd", "Fne") -BUILTIN(__builtin_catanhf, "XfXf", "Fne") -BUILTIN(__builtin_catanhl, "XLdXLd", "Fne") -BUILTIN(__builtin_catanl, "XLdXLd", "Fne") -BUILTIN(__builtin_ccos, "XdXd", "Fne") -BUILTIN(__builtin_ccosf, "XfXf", "Fne") -BUILTIN(__builtin_ccosl, "XLdXLd", "Fne") -BUILTIN(__builtin_ccosh, "XdXd", "Fne") -BUILTIN(__builtin_ccoshf, "XfXf", "Fne") -BUILTIN(__builtin_ccoshl, "XLdXLd", "Fne") -BUILTIN(__builtin_cexp, "XdXd", "Fne") -BUILTIN(__builtin_cexpf, "XfXf", "Fne") -BUILTIN(__builtin_cexpl, "XLdXLd", "Fne") -BUILTIN(__builtin_cimag, "dXd", "Fnc") -BUILTIN(__builtin_cimagf, "fXf", "Fnc") -BUILTIN(__builtin_cimagl, "LdXLd", "Fnc") -BUILTIN(__builtin_conj, "XdXd", "Fnc") -BUILTIN(__builtin_conjf, "XfXf", "Fnc") -BUILTIN(__builtin_conjl, "XLdXLd", "Fnc") -BUILTIN(__builtin_clog, "XdXd", "Fne") -BUILTIN(__builtin_clogf, "XfXf", "Fne") -BUILTIN(__builtin_clogl, "XLdXLd", "Fne") -BUILTIN(__builtin_cproj, "XdXd", "Fnc") -BUILTIN(__builtin_cprojf, "XfXf", "Fnc") -BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc") -BUILTIN(__builtin_cpow, "XdXdXd", "Fne") -BUILTIN(__builtin_cpowf, "XfXfXf", "Fne") -BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fne") -BUILTIN(__builtin_creal, "dXd", "Fnc") -BUILTIN(__builtin_crealf, "fXf", "Fnc") -BUILTIN(__builtin_creall, "LdXLd", "Fnc") -BUILTIN(__builtin_csin, "XdXd", "Fne") -BUILTIN(__builtin_csinf, "XfXf", "Fne") -BUILTIN(__builtin_csinl, "XLdXLd", "Fne") -BUILTIN(__builtin_csinh, "XdXd", "Fne") -BUILTIN(__builtin_csinhf, "XfXf", "Fne") -BUILTIN(__builtin_csinhl, "XLdXLd", "Fne") -BUILTIN(__builtin_csqrt, "XdXd", "Fne") -BUILTIN(__builtin_csqrtf, "XfXf", "Fne") -BUILTIN(__builtin_csqrtl, "XLdXLd", "Fne") -BUILTIN(__builtin_ctan, "XdXd", "Fne") -BUILTIN(__builtin_ctanf, "XfXf", "Fne") -BUILTIN(__builtin_ctanl, "XLdXLd", "Fne") -BUILTIN(__builtin_ctanh, "XdXd", "Fne") -BUILTIN(__builtin_ctanhf, "XfXf", "Fne") -BUILTIN(__builtin_ctanhl, "XLdXLd", "Fne") - -// GCC-compatible C99 CMPLX implementation. -BUILTIN(__builtin_complex, "v.", "nctE") - -// FP Comparisons. -BUILTIN(__builtin_isgreater , "i.", "Fnct") -BUILTIN(__builtin_isgreaterequal, "i.", "Fnct") -BUILTIN(__builtin_isless , "i.", "Fnct") -BUILTIN(__builtin_islessequal , "i.", "Fnct") -BUILTIN(__builtin_islessgreater , "i.", "Fnct") -BUILTIN(__builtin_isunordered , "i.", "Fnct") - -// Unary FP classification -BUILTIN(__builtin_fpclassify, "iiiiii.", "FnctE") -BUILTIN(__builtin_isfinite, "i.", "FnctE") -BUILTIN(__builtin_isinf, "i.", "FnctE") -BUILTIN(__builtin_isinf_sign, "i.", "FnctE") -BUILTIN(__builtin_isnan, "i.", "FnctE") -BUILTIN(__builtin_isnormal, "i.", "FnctE") -BUILTIN(__builtin_issubnormal,"i.", "FnctE") -BUILTIN(__builtin_iszero, "i.", "FnctE") -BUILTIN(__builtin_issignaling,"i.", "FnctE") -BUILTIN(__builtin_isfpclass, "i.", "nctE") - -// FP signbit builtins -BUILTIN(__builtin_signbit, "i.", "Fnct") -BUILTIN(__builtin_signbitf, "if", "Fnc") -BUILTIN(__builtin_signbitl, "iLd", "Fnc") - -// Special FP builtins. -BUILTIN(__builtin_canonicalize, "dd", "nc") -BUILTIN(__builtin_canonicalizef, "ff", "nc") -BUILTIN(__builtin_canonicalizef16, "hh", "nc") -BUILTIN(__builtin_canonicalizel, "LdLd", "nc") - -// Builtins for arithmetic. -BUILTIN(__builtin_clzs , "iUs" , "ncE") -BUILTIN(__builtin_clz , "iUi" , "ncE") -BUILTIN(__builtin_clzl , "iULi" , "ncE") -BUILTIN(__builtin_clzll, "iULLi", "ncE") -// TODO: int clzimax(uintmax_t) -BUILTIN(__builtin_ctzs , "iUs" , "ncE") -BUILTIN(__builtin_ctz , "iUi" , "ncE") -BUILTIN(__builtin_ctzl , "iULi" , "ncE") -BUILTIN(__builtin_ctzll, "iULLi", "ncE") -// TODO: int ctzimax(uintmax_t) -BUILTIN(__builtin_ffs , "ii" , "FncE") -BUILTIN(__builtin_ffsl , "iLi" , "FncE") -BUILTIN(__builtin_ffsll, "iLLi", "FncE") -BUILTIN(__builtin_parity , "iUi" , "ncE") -BUILTIN(__builtin_parityl , "iULi" , "ncE") -BUILTIN(__builtin_parityll, "iULLi", "ncE") -BUILTIN(__builtin_popcount , "iUi" , "ncE") -BUILTIN(__builtin_popcountl , "iULi" , "ncE") -BUILTIN(__builtin_popcountll, "iULLi", "ncE") -BUILTIN(__builtin_clrsb , "ii" , "ncE") -BUILTIN(__builtin_clrsbl , "iLi" , "ncE") -BUILTIN(__builtin_clrsbll, "iLLi", "ncE") - -// The following builtins rely on that char == 8 bits, short == 16 bits and that -// there exists native types on the target that are 32- and 64-bits wide, unless -// these conditions are fulfilled these builtins will operate on a not intended -// bitwidth. -BUILTIN(__builtin_bswap16, "UsUs", "ncE") -BUILTIN(__builtin_bswap32, "UZiUZi", "ncE") -BUILTIN(__builtin_bswap64, "UWiUWi", "ncE") - -BUILTIN(__builtin_bitreverse8, "UcUc", "ncE") -BUILTIN(__builtin_bitreverse16, "UsUs", "ncE") -BUILTIN(__builtin_bitreverse32, "UZiUZi", "ncE") -BUILTIN(__builtin_bitreverse64, "UWiUWi", "ncE") - -BUILTIN(__builtin_rotateleft8, "UcUcUc", "ncE") -BUILTIN(__builtin_rotateleft16, "UsUsUs", "ncE") -BUILTIN(__builtin_rotateleft32, "UZiUZiUZi", "ncE") -BUILTIN(__builtin_rotateleft64, "UWiUWiUWi", "ncE") -BUILTIN(__builtin_rotateright8, "UcUcUc", "ncE") -BUILTIN(__builtin_rotateright16, "UsUsUs", "ncE") -BUILTIN(__builtin_rotateright32, "UZiUZiUZi", "ncE") -BUILTIN(__builtin_rotateright64, "UWiUWiUWi", "ncE") - -// Random GCC builtins -BUILTIN(__builtin_calloc, "v*zz", "nF") -BUILTIN(__builtin_constant_p, "i.", "nctuE") -BUILTIN(__builtin_classify_type, "i.", "nctuE") -BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "ncE") -BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "ncE") -BUILTIN(__builtin_va_start, "vA.", "nt") -BUILTIN(__builtin_va_end, "vA", "n") -BUILTIN(__builtin_va_copy, "vAA", "n") -BUILTIN(__builtin_stdarg_start, "vA.", "nt") -BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nctE") -BUILTIN(__builtin_bcmp, "ivC*vC*z", "FnE") -BUILTIN(__builtin_bcopy, "vvC*v*z", "nF") -BUILTIN(__builtin_bzero, "vv*z", "nF") -BUILTIN(__builtin_free, "vv*", "nF") -BUILTIN(__builtin_malloc, "v*z", "nF") -BUILTIN(__builtin_memchr, "v*vC*iz", "nFE") -BUILTIN(__builtin_memcmp, "ivC*vC*z", "nFE") -BUILTIN(__builtin_memcpy, "v*v*vC*z", "nFE") -BUILTIN(__builtin_memcpy_inline, "vv*vC*Iz", "n") -BUILTIN(__builtin_memmove, "v*v*vC*z", "nFE") -BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF") -BUILTIN(__builtin_memset, "v*v*iz", "nF") -BUILTIN(__builtin_memset_inline, "vv*iIz", "n") -BUILTIN(__builtin_stpcpy, "c*c*cC*", "nF") -BUILTIN(__builtin_stpncpy, "c*c*cC*z", "nF") -BUILTIN(__builtin_strcasecmp, "icC*cC*", "nF") -BUILTIN(__builtin_strcat, "c*c*cC*", "nF") -BUILTIN(__builtin_strchr, "c*cC*i", "nFE") -BUILTIN(__builtin_strcmp, "icC*cC*", "nFE") -BUILTIN(__builtin_strcpy, "c*c*cC*", "nF") -BUILTIN(__builtin_strcspn, "zcC*cC*", "nF") -BUILTIN(__builtin_strdup, "c*cC*", "nF") -BUILTIN(__builtin_strlen, "zcC*", "nFE") -BUILTIN(__builtin_strncasecmp, "icC*cC*z", "nF") -BUILTIN(__builtin_strncat, "c*c*cC*z", "nF") -BUILTIN(__builtin_strncmp, "icC*cC*z", "nFE") -BUILTIN(__builtin_strncpy, "c*c*cC*z", "nF") -BUILTIN(__builtin_strndup, "c*cC*z", "nF") -BUILTIN(__builtin_strpbrk, "c*cC*cC*", "nF") -BUILTIN(__builtin_strrchr, "c*cC*i", "nF") -BUILTIN(__builtin_strspn, "zcC*cC*", "nF") -BUILTIN(__builtin_strstr, "c*cC*cC*", "nF") -BUILTIN(__builtin_wcschr, "w*wC*w", "nFE") -BUILTIN(__builtin_wcscmp, "iwC*wC*", "nFE") -BUILTIN(__builtin_wcslen, "zwC*", "nFE") -BUILTIN(__builtin_wcsncmp, "iwC*wC*z", "nFE") -BUILTIN(__builtin_wmemchr, "w*wC*wz", "nFE") -BUILTIN(__builtin_wmemcmp, "iwC*wC*z", "nFE") -BUILTIN(__builtin_wmemcpy, "w*w*wC*z", "nFE") -BUILTIN(__builtin_wmemmove, "w*w*wC*z", "nFE") -BUILTIN(__builtin_realloc, "v*v*z", "nF") -BUILTIN(__builtin_return_address, "v*IUi", "n") -BUILTIN(__builtin_extract_return_addr, "v*v*", "n") -BUILTIN(__builtin_frame_address, "v*IUi", "n") -BUILTIN(__builtin___clear_cache, "vc*c*", "n") -BUILTIN(__builtin_setjmp, "iv**", "j") -BUILTIN(__builtin_longjmp, "vv**i", "r") -BUILTIN(__builtin_unwind_init, "v", "") -BUILTIN(__builtin_eh_return_data_regno, "iIi", "ncE") -BUILTIN(__builtin_fprintf, "iP*RcC*R.", "nFp:1:") -BUILTIN(__builtin_printf, "icC*R.", "nFp:0:") -BUILTIN(__builtin_sprintf, "ic*RcC*R.", "nFp:1:") -BUILTIN(__builtin_snprintf, "ic*RzcC*R.", "nFp:2:") -BUILTIN(__builtin_vprintf, "icC*Ra", "nFP:0:") -BUILTIN(__builtin_vfprintf, "iP*RcC*Ra", "nFP:1:") -BUILTIN(__builtin_vsprintf, "ic*RcC*Ra", "nFP:1:") -BUILTIN(__builtin_vsnprintf, "ic*RzcC*Ra", "nFP:2:") -BUILTIN(__builtin_fscanf, "iP*RcC*R.", "Fs:1:") -BUILTIN(__builtin_scanf, "icC*R.", "Fs:0:") -BUILTIN(__builtin_sscanf, "icC*RcC*R.", "Fs:1:") -BUILTIN(__builtin_vfscanf, "iP*RcC*Ra", "FS:1:") -BUILTIN(__builtin_vscanf, "icC*Ra", "FS:0:") -BUILTIN(__builtin_vsscanf, "icC*RcC*Ra", "FS:1:") -BUILTIN(__builtin_thread_pointer, "v*", "nc") -BUILTIN(__builtin_launder, "v*v*", "ntE") -LANGBUILTIN(__builtin_is_constant_evaluated, "b", "nE", CXX_LANG) - -// GCC exception builtins -BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t! -BUILTIN(__builtin_frob_return_addr, "v*v*", "n") -BUILTIN(__builtin_dwarf_cfa, "v*", "n") -BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n") -BUILTIN(__builtin_dwarf_sp_column, "Ui", "n") -BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t - -// GCC Object size checking builtins -BUILTIN(__builtin_object_size, "zvC*i", "nuE") -BUILTIN(__builtin_dynamic_object_size, "zvC*i", "nuE") // Clang only. -BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF") -BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF") -BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF") -BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF") -BUILTIN(__builtin___memset_chk, "v*v*izz", "nF") -BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF") -BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF") -BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF") -BUILTIN(__builtin___strlcat_chk, "zc*cC*zz", "nF") -BUILTIN(__builtin___strlcpy_chk, "zc*cC*zz", "nF") -BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF") -BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF") -BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF") -BUILTIN(__builtin___snprintf_chk, "ic*RzizcC*R.", "Fp:4:") -BUILTIN(__builtin___sprintf_chk, "ic*RizcC*R.", "Fp:3:") -BUILTIN(__builtin___vsnprintf_chk, "ic*RzizcC*Ra", "FP:4:") -BUILTIN(__builtin___vsprintf_chk, "ic*RizcC*Ra", "FP:3:") -BUILTIN(__builtin___fprintf_chk, "iP*RicC*R.", "Fp:2:") -BUILTIN(__builtin___printf_chk, "iicC*R.", "Fp:1:") -BUILTIN(__builtin___vfprintf_chk, "iP*RicC*Ra", "FP:2:") -BUILTIN(__builtin___vprintf_chk, "iicC*Ra", "FP:1:") - -BUILTIN(__builtin_unpredictable, "LiLi" , "nc") -BUILTIN(__builtin_expect, "LiLiLi" , "ncE") -BUILTIN(__builtin_expect_with_probability, "LiLiLid", "ncE") -BUILTIN(__builtin_prefetch, "vvC*.", "nc") -BUILTIN(__builtin_readcyclecounter, "ULLi", "n") -BUILTIN(__builtin_trap, "v", "nr") -BUILTIN(__builtin_debugtrap, "v", "n") -BUILTIN(__builtin_unreachable, "v", "nr") -BUILTIN(__builtin_shufflevector, "v." , "nct") -BUILTIN(__builtin_convertvector, "v." , "nct") -BUILTIN(__builtin_vectorelements, "v." , "nct") -BUILTIN(__builtin_alloca, "v*z" , "Fn") -BUILTIN(__builtin_alloca_uninitialized, "v*z", "Fn") -BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn") -BUILTIN(__builtin_alloca_with_align_uninitialized, "v*zIz", "Fn") -BUILTIN(__builtin_call_with_static_chain, "v.", "nt") -BUILTIN(__builtin_nondeterministic_value, "v.", "nt") - -BUILTIN(__builtin_elementwise_abs, "v.", "nct") -BUILTIN(__builtin_elementwise_bitreverse, "v.", "nct") -BUILTIN(__builtin_elementwise_max, "v.", "nct") -BUILTIN(__builtin_elementwise_min, "v.", "nct") -BUILTIN(__builtin_elementwise_ceil, "v.", "nct") -BUILTIN(__builtin_elementwise_cos, "v.", "nct") -BUILTIN(__builtin_elementwise_exp, "v.", "nct") -BUILTIN(__builtin_elementwise_exp2, "v.", "nct") -BUILTIN(__builtin_elementwise_floor, "v.", "nct") -BUILTIN(__builtin_elementwise_log, "v.", "nct") -BUILTIN(__builtin_elementwise_log2, "v.", "nct") -BUILTIN(__builtin_elementwise_log10, "v.", "nct") -BUILTIN(__builtin_elementwise_pow, "v.", "nct") -BUILTIN(__builtin_elementwise_roundeven, "v.", "nct") -BUILTIN(__builtin_elementwise_round, "v.", "nct") -BUILTIN(__builtin_elementwise_rint, "v.", "nct") -BUILTIN(__builtin_elementwise_nearbyint, "v.", "nct") -BUILTIN(__builtin_elementwise_sin, "v.", "nct") -BUILTIN(__builtin_elementwise_sqrt, "v.", "nct") -BUILTIN(__builtin_elementwise_trunc, "v.", "nct") -BUILTIN(__builtin_elementwise_canonicalize, "v.", "nct") -BUILTIN(__builtin_elementwise_copysign, "v.", "nct") -BUILTIN(__builtin_elementwise_fma, "v.", "nct") -BUILTIN(__builtin_elementwise_add_sat, "v.", "nct") -BUILTIN(__builtin_elementwise_sub_sat, "v.", "nct") -BUILTIN(__builtin_reduce_max, "v.", "nct") -BUILTIN(__builtin_reduce_min, "v.", "nct") -BUILTIN(__builtin_reduce_xor, "v.", "nct") -BUILTIN(__builtin_reduce_or, "v.", "nct") -BUILTIN(__builtin_reduce_and, "v.", "nct") -BUILTIN(__builtin_reduce_add, "v.", "nct") -BUILTIN(__builtin_reduce_mul, "v.", "nct") - -BUILTIN(__builtin_matrix_transpose, "v.", "nFt") -BUILTIN(__builtin_matrix_column_major_load, "v.", "nFt") -BUILTIN(__builtin_matrix_column_major_store, "v.", "nFt") - -// "Overloaded" Atomic operator builtins. These are overloaded to support data -// types of i8, i16, i32, i64, and i128. The front-end sees calls to the -// non-suffixed version of these (which has a bogus type) and transforms them to -// the right overloaded version in Sema (plus casts). - -// FIXME: These assume that char -> i8, short -> i16, int -> i32, -// long long -> i64. - -BUILTIN(__sync_fetch_and_add, "v.", "t") -BUILTIN(__sync_fetch_and_add_1, "ccD*c.", "nt") -BUILTIN(__sync_fetch_and_add_2, "ssD*s.", "nt") -BUILTIN(__sync_fetch_and_add_4, "iiD*i.", "nt") -BUILTIN(__sync_fetch_and_add_8, "LLiLLiD*LLi.", "nt") -BUILTIN(__sync_fetch_and_add_16, "LLLiLLLiD*LLLi.", "nt") - -BUILTIN(__sync_fetch_and_sub, "v.", "t") -BUILTIN(__sync_fetch_and_sub_1, "ccD*c.", "nt") -BUILTIN(__sync_fetch_and_sub_2, "ssD*s.", "nt") -BUILTIN(__sync_fetch_and_sub_4, "iiD*i.", "nt") -BUILTIN(__sync_fetch_and_sub_8, "LLiLLiD*LLi.", "nt") -BUILTIN(__sync_fetch_and_sub_16, "LLLiLLLiD*LLLi.", "nt") - -BUILTIN(__sync_fetch_and_or, "v.", "t") -BUILTIN(__sync_fetch_and_or_1, "ccD*c.", "nt") -BUILTIN(__sync_fetch_and_or_2, "ssD*s.", "nt") -BUILTIN(__sync_fetch_and_or_4, "iiD*i.", "nt") -BUILTIN(__sync_fetch_and_or_8, "LLiLLiD*LLi.", "nt") -BUILTIN(__sync_fetch_and_or_16, "LLLiLLLiD*LLLi.", "nt") - -BUILTIN(__sync_fetch_and_and, "v.", "t") -BUILTIN(__sync_fetch_and_and_1, "ccD*c.", "tn") -BUILTIN(__sync_fetch_and_and_2, "ssD*s.", "tn") -BUILTIN(__sync_fetch_and_and_4, "iiD*i.", "tn") -BUILTIN(__sync_fetch_and_and_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_fetch_and_and_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_fetch_and_xor, "v.", "t") -BUILTIN(__sync_fetch_and_xor_1, "ccD*c.", "tn") -BUILTIN(__sync_fetch_and_xor_2, "ssD*s.", "tn") -BUILTIN(__sync_fetch_and_xor_4, "iiD*i.", "tn") -BUILTIN(__sync_fetch_and_xor_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_fetch_and_nand, "v.", "t") -BUILTIN(__sync_fetch_and_nand_1, "ccD*c.", "tn") -BUILTIN(__sync_fetch_and_nand_2, "ssD*s.", "tn") -BUILTIN(__sync_fetch_and_nand_4, "iiD*i.", "tn") -BUILTIN(__sync_fetch_and_nand_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_fetch_and_nand_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_add_and_fetch, "v.", "t") -BUILTIN(__sync_add_and_fetch_1, "ccD*c.", "tn") -BUILTIN(__sync_add_and_fetch_2, "ssD*s.", "tn") -BUILTIN(__sync_add_and_fetch_4, "iiD*i.", "tn") -BUILTIN(__sync_add_and_fetch_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_add_and_fetch_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_sub_and_fetch, "v.", "t") -BUILTIN(__sync_sub_and_fetch_1, "ccD*c.", "tn") -BUILTIN(__sync_sub_and_fetch_2, "ssD*s.", "tn") -BUILTIN(__sync_sub_and_fetch_4, "iiD*i.", "tn") -BUILTIN(__sync_sub_and_fetch_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_sub_and_fetch_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_or_and_fetch, "v.", "t") -BUILTIN(__sync_or_and_fetch_1, "ccD*c.", "tn") -BUILTIN(__sync_or_and_fetch_2, "ssD*s.", "tn") -BUILTIN(__sync_or_and_fetch_4, "iiD*i.", "tn") -BUILTIN(__sync_or_and_fetch_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_or_and_fetch_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_and_and_fetch, "v.", "t") -BUILTIN(__sync_and_and_fetch_1, "ccD*c.", "tn") -BUILTIN(__sync_and_and_fetch_2, "ssD*s.", "tn") -BUILTIN(__sync_and_and_fetch_4, "iiD*i.", "tn") -BUILTIN(__sync_and_and_fetch_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_and_and_fetch_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_xor_and_fetch, "v.", "t") -BUILTIN(__sync_xor_and_fetch_1, "ccD*c.", "tn") -BUILTIN(__sync_xor_and_fetch_2, "ssD*s.", "tn") -BUILTIN(__sync_xor_and_fetch_4, "iiD*i.", "tn") -BUILTIN(__sync_xor_and_fetch_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_nand_and_fetch, "v.", "t") -BUILTIN(__sync_nand_and_fetch_1, "ccD*c.", "tn") -BUILTIN(__sync_nand_and_fetch_2, "ssD*s.", "tn") -BUILTIN(__sync_nand_and_fetch_4, "iiD*i.", "tn") -BUILTIN(__sync_nand_and_fetch_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_nand_and_fetch_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_bool_compare_and_swap, "v.", "t") -BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "tn") -BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "tn") -BUILTIN(__sync_bool_compare_and_swap_4, "biD*ii.", "tn") -BUILTIN(__sync_bool_compare_and_swap_8, "bLLiD*LLiLLi.", "tn") -BUILTIN(__sync_bool_compare_and_swap_16, "bLLLiD*LLLiLLLi.", "tn") - -BUILTIN(__sync_val_compare_and_swap, "v.", "t") -BUILTIN(__sync_val_compare_and_swap_1, "ccD*cc.", "tn") -BUILTIN(__sync_val_compare_and_swap_2, "ssD*ss.", "tn") -BUILTIN(__sync_val_compare_and_swap_4, "iiD*ii.", "tn") -BUILTIN(__sync_val_compare_and_swap_8, "LLiLLiD*LLiLLi.", "tn") -BUILTIN(__sync_val_compare_and_swap_16, "LLLiLLLiD*LLLiLLLi.", "tn") - -BUILTIN(__sync_lock_test_and_set, "v.", "t") -BUILTIN(__sync_lock_test_and_set_1, "ccD*c.", "tn") -BUILTIN(__sync_lock_test_and_set_2, "ssD*s.", "tn") -BUILTIN(__sync_lock_test_and_set_4, "iiD*i.", "tn") -BUILTIN(__sync_lock_test_and_set_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_lock_test_and_set_16, "LLLiLLLiD*LLLi.", "tn") - -BUILTIN(__sync_lock_release, "v.", "t") -BUILTIN(__sync_lock_release_1, "vcD*.", "tn") -BUILTIN(__sync_lock_release_2, "vsD*.", "tn") -BUILTIN(__sync_lock_release_4, "viD*.", "tn") -BUILTIN(__sync_lock_release_8, "vLLiD*.", "tn") -BUILTIN(__sync_lock_release_16, "vLLLiD*.", "tn") - -BUILTIN(__sync_swap, "v.", "t") -BUILTIN(__sync_swap_1, "ccD*c.", "tn") -BUILTIN(__sync_swap_2, "ssD*s.", "tn") -BUILTIN(__sync_swap_4, "iiD*i.", "tn") -BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "tn") -BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "tn") - -// Some of our atomics builtins are handled by AtomicExpr rather than -// as normal builtin CallExprs. This macro is used for such builtins. -#ifndef ATOMIC_BUILTIN -#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) BUILTIN(ID, TYPE, ATTRS) -#endif - -// C11 _Atomic operations for . -ATOMIC_BUILTIN(__c11_atomic_init, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_load, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_store, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_exchange, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_compare_exchange_strong, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_compare_exchange_weak, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_add, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_sub, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_and, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_or, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_xor, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_nand, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_max, "v.", "t") -ATOMIC_BUILTIN(__c11_atomic_fetch_min, "v.", "t") -BUILTIN(__c11_atomic_thread_fence, "vi", "n") -BUILTIN(__c11_atomic_signal_fence, "vi", "n") -BUILTIN(__c11_atomic_is_lock_free, "bz", "nE") - -// GNU atomic builtins. -ATOMIC_BUILTIN(__atomic_load, "v.", "t") -ATOMIC_BUILTIN(__atomic_load_n, "v.", "t") -ATOMIC_BUILTIN(__atomic_store, "v.", "t") -ATOMIC_BUILTIN(__atomic_store_n, "v.", "t") -ATOMIC_BUILTIN(__atomic_exchange, "v.", "t") -ATOMIC_BUILTIN(__atomic_exchange_n, "v.", "t") -ATOMIC_BUILTIN(__atomic_compare_exchange, "v.", "t") -ATOMIC_BUILTIN(__atomic_compare_exchange_n, "v.", "t") -ATOMIC_BUILTIN(__atomic_fetch_add, "v.", "t") -ATOMIC_BUILTIN(__atomic_fetch_sub, "v.", "t") -ATOMIC_BUILTIN(__atomic_fetch_and, "v.", "t") -ATOMIC_BUILTIN(__atomic_fetch_or, "v.", "t") -ATOMIC_BUILTIN(__atomic_fetch_xor, "v.", "t") -ATOMIC_BUILTIN(__atomic_fetch_nand, "v.", "t") -ATOMIC_BUILTIN(__atomic_add_fetch, "v.", "t") -ATOMIC_BUILTIN(__atomic_sub_fetch, "v.", "t") -ATOMIC_BUILTIN(__atomic_and_fetch, "v.", "t") -ATOMIC_BUILTIN(__atomic_or_fetch, "v.", "t") -ATOMIC_BUILTIN(__atomic_xor_fetch, "v.", "t") -ATOMIC_BUILTIN(__atomic_max_fetch, "v.", "t") -ATOMIC_BUILTIN(__atomic_min_fetch, "v.", "t") -ATOMIC_BUILTIN(__atomic_nand_fetch, "v.", "t") -BUILTIN(__atomic_test_and_set, "bvD*i", "n") -BUILTIN(__atomic_clear, "vvD*i", "n") -BUILTIN(__atomic_thread_fence, "vi", "n") -BUILTIN(__atomic_signal_fence, "vi", "n") -BUILTIN(__atomic_always_lock_free, "bzvCD*", "nE") -BUILTIN(__atomic_is_lock_free, "bzvCD*", "nE") - -// GNU atomic builtins with atomic scopes. -ATOMIC_BUILTIN(__scoped_atomic_load, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_load_n, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_store, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_store_n, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_exchange, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_exchange_n, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_compare_exchange, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_compare_exchange_n, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_add, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_sub, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_and, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_or, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_xor, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_nand, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_add_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_sub_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_and_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_or_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_xor_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_max_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_min_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_nand_fetch, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_min, "v.", "t") -ATOMIC_BUILTIN(__scoped_atomic_fetch_max, "v.", "t") - -// OpenCL 2.0 atomic builtins. -ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_load, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_store, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_exchange, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_compare_exchange_strong, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_compare_exchange_weak, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_fetch_add, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_fetch_sub, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_fetch_and, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_fetch_or, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_fetch_xor, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_fetch_min, "v.", "t") -ATOMIC_BUILTIN(__opencl_atomic_fetch_max, "v.", "t") - -// GCC does not support these, they are a Clang extension. -ATOMIC_BUILTIN(__atomic_fetch_min, "v.", "t") -ATOMIC_BUILTIN(__atomic_fetch_max, "v.", "t") - -// HIP atomic builtins. -ATOMIC_BUILTIN(__hip_atomic_load, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_store, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_compare_exchange_weak, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_compare_exchange_strong, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_exchange, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_fetch_add, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_fetch_sub, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_fetch_and, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_fetch_or, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_fetch_xor, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_fetch_min, "v.", "t") -ATOMIC_BUILTIN(__hip_atomic_fetch_max, "v.", "t") - -#undef ATOMIC_BUILTIN - -// Non-overloaded atomic builtins. -BUILTIN(__sync_synchronize, "v", "n") -// GCC does not support these, they are a Clang extension. -BUILTIN(__sync_fetch_and_min, "iiD*i", "n") -BUILTIN(__sync_fetch_and_max, "iiD*i", "n") -BUILTIN(__sync_fetch_and_umin, "UiUiD*Ui", "n") -BUILTIN(__sync_fetch_and_umax, "UiUiD*Ui", "n") - -// Random libc builtins. -BUILTIN(__builtin_abort, "v", "Fnr") -BUILTIN(__builtin_index, "c*cC*i", "Fn") -BUILTIN(__builtin_rindex, "c*cC*i", "Fn") - -// ignored glibc builtin, see https://sourceware.org/bugzilla/show_bug.cgi?id=25399 -BUILTIN(__warn_memset_zero_len, "v", "nU") - -// Microsoft builtins. These are only active with -fms-extensions. -LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__annotation, "wC*.","n", ALL_MS_LANGUAGES) -LANGBUILTIN(__assume, "vb", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittest, "UcNiC*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittestandcomplement, "UcNi*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittestandreset, "UcNi*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittestandset, "UcNi*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittest64, "UcWiC*Wi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittestandcomplement64, "UcWi*Wi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittestandreset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_bittestandset64, "UcWi*Wi", "n", ALL_MS_LANGUAGES) -LIBBUILTIN(_byteswap_ushort, "UsUs", "fnc", STDLIB_H, ALL_MS_LANGUAGES) -LIBBUILTIN(_byteswap_ulong, "UNiUNi", "fnc", STDLIB_H, ALL_MS_LANGUAGES) -LIBBUILTIN(_byteswap_uint64, "ULLiULLi", "fnc", STDLIB_H, ALL_MS_LANGUAGES) -LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__exception_code, "UNi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_exception_code, "UNi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__exception_info, "v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_exception_info, "v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__GetExceptionInfo, "v*.", "zntu", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedAnd8, "ccD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedAnd16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedAnd, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchange8, "ccD*cc", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchange16, "ssD*ss", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchange, "NiNiD*NiNi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchange64, "LLiLLiD*LLiLLi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedCompareExchangePointer_nf, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedDecrement16, "ssD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedDecrement, "NiNiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchange, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchange8, "ccD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchange16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeAdd8, "ccD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeAdd16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeAdd, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeSub8, "ccD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeSub16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeSub, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedIncrement16, "ssD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedIncrement, "NiNiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedOr8, "ccD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedOr16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedOr, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedXor8, "ccD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedXor16, "ssD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedXor, "NiNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandreset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandreset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandreset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandreset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandreset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandset, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandset64, "UcWiD*Wi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandset_acq, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandset_nf, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_interlockedbittestandset_rel, "UcNiD*Ni", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load8, "ccCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load16, "ssCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load32, "iiCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_load64, "LLiLLiCD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store8, "vcD*c", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store16, "vsD*s", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store32, "viD*i", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__iso_volatile_store64, "vLLiD*LLi", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__lzcnt16, "UsUs", "ncE", ALL_MS_LANGUAGES) -LANGBUILTIN(__lzcnt, "UiUi", "ncE", ALL_MS_LANGUAGES) -LANGBUILTIN(__lzcnt64, "UWiUWi", "ncE", ALL_MS_LANGUAGES) -LANGBUILTIN(__popcnt16, "UsUs", "ncE", ALL_MS_LANGUAGES) -LANGBUILTIN(__popcnt, "UiUi", "ncE", ALL_MS_LANGUAGES) -LANGBUILTIN(__popcnt64, "UWiUWi", "ncE", ALL_MS_LANGUAGES) -LANGBUILTIN(_ReturnAddress, "v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotl8, "UcUcUc", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotl16, "UsUsUc", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotl, "UiUii", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_lrotl, "ULiULii", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotl64, "UWiUWii", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotr8, "UcUcUc", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotr16, "UsUsUc", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotr, "UiUii", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_lrotr, "ULiULii", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(_rotr64, "UWiUWii", "nE", ALL_MS_LANGUAGES) -LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) -LANGBUILTIN(__fastfail, "vUi", "nr", ALL_MS_LANGUAGES) - -// Microsoft library builtins. -LIBBUILTIN(_setjmpex, "iJ", "fjT", SETJMPEX_H, ALL_MS_LANGUAGES) - -// C99 library functions -// C99 stdarg.h -LIBBUILTIN(va_start, "vA.", "fn", STDARG_H, ALL_LANGUAGES) -LIBBUILTIN(va_end, "vA", "fn", STDARG_H, ALL_LANGUAGES) -LIBBUILTIN(va_copy, "vAA", "fn", STDARG_H, ALL_LANGUAGES) -// C99 stdlib.h -LIBBUILTIN(abort, "v", "fr", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(calloc, "v*zz", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(exit, "vi", "fr", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(_Exit, "vi", "fr", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(malloc, "v*z", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(realloc, "v*v*z", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(free, "vv*", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(strtod, "dcC*c**", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(strtof, "fcC*c**", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(strtold, "LdcC*c**", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(strtol, "LicC*c**i", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(strtoll, "LLicC*c**i", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(strtoul, "ULicC*c**i", "f", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(strtoull, "ULLicC*c**i", "f", STDLIB_H, ALL_LANGUAGES) -// C11 stdlib.h -LIBBUILTIN(aligned_alloc, "v*zz", "f", STDLIB_H, ALL_LANGUAGES) -// C99 string.h -LIBBUILTIN(memcpy, "v*v*vC*z", "fE", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(memcmp, "ivC*vC*z", "fE", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(memmove, "v*v*vC*z", "fE", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strcpy, "c*c*cC*", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strncpy, "c*c*cC*z", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strcmp, "icC*cC*", "fE", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strncmp, "icC*cC*z", "fE", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strcat, "c*c*cC*", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strncat, "c*c*cC*z", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strxfrm, "zc*cC*z", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(memchr, "v*vC*iz", "fE", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strchr, "c*cC*i", "fE", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strcspn, "zcC*cC*", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strpbrk, "c*cC*cC*", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strrchr, "c*cC*i", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strspn, "zcC*cC*", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strstr, "c*cC*cC*", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strtok, "c*c*cC*", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(memset, "v*v*iz", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strerror, "c*i", "f", STRING_H, ALL_LANGUAGES) -LIBBUILTIN(strlen, "zcC*", "fE", STRING_H, ALL_LANGUAGES) -// C99 stdio.h -// FIXME: This list is incomplete. -LIBBUILTIN(printf, "icC*.", "fp:0:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(fprintf, "iP*cC*.", "fp:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(snprintf, "ic*zcC*.", "fp:2:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(sprintf, "ic*cC*.", "fp:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(vprintf, "icC*a", "fP:0:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(vfprintf, "iP*cC*a", "fP:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(scanf, "icC*R.", "fs:0:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(fscanf, "iP*RcC*R.", "fs:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(sscanf, "icC*RcC*R.", "fs:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(vscanf, "icC*Ra", "fS:0:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(fopen, "P*cC*cC*", "f", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(fread, "zv*zzP*", "f", STDIO_H, ALL_LANGUAGES) -LIBBUILTIN(fwrite, "zvC*zzP*", "f", STDIO_H, ALL_LANGUAGES) - -// C99 ctype.h -LIBBUILTIN(isalnum, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isalpha, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isblank, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(iscntrl, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isdigit, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isgraph, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(islower, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isprint, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(ispunct, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isspace, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isupper, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(isxdigit, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(tolower, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -LIBBUILTIN(toupper, "ii", "fnU", CTYPE_H, ALL_LANGUAGES) -// C99 wchar.h -// FIXME: This list is incomplete. We should cover at least the functions that -// take format strings. -LIBBUILTIN(wcschr, "w*wC*w", "fE", WCHAR_H, ALL_LANGUAGES) -LIBBUILTIN(wcscmp, "iwC*wC*", "fE", WCHAR_H, ALL_LANGUAGES) -LIBBUILTIN(wcslen, "zwC*", "fE", WCHAR_H, ALL_LANGUAGES) -LIBBUILTIN(wcsncmp, "iwC*wC*z", "fE", WCHAR_H, ALL_LANGUAGES) -LIBBUILTIN(wmemchr, "w*wC*wz", "fE", WCHAR_H, ALL_LANGUAGES) -LIBBUILTIN(wmemcmp, "iwC*wC*z", "fE", WCHAR_H, ALL_LANGUAGES) -LIBBUILTIN(wmemcpy, "w*w*wC*z", "fE", WCHAR_H, ALL_LANGUAGES) -LIBBUILTIN(wmemmove,"w*w*wC*z", "fE", WCHAR_H, ALL_LANGUAGES) - -// C99 -// In some systems setjmp is a macro that expands to _setjmp. We undefine -// it here to avoid having two identical LIBBUILTIN entries. -#undef setjmp -LIBBUILTIN(setjmp, "iJ", "fjT", SETJMP_H, ALL_LANGUAGES) -LIBBUILTIN(longjmp, "vJi", "frT", SETJMP_H, ALL_LANGUAGES) - -// Non-C library functions, active in GNU mode only. -// Functions with (returns_twice) attribute (marked as "j") are still active in -// all languages, because losing this attribute would result in miscompilation -// when these functions are used in non-GNU mode. PR16138. -LIBBUILTIN(alloca, "v*z", "f", STDLIB_H, ALL_GNU_LANGUAGES) -// POSIX malloc.h -LIBBUILTIN(memalign, "v*zz", "f", MALLOC_H, ALL_GNU_LANGUAGES) -// POSIX string.h -LIBBUILTIN(memccpy, "v*v*vC*iz", "f", STRING_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(mempcpy, "v*v*vC*z", "f", STRING_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(stpcpy, "c*c*cC*", "f", STRING_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(stpncpy, "c*c*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(strdup, "c*cC*", "f", STRING_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(strndup, "c*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES) -// POSIX strings.h -LIBBUILTIN(index, "c*cC*i", "f", STRINGS_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(rindex, "c*cC*i", "f", STRINGS_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(bzero, "vv*z", "f", STRINGS_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(bcopy, "vvC*v*z", "f", STRINGS_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(bcmp, "ivC*vC*z", "fE", STRINGS_H, ALL_GNU_LANGUAGES) -// In some systems str[n]casejmp is a macro that expands to _str[n]icmp. -// We undefine then here to avoid wrong name. -#undef strcasecmp -#undef strncasecmp -LIBBUILTIN(strcasecmp, "icC*cC*", "f", STRINGS_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(strncasecmp, "icC*cC*z", "f", STRINGS_H, ALL_GNU_LANGUAGES) -// POSIX unistd.h -LIBBUILTIN(_exit, "vi", "fr", UNISTD_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(vfork, "p", "fjT", UNISTD_H, ALL_LANGUAGES) -// POSIX pthread.h -// FIXME: Should specify argument types. -LIBBUILTIN(pthread_create, "", "fC<2,3>", PTHREAD_H, ALL_GNU_LANGUAGES) - -// POSIX setjmp.h - -// FIXME: MinGW _setjmp has an additional void* parameter. -LIBBUILTIN(_setjmp, "iJ", "fjT", SETJMP_H, ALL_LANGUAGES) -LIBBUILTIN(__sigsetjmp, "iSJi", "fjT", SETJMP_H, ALL_LANGUAGES) -LIBBUILTIN(sigsetjmp, "iSJi", "fjT", SETJMP_H, ALL_LANGUAGES) -LIBBUILTIN(savectx, "iJ", "fjT", SETJMP_H, ALL_LANGUAGES) -LIBBUILTIN(getcontext, "iK*", "fjT", SETJMP_H, ALL_LANGUAGES) - -LIBBUILTIN(_longjmp, "vJi", "frT", SETJMP_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(siglongjmp, "vSJi", "frT", SETJMP_H, ALL_GNU_LANGUAGES) -// non-standard but very common -LIBBUILTIN(strlcpy, "zc*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES) -LIBBUILTIN(strlcat, "zc*cC*z", "f", STRING_H, ALL_GNU_LANGUAGES) -// id objc_msgSend(id, SEL, ...) -LIBBUILTIN(objc_msgSend, "GGH.", "f", OBJC_MESSAGE_H, OBJC_LANG) -// long double objc_msgSend_fpret(id self, SEL op, ...) -LIBBUILTIN(objc_msgSend_fpret, "LdGH.", "f", OBJC_MESSAGE_H, OBJC_LANG) -// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...) -LIBBUILTIN(objc_msgSend_fp2ret, "XLdGH.", "f", OBJC_MESSAGE_H, OBJC_LANG) -// void objc_msgSend_stret (id, SEL, ...) -LIBBUILTIN(objc_msgSend_stret, "vGH.", "f", OBJC_MESSAGE_H, OBJC_LANG) -// id objc_msgSendSuper(struct objc_super *super, SEL op, ...) -LIBBUILTIN(objc_msgSendSuper, "GM*H.", "f", OBJC_MESSAGE_H, OBJC_LANG) -// void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...) -LIBBUILTIN(objc_msgSendSuper_stret, "vM*H.", "f", OBJC_MESSAGE_H, OBJC_LANG) -// id objc_getClass(const char *name) -LIBBUILTIN(objc_getClass, "GcC*", "f", OBJC_RUNTIME_H, OBJC_LANG) -// id objc_getMetaClass(const char *name) -LIBBUILTIN(objc_getMetaClass, "GcC*", "f", OBJC_RUNTIME_H, OBJC_LANG) -// void objc_enumerationMutation(id) -LIBBUILTIN(objc_enumerationMutation, "vG", "f", OBJC_RUNTIME_H, OBJC_LANG) - -// id objc_read_weak(id *location) -LIBBUILTIN(objc_read_weak, "GG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG) -// id objc_assign_weak(id value, id *location) -LIBBUILTIN(objc_assign_weak, "GGG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG) -// id objc_assign_ivar(id value, id dest, ptrdiff_t offset) -LIBBUILTIN(objc_assign_ivar, "GGGY", "f", OBJC_OBJC_AUTO_H, OBJC_LANG) -// id objc_assign_global(id val, id *dest) -LIBBUILTIN(objc_assign_global, "GGG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG) -// id objc_assign_strongCast(id val, id *dest -LIBBUILTIN(objc_assign_strongCast, "GGG*", "f", OBJC_OBJC_AUTO_H, OBJC_LANG) - -// id objc_exception_extract(void *localExceptionData) -LIBBUILTIN(objc_exception_extract, "Gv*", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG) -// void objc_exception_try_enter(void *localExceptionData) -LIBBUILTIN(objc_exception_try_enter, "vv*", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG) -// void objc_exception_try_exit(void *localExceptionData) -LIBBUILTIN(objc_exception_try_exit, "vv*", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG) -// int objc_exception_match(Class exceptionClass, id exception) -LIBBUILTIN(objc_exception_match, "iGG", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG) -// void objc_exception_throw(id exception) -LIBBUILTIN(objc_exception_throw, "vG", "f", OBJC_OBJC_EXCEPTION_H, OBJC_LANG) - -// int objc_sync_enter(id obj) -LIBBUILTIN(objc_sync_enter, "iG", "f", OBJC_OBJC_SYNC_H, OBJC_LANG) -// int objc_sync_exit(id obj) -LIBBUILTIN(objc_sync_exit, "iG", "f", OBJC_OBJC_SYNC_H, OBJC_LANG) - -BUILTIN(__builtin_objc_memmove_collectable, "v*v*vC*z", "nF") - -// void NSLog(NSString *fmt, ...) -LIBBUILTIN(NSLog, "vG.", "fp:0:", FOUNDATION_NSOBJCRUNTIME_H, OBJC_LANG) -// void NSLogv(NSString *fmt, va_list args) -LIBBUILTIN(NSLogv, "vGa", "fP:0:", FOUNDATION_NSOBJCRUNTIME_H, OBJC_LANG) - -// Builtin math library functions -LIBBUILTIN(atan2, "ddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(atan2f, "fff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(atan2l, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(abs, "ii", "fnc", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(labs, "LiLi", "fnc", STDLIB_H, ALL_LANGUAGES) -LIBBUILTIN(llabs, "LLiLLi", "fnc", STDLIB_H, ALL_LANGUAGES) - -LIBBUILTIN(copysign, "ddd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(copysignf, "fff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(copysignl, "LdLdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(fabs, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fabsf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fabsl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -// Some systems define finitef as alias of _finitef. -#if defined (finitef) -#undef finitef -#endif -LIBBUILTIN(finite, "id", "fnc", MATH_H, GNU_LANG) -LIBBUILTIN(finitef, "if", "fnc", MATH_H, GNU_LANG) -LIBBUILTIN(finitel, "iLd", "fnc", MATH_H, GNU_LANG) -// glibc's math.h generates calls to __finite -LIBBUILTIN(__finite, "id", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(__finitef, "if", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(__finitel, "iLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(fmod, "ddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fmodf, "fff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fmodl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(frexp, "ddi*", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(frexpf, "ffi*", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(frexpl, "LdLdi*", "fn", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(ldexp, "ddi", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(ldexpf, "ffi", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(ldexpl, "LdLdi", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(modf, "ddd*", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(modff, "fff*", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(modfl, "LdLdLd*", "fn", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(nan, "dcC*", "fUn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nanf, "fcC*", "fUn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nanl, "LdcC*", "fUn", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(pow, "ddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(powf, "fff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(powl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(acos, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(acosf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(acosl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(acosh, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(acoshf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(acoshl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(asin, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(asinf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(asinl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(asinh, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(asinhf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(asinhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(atan, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(atanf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(atanl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(atanh, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(atanhf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(atanhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(cbrt, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(cbrtf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(cbrtl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(ceil, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(ceilf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(ceill, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(cos, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(cosf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(cosl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(cosh, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(coshf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(coshl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(erf, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(erff, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(erfl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(erfc, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(erfcf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(erfcl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(exp, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(expf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(expl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(exp2, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(exp2f, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(exp2l, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(expm1, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(expm1f, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(expm1l, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(fdim, "ddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fdimf, "fff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fdiml, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(floor, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(floorf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(floorl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(fma, "dddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fmaf, "ffff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fmal, "LdLdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(fmax, "ddd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fmaxf, "fff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fmaxl, "LdLdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(fmin, "ddd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fminf, "fff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(fminl, "LdLdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(hypot, "ddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(hypotf, "fff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(hypotl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(ilogb, "id", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(ilogbf, "if", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(ilogbl, "iLd", "fne", MATH_H, ALL_LANGUAGES) - -// POSIX math.h declares a global, signgam, that lgamma writes to, so these -// shouldn't have "e", "c" or "g" attributes -LIBBUILTIN(lgamma, "dd", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(lgammaf, "ff", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(lgammal, "LdLd", "fn", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(llrint, "LLid", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(llrintf, "LLif", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(llrintl, "LLiLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(llround, "LLid", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(llroundf, "LLif", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(llroundl, "LLiLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(log, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(logf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(logl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(log10, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(log10f, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(log10l, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(log1p, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(log1pf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(log1pl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(log2, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(log2f, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(log2l, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(logb, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(logbf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(logbl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(lrint, "Lid", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(lrintf, "Lif", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(lrintl, "LiLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(lround, "Lid", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(lroundf, "Lif", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(lroundl, "LiLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(nearbyint, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nearbyintf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nearbyintl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(nextafter, "ddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nextafterf, "fff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nextafterl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(nexttoward, "ddLd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nexttowardf, "ffLd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(nexttowardl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(remainder, "ddd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(remainderf, "fff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(remainderl, "LdLdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(remquo, "dddi*", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(remquof, "fffi*", "fn", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(remquol, "LdLdLdi*", "fn", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(rint, "dd", "fng", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(rintf, "ff", "fng", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(rintl, "LdLd", "fng", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(round, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(roundf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(roundl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(roundeven, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(roundevenf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(roundevenl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(scalbln, "ddLi", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(scalblnf, "ffLi", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(scalblnl, "LdLdLi", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(scalbn, "ddi", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(scalbnf, "ffi", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(scalbnl, "LdLdi", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(sin, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(sinf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(sinl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(sinh, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(sinhf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(sinhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(sqrt, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(sqrtf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(sqrtl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(tan, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(tanf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(tanl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(tanh, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(tanhf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(tanhl, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(tgamma, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(tgammaf, "ff", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(tgammal, "LdLd", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(trunc, "dd", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(truncf, "ff", "fnc", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(truncl, "LdLd", "fnc", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(cabs, "dXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cabsf, "fXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cabsl, "LdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(cacos, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cacosf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cacosl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(cacosh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cacoshf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cacoshl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(carg, "dXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cargf, "fXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cargl, "LdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(casin, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(casinf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(casinl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(casinh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(casinhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(casinhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(catan, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(catanf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(catanl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(catanh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(catanhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(catanhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(ccos, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ccosf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ccosl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(ccosh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ccoshf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ccoshl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(cexp, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cexpf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cexpl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(cimag, "dXd", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cimagf, "fXf", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cimagl, "LdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(conj, "XdXd", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(conjf, "XfXf", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(conjl, "XLdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(clog, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(clogf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(clogl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(cproj, "XdXd", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cprojf, "XfXf", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cprojl, "XLdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(cpow, "XdXdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cpowf, "XfXfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(cpowl, "XLdXLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(creal, "dXd", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(crealf, "fXf", "fnc", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(creall, "LdXLd", "fnc", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(csin, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(csinf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(csinl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(csinh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(csinhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(csinhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(csqrt, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(csqrtf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(csqrtl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(ctan, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ctanf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ctanl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -LIBBUILTIN(ctanh, "XdXd", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ctanhf, "XfXf", "fne", COMPLEX_H, ALL_LANGUAGES) -LIBBUILTIN(ctanhl, "XLdXLd", "fne", COMPLEX_H, ALL_LANGUAGES) - -// __sinpi and friends are OS X specific library functions, but otherwise much -// like the standard (non-complex) sin (etc). -LIBBUILTIN(__sinpi, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(__sinpif, "ff", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(__cospi, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(__cospif, "ff", "fne", MATH_H, ALL_LANGUAGES) - -LIBBUILTIN(__tanpi, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(__tanpif, "ff", "fne", MATH_H, ALL_LANGUAGES) - -// Similarly, __exp10 is OS X only -LIBBUILTIN(__exp10, "dd", "fne", MATH_H, ALL_LANGUAGES) -LIBBUILTIN(__exp10f, "ff", "fne", MATH_H, ALL_LANGUAGES) - -// Blocks runtime Builtin math library functions -LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", BLOCKS_H, ALL_LANGUAGES) -LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", BLOCKS_H, ALL_LANGUAGES) -// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock. - -// C++ standard library builtins in namespace 'std'. -LIBBUILTIN(addressof, "v*v&", "zfncThE", MEMORY, CXX_LANG) -// Synonym for addressof used internally by libstdc++. -LANGBUILTIN(__addressof, "v*v&", "zfncTE", CXX_LANG) -LIBBUILTIN(as_const, "v&v&", "zfncThE", UTILITY, CXX_LANG) -LIBBUILTIN(forward, "v&v&", "zfncThE", UTILITY, CXX_LANG) -LIBBUILTIN(forward_like, "v&v&", "zfncThE", UTILITY, CXX_LANG) -LIBBUILTIN(move, "v&v&", "zfncThE", UTILITY, CXX_LANG) -LIBBUILTIN(move_if_noexcept, "v&v&", "zfncThE", UTILITY, CXX_LANG) - -// Annotation function -BUILTIN(__builtin_annotation, "v.", "tn") - -// Invariants -BUILTIN(__builtin_assume, "vb", "nE") -BUILTIN(__builtin_assume_separate_storage, "vvCD*vCD*", "nE") - -// Multiprecision Arithmetic Builtins. -BUILTIN(__builtin_addcb, "UcUcCUcCUcCUc*", "n") -BUILTIN(__builtin_addcs, "UsUsCUsCUsCUs*", "n") -BUILTIN(__builtin_addc, "UiUiCUiCUiCUi*", "n") -BUILTIN(__builtin_addcl, "ULiULiCULiCULiCULi*", "n") -BUILTIN(__builtin_addcll, "ULLiULLiCULLiCULLiCULLi*", "n") -BUILTIN(__builtin_subcb, "UcUcCUcCUcCUc*", "n") -BUILTIN(__builtin_subcs, "UsUsCUsCUsCUs*", "n") -BUILTIN(__builtin_subc, "UiUiCUiCUiCUi*", "n") -BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n") -BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n") - -// Checked Arithmetic Builtins for Security. -BUILTIN(__builtin_add_overflow, "b.", "ntE") -BUILTIN(__builtin_sub_overflow, "b.", "ntE") -BUILTIN(__builtin_mul_overflow, "b.", "ntE") -BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "nE") -BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "nE") -BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "nE") -BUILTIN(__builtin_usub_overflow, "bUiCUiCUi*", "nE") -BUILTIN(__builtin_usubl_overflow, "bULiCULiCULi*", "nE") -BUILTIN(__builtin_usubll_overflow, "bULLiCULLiCULLi*", "nE") -BUILTIN(__builtin_umul_overflow, "bUiCUiCUi*", "nE") -BUILTIN(__builtin_umull_overflow, "bULiCULiCULi*", "nE") -BUILTIN(__builtin_umulll_overflow, "bULLiCULLiCULLi*", "nE") -BUILTIN(__builtin_sadd_overflow, "bSiCSiCSi*", "nE") -BUILTIN(__builtin_saddl_overflow, "bSLiCSLiCSLi*", "nE") -BUILTIN(__builtin_saddll_overflow, "bSLLiCSLLiCSLLi*", "nE") -BUILTIN(__builtin_ssub_overflow, "bSiCSiCSi*", "nE") -BUILTIN(__builtin_ssubl_overflow, "bSLiCSLiCSLi*", "nE") -BUILTIN(__builtin_ssubll_overflow, "bSLLiCSLLiCSLLi*", "nE") -BUILTIN(__builtin_smul_overflow, "bSiCSiCSi*", "nE") -BUILTIN(__builtin_smull_overflow, "bSLiCSLiCSLi*", "nE") -BUILTIN(__builtin_smulll_overflow, "bSLLiCSLLiCSLLi*", "nE") - -// Clang builtins (not available in GCC). -BUILTIN(__builtin_addressof, "v*v&", "nctE") -BUILTIN(__builtin_function_start, "v*v&", "nctE") -BUILTIN(__builtin_operator_new, "v*z", "tcE") -BUILTIN(__builtin_operator_delete, "vv*", "tnE") -BUILTIN(__builtin_char_memchr, "c*cC*iz", "nE") -BUILTIN(__builtin_dump_struct, "v.", "t") -BUILTIN(__builtin_preserve_access_index, "v.", "t") - -// Alignment builtins (uses custom parsing to support pointers and integers) -BUILTIN(__builtin_is_aligned, "bvC*z", "nctE") -BUILTIN(__builtin_align_up, "v*vC*z", "nctE") -BUILTIN(__builtin_align_down, "v*vC*z", "nctE") - -// Safestack builtins -BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn") -BUILTIN(__builtin___get_unsafe_stack_bottom, "v*", "Fn") -BUILTIN(__builtin___get_unsafe_stack_top, "v*", "Fn") -BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn") - -// Nontemporal loads/stores builtins -BUILTIN(__builtin_nontemporal_store, "v.", "t") -BUILTIN(__builtin_nontemporal_load, "v.", "t") - -// Coroutine intrinsics. -LANGBUILTIN(__builtin_coro_resume, "vv*", "", COR_LANG) -LANGBUILTIN(__builtin_coro_destroy, "vv*", "", COR_LANG) -LANGBUILTIN(__builtin_coro_done, "bv*", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_promise, "v*v*IiIb", "n", COR_LANG) - -LANGBUILTIN(__builtin_coro_size, "z", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_align, "z", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_frame, "v*", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_noop, "v*", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_free, "v*v*", "n", COR_LANG) - -LANGBUILTIN(__builtin_coro_id, "v*Iiv*v*v*", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_alloc, "b", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_begin, "v*v*", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_end, "bv*Ib", "n", COR_LANG) -LANGBUILTIN(__builtin_coro_suspend, "cIb", "n", COR_LANG) - -// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. -// We need the generic prototype, since the packet type could be anything. -LANGBUILTIN(read_pipe, "i.", "tn", OCL_PIPE) -LANGBUILTIN(write_pipe, "i.", "tn", OCL_PIPE) - -LANGBUILTIN(reserve_read_pipe, "i.", "tn", OCL_PIPE) -LANGBUILTIN(reserve_write_pipe, "i.", "tn", OCL_PIPE) - -LANGBUILTIN(commit_write_pipe, "v.", "tn", OCL_PIPE) -LANGBUILTIN(commit_read_pipe, "v.", "tn", OCL_PIPE) - -LANGBUILTIN(sub_group_reserve_read_pipe, "i.", "tn", OCL_PIPE) -LANGBUILTIN(sub_group_reserve_write_pipe, "i.", "tn", OCL_PIPE) - -LANGBUILTIN(sub_group_commit_read_pipe, "v.", "tn", OCL_PIPE) -LANGBUILTIN(sub_group_commit_write_pipe, "v.", "tn", OCL_PIPE) - -LANGBUILTIN(work_group_reserve_read_pipe, "i.", "tn", OCL_PIPE) -LANGBUILTIN(work_group_reserve_write_pipe, "i.", "tn", OCL_PIPE) - -LANGBUILTIN(work_group_commit_read_pipe, "v.", "tn", OCL_PIPE) -LANGBUILTIN(work_group_commit_write_pipe, "v.", "tn", OCL_PIPE) - -LANGBUILTIN(get_pipe_num_packets, "Ui.", "tn", OCL_PIPE) -LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCL_PIPE) - -// OpenCL v2.0 s6.13.17 - Enqueue kernel functions. -// Custom builtin check allows to perform special check of passed block arguments. -LANGBUILTIN(enqueue_kernel, "i.", "tn", OCL_DSE) -LANGBUILTIN(get_kernel_work_group_size, "Ui.", "tn", OCL_DSE) -LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "Ui.", "tn", OCL_DSE) -LANGBUILTIN(get_kernel_max_sub_group_size_for_ndrange, "Ui.", "tn", OCL_DSE) -LANGBUILTIN(get_kernel_sub_group_count_for_ndrange, "Ui.", "tn", OCL_DSE) - -// OpenCL v2.0 s6.13.9 - Address space qualifier functions. -// FIXME: Pointer parameters of OpenCL builtins should have their address space -// requirement defined. -LANGBUILTIN(to_global, "v*v*", "tn", OCL_GAS) -LANGBUILTIN(to_local, "v*v*", "tn", OCL_GAS) -LANGBUILTIN(to_private, "v*v*", "tn", OCL_GAS) - -// OpenCL half load/store builtin -LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCL_LANGUAGES) -LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCL_LANGUAGES) -LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCL_LANGUAGES) -LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCL_LANGUAGES) - -// Builtins for os_log/os_trace -BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nutE") -BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt") - -// CUDA/HIP -LANGBUILTIN(__builtin_get_device_side_mangled_name, "cC*.", "ncT", CUDA_LANG) - -// HLSL -LANGBUILTIN(__builtin_hlsl_wave_active_count_bits, "Uib", "nc", HLSL_LANG) -LANGBUILTIN(__builtin_hlsl_create_handle, "v*Uc", "nc", HLSL_LANG) - -// Builtins for XRay -BUILTIN(__xray_customevent, "vcC*z", "") -BUILTIN(__xray_typedevent, "vzcC*z", "") - -// Win64-compatible va_list functions -BUILTIN(__builtin_ms_va_start, "vc*&.", "nt") -BUILTIN(__builtin_ms_va_end, "vc*&", "n") -BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n") - -// Arithmetic Fence: to prevent FP reordering and reassociation optimizations -LANGBUILTIN(__arithmetic_fence, "v.", "tE", ALL_LANGUAGES) - -#undef BUILTIN -#undef LIBBUILTIN -#undef LANGBUILTIN +// G -> this is a C++20 consteval function diff --git a/contrib/llvm-project/clang/include/clang/Basic/Builtins.h b/contrib/llvm-project/clang/include/clang/Basic/Builtins.h index 3fd5b02b5aa..e85ec5b2dca 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Builtins.h +++ b/contrib/llvm-project/clang/include/clang/Basic/Builtins.h @@ -64,7 +64,7 @@ namespace Builtin { enum ID { NotBuiltin = 0, // This is not a builtin function. #define BUILTIN(ID, TYPE, ATTRS) BI##ID, -#include "clang/Basic/Builtins.def" +#include "clang/Basic/Builtins.inc" FirstTSBuiltin }; @@ -280,6 +280,11 @@ public: return strchr(getRecord(ID).Attributes, 'E') != nullptr; } + /// Returns true if this is an immediate (consteval) function + bool isImmediate(unsigned ID) const { + return strchr(getRecord(ID).Attributes, 'G') != nullptr; + } + private: const Info &getRecord(unsigned ID) const; diff --git a/contrib/llvm-project/clang/include/clang/Basic/Builtins.td b/contrib/llvm-project/clang/include/clang/Basic/Builtins.td new file mode 100644 index 00000000000..4133f6ff40c --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/Builtins.td @@ -0,0 +1,4770 @@ +//===--- Builtins.td - Builtins function info 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 +// +//===----------------------------------------------------------------------===// + +include "clang/Basic/BuiltinsBase.td" + +class FPMathTemplate : Template<["float", "double", "long double"], + ["f", "", "l"]>; + +class FPMathWithF16Template : + Template<["float", "double", "long double", "__fp16"], + ["f", "", "l", "f16"]>; + +class FPMathWithF16F128Template : + Template<["float", "double", "long double", "__fp16", "__float128"], + ["f", "", "l", "f16", "f128"]>; + +class FPMathWithF128Template : + Template<["float", "double", "long double", "__float128"], + ["f", "", "l", "f128"]>; + +class F16F128MathTemplate : Template<["__fp16", "__float128"], + ["f16", "f128"]>; + +class IntMathTemplate : Template<["int", "long int", "long long int"], + ["", "l", "ll"], /*AsPrefix=*/1>; + +class MSInt8_16_32Template : Template<["char", "short", "msint32_t"], + ["8", "16", ""]>; + +class Int8_16_32_64Template + : Template<["char", "short", "int", "long long int"], + ["8", "16", "32", "64"]>; + +class MSInt8_16_32_64Template + : Template<["char", "short", "msint32_t", "long long int"], + ["8", "16", "", "64"]>; + +class MSInt16_32Template : Template<["short", "msint32_t"], + ["16", ""]>; + +class MSUInt16_32_64Template : + Template<["unsigned short", "unsigned int", "uint64_t"], + ["16", "", "64"]>; + +class MSInt32_64Template : Template<["msint32_t", "int64_t"], + ["", "64"]>; + +class FloatDoubleTemplate : Template<["float", "double"], + ["f", ""]>; + +// FIXME: These assume that char -> i8, short -> i16, int -> i32, +// long long -> i64. +class SyncBuiltinsTemplate : + Template<["char", "short", "int", "long long int", "__int128_t"], + ["1", "2", "4", "8", "16"]>; + +class BitInt8_16_32_64BuiltinsTemplate : + Template<["unsigned char", "unsigned short", "uint32_t", "uint64_t"], + ["8", "16", "32", "64"]>; + +class BitShort_Int_Long_LongLongTemplate : + Template<["short", "int", "long int", "long long int"], + ["s", "", "l", "ll"]>; + +class BitInt_Long_LongLongTemplate : + Template<["int", "long int", "long long int"], + ["", "l", "ll"]>; + +// Most of the types used in the prototypes are types from C, C++ or ObjC. There +// are a few builtin-specific types and qualifiers. +// +// builtin-specific types: +// - __builtin_va_list: This is the internal representation for va_lists +// - __builtin_va_list_ref: A reference-like type to __builtin_va_list +// - msint32_t: 'int' size if target is LP64, 'L' otherwise. +// +// builtin-specific qualifiers: +// - _Constant: Argument has to constant-fold to an integer constant expression + +// __fp16 and __float128 builtin variants of libc/libm functions. +def AcosF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_acos"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def AcoshF128 : Builtin { + let Spellings = ["__builtin_acoshf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def AsinF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_asin"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def AsinhF128 : Builtin { + let Spellings = ["__builtin_asinhf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def AtanF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_atan"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def AtanhF128 : Builtin { + let Spellings = ["__builtin_atanhf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def CbrtF128 : Builtin { + let Spellings = ["__builtin_cbrtf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "__float128(__float128)"; +} + +def CeilF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_ceil"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "T(T)"; +} + +def CosF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_cos"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def CoshF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_cosh"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def ErfF128 : Builtin { + let Spellings = ["__builtin_erff128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def ErfcF128 : Builtin { + let Spellings = ["__builtin_erfcf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def ExpF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_exp"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def Exp2F16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_exp2"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def Exp10F16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_exp10"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def Expm1F128 : Builtin { + let Spellings = ["__builtin_expm1f128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def FdimF128 : Builtin { + let Spellings = ["__builtin_fdimf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, __float128)"; +} + +def FloorF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_floor"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "T(T)"; +} + +def FmaF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_fma"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T, T)"; +} + +def FmaxF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_fmax"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr]; + let Prototype = "T(T, T)"; +} + +def FminF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_fmin"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr]; + let Prototype = "T(T, T)"; +} + +def Atan2F128 : Builtin { + let Spellings = ["__builtin_atan2f128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, __float128)"; +} + +def CopysignF16 : Builtin { + let Spellings = ["__builtin_copysignf16"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "__fp16(__fp16, __fp16)"; +} + +def CopysignF128 : Builtin { + let Spellings = ["__builtin_copysignf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr]; + let Prototype = "__float128(__float128, __float128)"; +} + +def FabsF16 : Builtin { + let Spellings = ["__builtin_fabsf16"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "__fp16(__fp16)"; +} + +def FabsF128 : Builtin { + let Spellings = ["__builtin_fabsf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr]; + let Prototype = "__float128(__float128)"; +} + +def FmodF16F128 : F16F128MathTemplate, Builtin { + let Spellings = ["__builtin_fmod"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; +} + +def FrexpF16F128 : F16F128MathTemplate, Builtin { + let Spellings = ["__builtin_frexp"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "T(T, int*)"; +} + +def HugeVal : Builtin, FPMathWithF128Template { + let Spellings = ["__builtin_huge_val"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T()"; +} + +def HugeValF16 : Builtin { + let Spellings = ["__builtin_huge_valf16"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "_Float16()"; +} + +def Inf : Builtin, FPMathWithF128Template { + let Spellings = ["__builtin_inf"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T()"; +} + +def InfF16 : Builtin { + let Spellings = ["__builtin_inff16"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "_Float16()"; +} + +def LdexpF16F128 : F16F128MathTemplate, Builtin { + let Spellings = ["__builtin_ldexp"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, int)"; +} + +def ModfF128 : Builtin { + let Spellings = ["__builtin_modff128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "__float128(__float128, __float128*)"; +} + +// This isn't a FPMathWithF16F128Template because the f16 +// version takes a _Float16 for some reason. +def NanF16 : Builtin { + let Spellings = ["__builtin_nanf16"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Pure, Constexpr]; + let Prototype = "_Float16(char const*)"; +} + +def NanF128 : Builtin { + let Spellings = ["__builtin_nanf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Pure, Constexpr]; + let Prototype = "__float128(char const*)"; +} + +def Nans : Builtin, + Template<["float", "double", "long double", "_Float16", "__float128"], + ["f", "", "l", "f16", "f128"]> { + let Spellings = ["__builtin_nans"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Pure, Constexpr]; + let Prototype = "T(char const*)"; +} + +def PowI : Builtin, FPMathTemplate { + let Spellings = ["__builtin_powi"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "T(T, int)"; +} + +def PowF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_pow"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; +} + +def HypotF128 : Builtin { + let Spellings = ["__builtin_hypotf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, __float128)"; +} + +def ILogbF128 : Builtin { + let Spellings = ["__builtin_ilogbf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "int(__float128)"; +} + +def LgammaF128 : Builtin { + let Spellings = ["__builtin_lgammaf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "__float128(__float128)"; +} + +def LLrintF128 : Builtin { + let Spellings = ["__builtin_llrintf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long long int(__float128)"; +} + +def LLroundF128 : Builtin { + let Spellings = ["__builtin_llroundf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long long int(__float128)"; +} + +def Log10F16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_log10"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def Log1pF128 : Builtin { + let Spellings = ["__builtin_log1pf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def Log2F16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_log2"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def LogbF128 : Builtin { + let Spellings = ["__builtin_logbf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def LogF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_log"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def LrintF128 : Builtin { + let Spellings = ["__builtin_lrintf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long int(__float128)"; +} + +def LroundF128 : Builtin { + let Spellings = ["__builtin_lroundf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long int(__float128)"; +} + +def NearbyintF128 : Builtin { + let Spellings = ["__builtin_nearbyintf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "__float128(__float128)"; +} + +def NextafterF128 : Builtin { + let Spellings = ["__builtin_nextafterf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, __float128)"; +} + +def NexttowardF128 : Builtin { + let Spellings = ["__builtin_nexttowardf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, __float128)"; +} + +def RemainderF128 : Builtin { + let Spellings = ["__builtin_remainderf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, __float128)"; +} + +def RemquoF128 : Builtin { + let Spellings = ["__builtin_remquof128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "__float128(__float128, __float128, int*)"; +} + +def RintF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_rint"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "T(T)"; +} + +def RoundF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_round"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "T(T)"; +} + +def RoundevenF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_roundeven"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "T(T)"; +} + +def ScanlblnF128 : Builtin { + let Spellings = ["__builtin_scalblnf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, long int)"; +} + +def ScanlbnF128 : Builtin { + let Spellings = ["__builtin_scalbnf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128, int)"; +} + +def SinF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_sin"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def SinhF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_sinh"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def SqrtF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_sqrt"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def TanF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_tan"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def TanhF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_tanh"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def TgammaF128 : Builtin { + let Spellings = ["__builtin_tgammaf128"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "__float128(__float128)"; +} + +def TruncF16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_trunc"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "T(T)"; +} + +// Access to floating point environment. +def BuiltinFltRounds : Builtin { + let Spellings = ["__builtin_flt_rounds"]; + let Attributes = [NoThrow]; + let Prototype = "int()"; +} + +def BuiltinSetFltRounds : Builtin { + let Spellings = ["__builtin_set_flt_rounds"]; + let Attributes = [NoThrow]; + let Prototype = "void(int)"; +} + +// GCC-compatible C99 CMPLX implementation. +def BuiltinComplex : Builtin { + let Spellings = ["__builtin_complex"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "void(...)"; +} + +// FP Comparison functions. +def IsGreater : Builtin { + let Spellings = ["__builtin_isgreater"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def IsGreaterEqual : Builtin { + let Spellings = ["__builtin_isgreaterequal"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def IsLess : Builtin { + let Spellings = ["__builtin_isless"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def IsLessEqual : Builtin { + let Spellings = ["__builtin_islessequal"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def IsLessGreater : Builtin { + let Spellings = ["__builtin_islessgreater"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def IsUnordered : Builtin { + let Spellings = ["__builtin_isunordered"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking]; + let Prototype = "int(...)"; +} + +// Unary FP classification. +def FPClassify : Builtin { + let Spellings = ["__builtin_fpclassify"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(int, int, int, int, int, ...)"; +} + +def IsFinite : Builtin { + let Spellings = ["__builtin_isfinite"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsInf : Builtin { + let Spellings = ["__builtin_isinf"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsInfSign : Builtin { + let Spellings = ["__builtin_isinf_sign"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsNan : Builtin { + let Spellings = ["__builtin_isnan"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsNormal : Builtin { + let Spellings = ["__builtin_isnormal"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsSubnormal : Builtin { + let Spellings = ["__builtin_issubnormal"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsZero : Builtin { + let Spellings = ["__builtin_iszero"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsSignaling : Builtin { + let Spellings = ["__builtin_issignaling"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +def IsFPClass : Builtin { + let Spellings = ["__builtin_isfpclass"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "int(...)"; +} + +// FP signbit builtins. +def Signbit : Builtin { + let Spellings = ["__builtin_signbit"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, + CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def SignbitF : Builtin { + let Spellings = ["__builtin_signbitf"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "int(float)"; +} + +def SignbitL : Builtin { + let Spellings = ["__builtin_signbitl"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const]; + let Prototype = "int(long double)"; +} + +// Special FP builtins. +def Canonicalize : Builtin, FPMathWithF16Template { + let Spellings = ["__builtin_canonicalize"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; +} + +// Builtins for arithmetic. +def Clz : Builtin, BitShort_Int_Long_LongLongTemplate { + let Spellings = ["__builtin_clz"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "int(unsigned T)"; +} + +def Clzg : Builtin { + let Spellings = ["__builtin_clzg"]; + let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate { + let Spellings = ["__builtin_ctz"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "int(unsigned T)"; +} + +def Ctzg : Builtin { + let Spellings = ["__builtin_ctzg"]; + let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def FFS : Builtin, BitInt_Long_LongLongTemplate { + let Spellings = ["__builtin_ffs"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Const, Constexpr]; + let Prototype = "int(T)"; +} + +def Parity : Builtin, BitInt_Long_LongLongTemplate { + let Spellings = ["__builtin_parity"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "int(unsigned T)"; +} + +def Popcount : Builtin, BitInt_Long_LongLongTemplate { + let Spellings = ["__builtin_popcount"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "int(unsigned T)"; +} + +def Popcountg : Builtin { + let Spellings = ["__builtin_popcountg"]; + let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking]; + let Prototype = "int(...)"; +} + +def Clrsb : Builtin, BitInt_Long_LongLongTemplate { + let Spellings = ["__builtin_clrsb"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "int(T)"; +} + +// The following builtins rely on that char == 8 bits, short == 16 bits and that +// there exists native types on the target that are 32- and 64-bits wide, unless +// these conditions are fulfilled these builtins will operate on a not intended +// bitwidth. +def BSwap : Builtin, Template<["unsigned short", "uint32_t", "uint64_t"], + ["16", "32", "64"]> { + let Spellings = ["__builtin_bswap"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T(T)"; +} + +def Bitreverse : BitInt8_16_32_64BuiltinsTemplate, Builtin { + let Spellings = ["__builtin_bitreverse"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T(T)"; +} + +def RotateLeft : BitInt8_16_32_64BuiltinsTemplate, Builtin { + let Spellings = ["__builtin_rotateleft"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T(T, T)"; +} + +def RotateRight : BitInt8_16_32_64BuiltinsTemplate, Builtin { + let Spellings = ["__builtin_rotateright"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T(T, T)"; +} + +// Random GCC builtins +// FIXME: The builtins marked FunctionWithBuiltinPrefix below should be +// merged with the library definitions. They are currently not because +// the attributes are different. + +// Builtins for checking CPU features based on the GCC builtins. +def BuiltinCPUIs : Builtin { + let Spellings = ["__builtin_cpu_is"]; + let Attributes = [NoThrow, Const]; + let Prototype = "bool(char const*)"; +} + +def BuiltinCPUSupports : Builtin { + let Spellings = ["__builtin_cpu_supports"]; + let Attributes = [NoThrow, Const]; + let Prototype = "bool(char const*)"; +} + +def BuiltinCPUInit : Builtin { + let Spellings = ["__builtin_cpu_init"]; + let Attributes = [NoThrow]; + let Prototype = "void()"; +} + +def BuiltinCalloc : Builtin { + let Spellings = ["__builtin_calloc"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(size_t, size_t)"; +} + +def BuiltinConstantP : Builtin { + let Spellings = ["__builtin_constant_p"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, UnevaluatedArguments, Constexpr]; + let Prototype = "int(...)"; +} + +def BuiltinClassifyType : Builtin { + let Spellings = ["__builtin_classify_type"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, UnevaluatedArguments, Constexpr]; + let Prototype = "int(...)"; +} + +def BuiltinCFStringMakeConstantString : Builtin { + let Spellings = ["__builtin___CFStringMakeConstantString"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "constant_CFString const*(char const*)"; +} + +def BuiltinNSStringMakeConstantString : Builtin { + let Spellings = ["__builtin___NSStringMakeConstantString"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "constant_CFString const*(char const*)"; +} + +def BuiltinVaStart : Builtin { + let Spellings = ["__builtin_va_start"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(__builtin_va_list_ref, ...)"; +} + +def BuiltinStdargStart : Builtin { + let Spellings = ["__builtin_stdarg_start"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(__builtin_va_list_ref, ...)"; +} + +def BuiltinAssumeAligned : Builtin { + let Spellings = ["__builtin_assume_aligned"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "void*(void const*, size_t, ...)"; +} + +def BuiltinFree : Builtin { + let Spellings = ["__builtin_free"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void(void*)"; +} + +def BuiltinMalloc : Builtin { + let Spellings = ["__builtin_malloc"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(size_t)"; +} + +def BuiltinMemcpyInline : Builtin { + let Spellings = ["__builtin_memcpy_inline"]; + let Attributes = [NoThrow]; + let Prototype = "void(void*, void const*, _Constant size_t)"; +} + +def BuiltinMempcpy : Builtin { + let Spellings = ["__builtin_mempcpy"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(void*, void const*, size_t)"; +} + +def BuiltinMemsetInline : Builtin { + let Spellings = ["__builtin_memset_inline"]; + let Attributes = [NoThrow]; + let Prototype = "void(void*, int, _Constant size_t)"; +} + +def BuiltinStrcspn : Builtin { + let Spellings = ["__builtin_strcspn"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "size_t(char const*, char const*)"; +} + +def BuiltinRealloc : Builtin { + let Spellings = ["__builtin_realloc"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(void*, size_t)"; +} + +def BuiltinReturnAddress : Builtin { + let Spellings = ["__builtin_return_address"]; + let Attributes = [NoThrow]; + let Prototype = "void*(_Constant unsigned int)"; +} + +def ExtractReturnAddr : Builtin { + let Spellings = ["__builtin_extract_return_addr"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void*)"; +} + +def FrameAddress : Builtin { + let Spellings = ["__builtin_frame_address"]; + let Attributes = [NoThrow]; + let Prototype = "void*(_Constant unsigned int)"; +} + +def ClearCache : Builtin { + let Spellings = ["__builtin___clear_cache"]; + let Attributes = [NoThrow]; + let Prototype = "void(char*, char*)"; +} + +def BuiltinSetjmp : Builtin { + let Spellings = ["__builtin_setjmp"]; + let Attributes = [ReturnsTwice]; + let Prototype = "int(void**)"; +} + +def BuiltinLongjmp : Builtin { + let Spellings = ["__builtin_longjmp"]; + let Attributes = [NoReturn]; + let Prototype = "void(void**, int)"; +} + +def UnwindInit : Builtin { + let Spellings = ["__builtin_unwind_init"]; + let Prototype = "void()"; +} + +def EHReturnDataRegNo : Builtin { + let Spellings = ["__builtin_eh_return_data_regno"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "int(_Constant int)"; +} + +def ThreadPointer : Builtin { + let Spellings = ["__builtin_thread_pointer"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void*()"; +} + +def Launder : Builtin { + let Spellings = ["__builtin_launder"]; + let Attributes = [NoThrow, CustomTypeChecking, Constexpr]; + let Prototype = "void*(void*)"; +} + +def IsConstantEvaluated : LangBuiltin<"CXX_LANG"> { + let Spellings = ["__builtin_is_constant_evaluated"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool()"; +} + +// GCC exception builtins +def EHReturn : Builtin { + let Spellings = ["__builtin_eh_return"]; + let Attributes = [NoReturn]; + // FIXME: Takes intptr_t, not size_t! + let Prototype = "void(size_t, void*)"; +} + +def FrobReturnAddr : Builtin { + let Spellings = ["__builtin_frob_return_addr"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void*)"; +} + +def DWARF_CFA : Builtin { + let Spellings = ["__builtin_dwarf_cfa"]; + let Attributes = [NoThrow]; + let Prototype = "void*()"; +} + +def InitDWARFRegSizeTable : Builtin { + let Spellings = ["__builtin_init_dwarf_reg_size_table"]; + let Attributes = [NoThrow]; + let Prototype = "void(void*)"; +} + +def DWARFSpColumn : Builtin { + let Spellings = ["__builtin_dwarf_sp_column"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned int()"; +} + +def ExtendPointer : Builtin { + let Spellings = ["__builtin_extend_pointer"]; + let Attributes = [NoThrow]; + // _Unwind_Word == uint64_t + let Prototype = "unsigned long long int(void*)"; +} + +// GCC Object size checking builtins. +def ObjectSize : Builtin { + let Spellings = ["__builtin_object_size"]; + let Attributes = [NoThrow, UnevaluatedArguments, Constexpr]; + let Prototype = "size_t(void const*, int)"; +} + +def DynamicObjectSize : Builtin { // Clang only + let Spellings = ["__builtin_dynamic_object_size"]; + let Attributes = [NoThrow, UnevaluatedArguments, Constexpr]; + let Prototype = "size_t(void const*, int)"; +} + +def MemcpyChk : Builtin { + let Spellings = ["__builtin___memcpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(void*, void const*, size_t, size_t)"; +} + +def MemccpyChk : Builtin { + let Spellings = ["__builtin___memccpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(void*, void const*, int, size_t, size_t)"; +} + +def MemmoveChk : Builtin { + let Spellings = ["__builtin___memmove_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(void*, void const*, size_t, size_t)"; +} + +def MempcpyChk : Builtin { + let Spellings = ["__builtin___mempcpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(void*, void const*, size_t, size_t)"; +} + +def MemsetChk : Builtin { + let Spellings = ["__builtin___memset_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(void*, int, size_t, size_t)"; +} + +def StpcpyChk : Builtin { + let Spellings = ["__builtin___stpcpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "char*(char*, char const*, size_t)"; +} + +def StrcatChk : Builtin { + let Spellings = ["__builtin___strcat_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "char*(char*, char const*, size_t)"; +} + +def StrcpyChk : Builtin { + let Spellings = ["__builtin___strcpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "char*(char*, char const*, size_t)"; +} + +def StrlcatChk : Builtin { + let Spellings = ["__builtin___strlcat_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "size_t(char*, char const*, size_t, size_t)"; +} + +def StrlcpyChk : Builtin { + let Spellings = ["__builtin___strlcpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "size_t(char*, char const*, size_t, size_t)"; +} + +def StrncatChk : Builtin { + let Spellings = ["__builtin___strncat_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "char*(char*, char const*, size_t, size_t)"; +} + +def StrncpyChk : Builtin { + let Spellings = ["__builtin___strncpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "char*(char*, char const*, size_t, size_t)"; +} + +def StpncpyChk : Builtin { + let Spellings = ["__builtin___stpncpy_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "char*(char*, char const*, size_t, size_t)"; +} + +def SNPrintfChk : Builtin { + let Spellings = ["__builtin___snprintf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, PrintfFormat<4>]; + let Prototype = "int(char* restrict, size_t, int, size_t, char const* restrict, ...)"; +} + +def SPrintfChk : Builtin { + let Spellings = ["__builtin___sprintf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, PrintfFormat<3>]; + let Prototype = "int(char* restrict, int, size_t, char const* restrict, ...)"; +} + +def VSNPrintfChk : Builtin { + let Spellings = ["__builtin___vsnprintf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, VPrintfFormat<4>]; + let Prototype = "int(char* restrict, size_t, int, size_t, char const* restrict, __builtin_va_list)"; +} + +def VSPrintfChk : Builtin { + let Spellings = ["__builtin___vsprintf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, VPrintfFormat<3>]; + let Prototype = "int(char* restrict, int, size_t, char const* restrict, __builtin_va_list)"; +} + +def FPrintfChk : Builtin { + let Spellings = ["__builtin___fprintf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, PrintfFormat<2>]; + let Prototype = "int(FILE* restrict, int, char const* restrict, ...)"; +} + +def PrintfChk : Builtin { + let Spellings = ["__builtin___printf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, PrintfFormat<1>]; + let Prototype = "int(int, char const* restrict, ...)"; +} + +def VFPrintfChk : Builtin { + let Spellings = ["__builtin___vfprintf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, VPrintfFormat<2>]; + let Prototype = "int(FILE* restrict, int, char const* restrict, __builtin_va_list)"; +} + +def VPrintfChk : Builtin { + let Spellings = ["__builtin___vprintf_chk"]; + let Attributes = [FunctionWithBuiltinPrefix, VPrintfFormat<1>]; + let Prototype = "int(int, char const* restrict, __builtin_va_list)"; +} + +def Unpredictable : Builtin { + let Spellings = ["__builtin_unpredictable"]; + let Attributes = [NoThrow, Const]; + let Prototype = "long int(long int)"; +} + +def Expect : Builtin { + let Spellings = ["__builtin_expect"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "long int(long int, long int)"; +} + +def ExpectWithProbability : Builtin { + let Spellings = ["__builtin_expect_with_probability"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "long int(long int, long int, double)"; +} + +def Prefetch : Builtin { + let Spellings = ["__builtin_prefetch"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(void const*, ...)"; +} + +def ReadCycleCounter : Builtin { + let Spellings = ["__builtin_readcyclecounter"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned long long int()"; +} + +def ReadSteadyCounter : Builtin { + let Spellings = ["__builtin_readsteadycounter"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned long long int()"; +} + +def Trap : Builtin { + let Spellings = ["__builtin_trap"]; + let Attributes = [NoThrow, NoReturn]; + let Prototype = "void()"; +} + +def VerboseTrap : Builtin { + let Spellings = ["__builtin_verbose_trap"]; + let Attributes = [NoThrow, NoReturn]; + let Prototype = "void(char const*, char const*)"; +} + +def Debugtrap : Builtin { + let Spellings = ["__builtin_debugtrap"]; + let Attributes = [NoThrow]; + let Prototype = "void()"; +} + +def Unreachable : Builtin { + let Spellings = ["__builtin_unreachable"]; + let Attributes = [NoThrow, NoReturn]; + let Prototype = "void()"; +} + +def AllowRuntimeCheck : Builtin { + let Spellings = ["__builtin_allow_runtime_check"]; + let Attributes = [NoThrow, Pure, Const]; + let Prototype = "bool(char const*)"; +} + +def ShuffleVector : Builtin { + let Spellings = ["__builtin_shufflevector"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ConvertVector : Builtin { + let Spellings = ["__builtin_convertvector"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AllocaUninitialized : Builtin { + let Spellings = ["__builtin_alloca_uninitialized"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(size_t)"; +} + +def AllocaWithAlign : Builtin { + let Spellings = ["__builtin_alloca_with_align"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(size_t, _Constant size_t)"; +} + +def AllocaWithAlignUninitialized : Builtin { + let Spellings = ["__builtin_alloca_with_align_uninitialized"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow]; + let Prototype = "void*(size_t, _Constant size_t)"; +} + +def CallWithStaticChain : Builtin { + let Spellings = ["__builtin_call_with_static_chain"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def NondetermenisticValue : Builtin { + let Spellings = ["__builtin_nondeterministic_value"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseAbs : Builtin { + let Spellings = ["__builtin_elementwise_abs"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseACos : Builtin { + let Spellings = ["__builtin_elementwise_acos"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseASin : Builtin { + let Spellings = ["__builtin_elementwise_asin"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseATan : Builtin { + let Spellings = ["__builtin_elementwise_atan"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseBitreverse : Builtin { + let Spellings = ["__builtin_elementwise_bitreverse"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseMax : Builtin { + let Spellings = ["__builtin_elementwise_max"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseMin : Builtin { + let Spellings = ["__builtin_elementwise_min"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseCeil : Builtin { + let Spellings = ["__builtin_elementwise_ceil"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseCos : Builtin { + let Spellings = ["__builtin_elementwise_cos"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseCosh : Builtin { + let Spellings = ["__builtin_elementwise_cosh"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseExp : Builtin { + let Spellings = ["__builtin_elementwise_exp"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseExp2 : Builtin { + let Spellings = ["__builtin_elementwise_exp2"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseFloor : Builtin { + let Spellings = ["__builtin_elementwise_floor"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseLog : Builtin { + let Spellings = ["__builtin_elementwise_log"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseLog2 : Builtin { + let Spellings = ["__builtin_elementwise_log2"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseLog10 : Builtin { + let Spellings = ["__builtin_elementwise_log10"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwisePow : Builtin { + let Spellings = ["__builtin_elementwise_pow"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseRoundEven : Builtin { + let Spellings = ["__builtin_elementwise_roundeven"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseRound : Builtin { + let Spellings = ["__builtin_elementwise_round"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseRint : Builtin { + let Spellings = ["__builtin_elementwise_rint"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseNearbyInt : Builtin { + let Spellings = ["__builtin_elementwise_nearbyint"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseSin : Builtin { + let Spellings = ["__builtin_elementwise_sin"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseSinh : Builtin { + let Spellings = ["__builtin_elementwise_sinh"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseSqrt : Builtin { + let Spellings = ["__builtin_elementwise_sqrt"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseTan : Builtin { + let Spellings = ["__builtin_elementwise_tan"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseTanh : Builtin { + let Spellings = ["__builtin_elementwise_tanh"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseTrunc : Builtin { + let Spellings = ["__builtin_elementwise_trunc"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseCanonicalize : Builtin { + let Spellings = ["__builtin_elementwise_canonicalize"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseCopysign : Builtin { + let Spellings = ["__builtin_elementwise_copysign"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseFma : Builtin { + let Spellings = ["__builtin_elementwise_fma"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseAddSat : Builtin { + let Spellings = ["__builtin_elementwise_add_sat"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ElementwiseSubSat : Builtin { + let Spellings = ["__builtin_elementwise_sub_sat"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ReduceMax : Builtin { + let Spellings = ["__builtin_reduce_max"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ReduceMin : Builtin { + let Spellings = ["__builtin_reduce_min"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ReduceXor : Builtin { + let Spellings = ["__builtin_reduce_xor"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ReduceOr : Builtin { + let Spellings = ["__builtin_reduce_or"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ReduceAnd : Builtin { + let Spellings = ["__builtin_reduce_and"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ReduceAdd : Builtin { + let Spellings = ["__builtin_reduce_add"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ReduceMul : Builtin { + let Spellings = ["__builtin_reduce_mul"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def MatrixTranspose : Builtin { + let Spellings = ["__builtin_matrix_transpose"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def MatrixColumnMajorLoad : Builtin { + let Spellings = ["__builtin_matrix_column_major_load"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def MatrixColumnMajorStore : Builtin { + let Spellings = ["__builtin_matrix_column_major_store"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +// "Overloaded" Atomic operator builtins. These are overloaded to support data +// types of i8, i16, i32, i64, and i128. The front-end sees calls to the +// non-suffixed version of these (which has a bogus type) and transforms them to +// the right overloaded version in Sema (plus casts). + +def SyncFetchAndAdd : Builtin { + let Spellings = ["__sync_fetch_and_add"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncFetchAndAddN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_fetch_and_add_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncFetchAndSub : Builtin { + let Spellings = ["__sync_fetch_and_sub"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncFetchAndSubN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_fetch_and_sub_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncFetchAndOr : Builtin { + let Spellings = ["__sync_fetch_and_or"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncFetchAndOrN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_fetch_and_or_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncFetchAndAnd : Builtin { + let Spellings = ["__sync_fetch_and_and"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncFetchAndAndN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_fetch_and_and_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncFetchAndXor : Builtin { + let Spellings = ["__sync_fetch_and_xor"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncFetchAndXorN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_fetch_and_xor_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncFetchAndNand : Builtin { + let Spellings = ["__sync_fetch_and_nand"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncFetchAndNandN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_fetch_and_nand_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncAddAndFetch : Builtin { + let Spellings = ["__sync_add_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncAddAndFetchN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_add_and_fetch_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncSubAndFetch : Builtin { + let Spellings = ["__sync_sub_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncSubAndFetchN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_sub_and_fetch_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncOrAndFetch : Builtin { + let Spellings = ["__sync_or_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncOrAndFetchN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_or_and_fetch_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncAndAndFetch : Builtin { + let Spellings = ["__sync_and_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncAndAndFetchN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_and_and_fetch_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncXorAndFetch : Builtin { + let Spellings = ["__sync_xor_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncXorAndFetchN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_xor_and_fetch_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncNandAndFetch : Builtin { + let Spellings = ["__sync_nand_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncNandAndFetchN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_nand_and_fetch_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncBoolCompareAndSwap : Builtin { + let Spellings = ["__sync_bool_compare_and_swap"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncBoolCompareAndSwapN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_bool_compare_and_swap_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "bool(T volatile*, T, T, ...)"; +} + +def SyncValCompareAndSwap : Builtin { + let Spellings = ["__sync_val_compare_and_swap"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SynLockValCompareAndSwapN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_val_compare_and_swap_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, T, ...)"; +} + +def SyncLockTestAndSet : Builtin { + let Spellings = ["__sync_lock_test_and_set"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SynLockLockTestAndSetN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_lock_test_and_set_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +def SyncLockRelease : Builtin { + let Spellings = ["__sync_lock_release"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncLockReleaseN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_lock_release_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void(T volatile*, ...)"; +} + +def SyncSwap : Builtin { + let Spellings = ["__sync_swap"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def SyncSwapN : Builtin, SyncBuiltinsTemplate { + let Spellings = ["__sync_swap_"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "T(T volatile*, T, ...)"; +} + +// C11 _Atomic operations for . +def C11AtomicInit : AtomicBuiltin { + let Spellings = ["__c11_atomic_init"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicLoad : AtomicBuiltin { + let Spellings = ["__c11_atomic_load"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicStore : AtomicBuiltin { + let Spellings = ["__c11_atomic_store"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicExchange : AtomicBuiltin { + let Spellings = ["__c11_atomic_exchange"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicCompareExchangeStrong : AtomicBuiltin { + let Spellings = ["__c11_atomic_compare_exchange_strong"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicCompareExchangeWeak : AtomicBuiltin { + let Spellings = ["__c11_atomic_compare_exchange_weak"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchAdd : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_add"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchSub : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_sub"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchAnd : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_and"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchOr : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_or"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchXor : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_xor"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchNand : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_nand"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchMax : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_max"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicFetchMin : AtomicBuiltin { + let Spellings = ["__c11_atomic_fetch_min"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def C11AtomicThreadFence : Builtin { + let Spellings = ["__c11_atomic_thread_fence"]; + let Attributes = [NoThrow]; + let Prototype = "void(int)"; +} + +def C11AtomicSignalFence : Builtin { + let Spellings = ["__c11_atomic_signal_fence"]; + let Attributes = [NoThrow]; + let Prototype = "void(int)"; +} + +def C11AtomicIsLockFree : Builtin { + let Spellings = ["__c11_atomic_is_lock_free"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(size_t)"; +} + +// GNU atomic builtins. +def AtomicLoad : AtomicBuiltin { + let Spellings = ["__atomic_load"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicLoadN : AtomicBuiltin { + let Spellings = ["__atomic_load_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicStore : AtomicBuiltin { + let Spellings = ["__atomic_store"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicStoreN : AtomicBuiltin { + let Spellings = ["__atomic_store_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicExchange : AtomicBuiltin { + let Spellings = ["__atomic_exchange"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicExchangeN : AtomicBuiltin { + let Spellings = ["__atomic_exchange_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicCompareExchange : AtomicBuiltin { + let Spellings = ["__atomic_compare_exchange"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicCompareExchangeN : AtomicBuiltin { + let Spellings = ["__atomic_compare_exchange_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicFetchAdd : AtomicBuiltin { + let Spellings = ["__atomic_fetch_add"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicFetchSub : AtomicBuiltin { + let Spellings = ["__atomic_fetch_sub"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicFetchAnd : AtomicBuiltin { + let Spellings = ["__atomic_fetch_and"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicFetchOr : AtomicBuiltin { + let Spellings = ["__atomic_fetch_or"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicFetchXor : AtomicBuiltin { + let Spellings = ["__atomic_fetch_xor"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicFetchNand : AtomicBuiltin { + let Spellings = ["__atomic_fetch_nand"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicAddFetch : AtomicBuiltin { + let Spellings = ["__atomic_add_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicSubFetch : AtomicBuiltin { + let Spellings = ["__atomic_sub_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicAndFetch : AtomicBuiltin { + let Spellings = ["__atomic_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicOrFetch : AtomicBuiltin { + let Spellings = ["__atomic_or_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicXorFetch : AtomicBuiltin { + let Spellings = ["__atomic_xor_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicMaxFetch : AtomicBuiltin { + let Spellings = ["__atomic_max_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicMinFetch : AtomicBuiltin { + let Spellings = ["__atomic_min_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicNandFetch : AtomicBuiltin { + let Spellings = ["__atomic_nand_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicTestAndSet : Builtin { + let Spellings = ["__atomic_test_and_set"]; + let Attributes = [NoThrow]; + let Prototype = "bool(void volatile*, int)"; +} + +def AtomicClear : Builtin { + let Spellings = ["__atomic_clear"]; + let Attributes = [NoThrow]; + let Prototype = "void(void volatile*, int)"; +} + +def AtomicThreadFence : Builtin { + let Spellings = ["__atomic_thread_fence"]; + let Attributes = [NoThrow]; + let Prototype = "void(int)"; +} + +def AtomicSignalFence : Builtin { + let Spellings = ["__atomic_signal_fence"]; + let Attributes = [NoThrow]; + let Prototype = "void(int)"; +} + +def AtomicAlwaysLockFree : Builtin { + let Spellings = ["__atomic_always_lock_free"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(size_t, void const volatile*)"; +} + +def AtomicIsLockFree : Builtin { + let Spellings = ["__atomic_is_lock_free"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(size_t, void const volatile*)"; +} + +// GNU atomic builtins with atomic scopes. +def ScopedAtomicLoad : AtomicBuiltin { + let Spellings = ["__scoped_atomic_load"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicLoadN : AtomicBuiltin { + let Spellings = ["__scoped_atomic_load_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicStore : AtomicBuiltin { + let Spellings = ["__scoped_atomic_store"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicStoreN : AtomicBuiltin { + let Spellings = ["__scoped_atomic_store_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicExchange : AtomicBuiltin { + let Spellings = ["__scoped_atomic_exchange"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicExchangeN : AtomicBuiltin { + let Spellings = ["__scoped_atomic_exchange_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicCompareExchange : AtomicBuiltin { + let Spellings = ["__scoped_atomic_compare_exchange"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicCompareExchangeN : AtomicBuiltin { + let Spellings = ["__scoped_atomic_compare_exchange_n"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchAdd : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_add"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchSub : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_sub"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchAnd : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_and"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchOr : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_or"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchXor : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_xor"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchNand : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_nand"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchMin : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_min"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicFetchMax : AtomicBuiltin { + let Spellings = ["__scoped_atomic_fetch_max"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicAddFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_add_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicSubFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_sub_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicAndFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_and_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicOrFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_or_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicXorFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_xor_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicNandFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_nand_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicMinFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_min_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def ScopedAtomicMaxFetch : AtomicBuiltin { + let Spellings = ["__scoped_atomic_max_fetch"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +// OpenCL 2.0 atomic builtins. +def OpenCLAtomicInit : AtomicBuiltin { + let Spellings = ["__opencl_atomic_init"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicLoad : AtomicBuiltin { + let Spellings = ["__opencl_atomic_load"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicStore : AtomicBuiltin { + let Spellings = ["__opencl_atomic_store"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicCompareExchangeWeak : AtomicBuiltin { + let Spellings = ["__opencl_atomic_compare_exchange_weak"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicCompareExchangeStrong : AtomicBuiltin { + let Spellings = ["__opencl_atomic_compare_exchange_strong"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicExchange : AtomicBuiltin { + let Spellings = ["__opencl_atomic_exchange"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicFetchAdd : AtomicBuiltin { + let Spellings = ["__opencl_atomic_fetch_add"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicFetchSub : AtomicBuiltin { + let Spellings = ["__opencl_atomic_fetch_sub"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicFetchAnd : AtomicBuiltin { + let Spellings = ["__opencl_atomic_fetch_and"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicFetchOr : AtomicBuiltin { + let Spellings = ["__opencl_atomic_fetch_or"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicFetchXor : AtomicBuiltin { + let Spellings = ["__opencl_atomic_fetch_xor"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicFetchMin : AtomicBuiltin { + let Spellings = ["__opencl_atomic_fetch_min"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def OpenCLAtomicFetchMax : AtomicBuiltin { + let Spellings = ["__opencl_atomic_fetch_max"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +// GCC does not support these, they are a Clang extension. +def AtomicFetchMax : AtomicBuiltin { + let Spellings = ["__atomic_fetch_max"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def AtomicFetchMin : AtomicBuiltin { + let Spellings = ["__atomic_fetch_min"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +// HIP atomic builtins. +def HipAtomicLoad : AtomicBuiltin { + let Spellings = ["__hip_atomic_load"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicStore : AtomicBuiltin { + let Spellings = ["__hip_atomic_store"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicCompareExchangeWeak : AtomicBuiltin { + let Spellings = ["__hip_atomic_compare_exchange_weak"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicCompareExchangeStrong : AtomicBuiltin { + let Spellings = ["__hip_atomic_compare_exchange_strong"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicExchange : AtomicBuiltin { + let Spellings = ["__hip_atomic_exchange"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicFetchAdd : AtomicBuiltin { + let Spellings = ["__hip_atomic_fetch_add"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicFetchSub : AtomicBuiltin { + let Spellings = ["__hip_atomic_fetch_sub"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicFetchAnd : AtomicBuiltin { + let Spellings = ["__hip_atomic_fetch_and"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicFetchOr : AtomicBuiltin { + let Spellings = ["__hip_atomic_fetch_or"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicFetchXor : AtomicBuiltin { + let Spellings = ["__hip_atomic_fetch_xor"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicFetchMin : AtomicBuiltin { + let Spellings = ["__hip_atomic_fetch_min"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def HipAtomicFetchMax : AtomicBuiltin { + let Spellings = ["__hip_atomic_fetch_max"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +// Non-overloaded atomic builtins. +def SyncSynchronize : Builtin { + let Spellings = ["__sync_synchronize"]; + let Attributes = [NoThrow]; + let Prototype = "void()"; +} + +// GCC does not support these, they are a Clang extension. +def SyncFetchAndMin : Builtin { + let Spellings = ["__sync_fetch_and_min"]; + let Attributes = [NoThrow]; + let Prototype = "int(int volatile*, int)"; +} + +def SyncFetchAndMax : Builtin { + let Spellings = ["__sync_fetch_and_max"]; + let Attributes = [NoThrow]; + let Prototype = "int(int volatile*, int)"; +} + +def SyncFetchAndUMin : Builtin { + let Spellings = ["__sync_fetch_and_umin"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned int(unsigned int volatile*, unsigned int)"; +} + +def SyncFetchAndUMax : Builtin { + let Spellings = ["__sync_fetch_and_umax"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned int(unsigned int volatile*, unsigned int)"; +} + +// ignored glibc builtin, see https://sourceware.org/bugzilla/show_bug.cgi?id=25399 +def WarnMemsetZeroLen : Builtin { + let Spellings = ["__warn_memset_zero_len"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "void()"; +} + +// Microsoft builtins. These are only active with -fms-extensions. +def Alloca : MSLangBuiltin { + let Spellings = ["_alloca"]; + let Attributes = [NoThrow]; + let Prototype = "void*(size_t)"; +} + +def MSAnnotation : MSLangBuiltin { + let Spellings = ["__annotation"]; + let Attributes = [NoThrow]; + let Prototype = "wchar_t const*(...)"; +} + +def MSAssume : MSLangBuiltin { + let Spellings = ["__assume"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "void(bool)"; +} + +def Bittest : MSLangBuiltin, MSInt32_64Template { + let Spellings = ["_bittest"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(T const*, T)"; +} + +def BittestAndComplement : MSLangBuiltin, MSInt32_64Template { + let Spellings = ["_bittestandcomplement"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(T*, T)"; +} + +def BittestAndReset : MSLangBuiltin, MSInt32_64Template { + let Spellings = ["_bittestandreset"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(T*, T)"; +} + +def BittestAndSet : MSLangBuiltin, MSInt32_64Template { + let Spellings = ["_bittestandset"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(T*, T)"; +} + +def MSByteswap : MSLibBuiltin<"stdlib.h">, + Template<["unsigned short", "msuint32_t", "unsigned long long int"], + ["_ushort", "_ulong", "_uint64"]> { + let Spellings = ["_byteswap"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; +} + +def Debugbreak : MSLangBuiltin { + let Spellings = ["__debugbreak"]; + let Attributes = [NoThrow]; + let Prototype = "void()"; +} + +def ExceptionCode : MSLangBuiltin { + let Spellings = ["__exception_code", "_exception_code"]; + let Attributes = [NoThrow]; + let Prototype = "msuint32_t()"; +} + +def ExceptionInfo : MSLangBuiltin { + let Spellings = ["__exception_info", "_exception_info"]; + let Attributes = [NoThrow]; + let Prototype = "void*()"; +} + +def AbnormalTermination : MSLangBuiltin { + let Spellings = ["__abnormal_termination", "_abnormal_termination"]; + let Attributes = [NoThrow]; + let Prototype = "int()"; +} + +def GetExceptionInfo : MSLangBuiltin { + let Spellings = ["__GetExceptionInfo"]; + let Attributes = [NoThrow, CustomTypeChecking, UnevaluatedArguments]; + let Prototype = "void*(...)"; + let Namespace = "std"; +} + +def InterlockedAnd : MSLangBuiltin, MSInt8_16_32Template { + let Spellings = ["_InterlockedAnd"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*, T)"; +} + +def InterlockedCompareExchange : MSLangBuiltin, MSInt8_16_32_64Template { + let Spellings = ["_InterlockedCompareExchange"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*, T, T)"; +} + +def InterlockedCompareExchangePointer : MSLangBuiltin { + let Spellings = ["_InterlockedCompareExchangePointer"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void* volatile*, void*, void*)"; +} + +def InterlockedCompareExchangePointer_nf : MSLangBuiltin { + let Spellings = ["_InterlockedCompareExchangePointer_nf"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void* volatile*, void*, void*)"; +} + +def InterlockedDecrement : MSLangBuiltin, MSInt16_32Template { + let Spellings = ["_InterlockedDecrement"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*)"; +} + +def InterlockedExchange : MSLangBuiltin, MSInt8_16_32Template { + let Spellings = ["_InterlockedExchange"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*, T)"; +} + +def InterlockedExchangeAdd : MSLangBuiltin, MSInt8_16_32Template { + let Spellings = ["_InterlockedExchangeAdd"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*, T)"; +} + +def InterlockedExchangePointer : MSLangBuiltin { + let Spellings = ["_InterlockedExchangePointer"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void* volatile*, void*)"; +} + +def InterlockedExchangeSub : MSLangBuiltin, MSInt8_16_32Template { + let Spellings = ["_InterlockedExchangeSub"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*, T)"; +} + +def InterlockedIncrement : MSLangBuiltin, MSInt16_32Template { + let Spellings = ["_InterlockedIncrement"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*)"; +} + +def InterlockedOr : MSLangBuiltin, MSInt8_16_32Template { + let Spellings = ["_InterlockedOr"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*, T)"; +} + +def InterlockedXor : MSLangBuiltin, MSInt8_16_32Template { + let Spellings = ["_InterlockedXor"]; + let Attributes = [NoThrow]; + let Prototype = "T(T volatile*, T)"; +} + +def InterlockedBittestAndReset : MSLangBuiltin, MSInt32_64Template { + let Spellings = ["_interlockedbittestandreset"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(T volatile*, T)"; +} + +def InterlockedBittestAndReset_acq : MSLangBuiltin { + let Spellings = ["_interlockedbittestandreset_acq"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(msint32_t volatile*, msint32_t)"; +} + +def InterlockedBittestAndReset_nf : MSLangBuiltin { + let Spellings = ["_interlockedbittestandreset_nf"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(msint32_t volatile*, msint32_t)"; +} + +def InterlockedBittestAndReset_rel : MSLangBuiltin { + let Spellings = ["_interlockedbittestandreset_rel"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(msint32_t volatile*, msint32_t)"; +} + +def InterlockedBittestAndSet : MSLangBuiltin, MSInt32_64Template { + let Spellings = ["_interlockedbittestandset"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(T volatile*, T)"; +} + +def InterlockedBittestAndSet_acq : MSLangBuiltin { + let Spellings = ["_interlockedbittestandset_acq"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(msint32_t volatile*, msint32_t)"; +} + +def InterlockedBittestAndSet_nf : MSLangBuiltin { + let Spellings = ["_interlockedbittestandset_nf"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(msint32_t volatile*, msint32_t)"; +} + +def InterlockedBittestAndSet_rel : MSLangBuiltin { + let Spellings = ["_interlockedbittestandset_rel"]; + let Attributes = [NoThrow]; + let Prototype = "unsigned char(msint32_t volatile*, msint32_t)"; +} + +def IsoVolatileLoad : MSLangBuiltin, Int8_16_32_64Template { + let Spellings = ["__iso_volatile_load"]; + let Attributes = [NoThrow]; + let Prototype = "T(T const volatile*)"; +} + +def IsoVolatileStore : MSLangBuiltin, Int8_16_32_64Template { + let Spellings = ["__iso_volatile_store"]; + let Attributes = [NoThrow]; + let Prototype = "void(T volatile*, T)"; +} + +def Noop : MSLangBuiltin { + let Spellings = ["__noop"]; + let Attributes = [NoThrow]; + let Prototype = "int(...)"; +} + +def MSCountLeadingZeroes : MSLangBuiltin, MSUInt16_32_64Template { + let Spellings = ["__lzcnt"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T(T)"; +} + +def MSPopCount : MSLangBuiltin, MSUInt16_32_64Template { + let Spellings = ["__popcnt"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "T(T)"; +} + +def MSReturnAddress : MSLangBuiltin { + let Spellings = ["_ReturnAddress"]; + let Attributes = [NoThrow]; + let Prototype = "void*()"; +} + +def Rotl8 : MSLangBuiltin { + let Spellings = ["_rotl8"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned char(unsigned char, unsigned char)"; +} + +def Rotl16 : MSLangBuiltin { + let Spellings = ["_rotl16"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned short(unsigned short, unsigned char)"; +} + +def Rotl : MSLangBuiltin { + let Spellings = ["_rotl"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned int(unsigned int, int)"; +} + +def Lrotl : MSLangBuiltin { + let Spellings = ["_lrotl"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned long int(unsigned long int, int)"; +} + +def Rotl64 : MSLangBuiltin { + let Spellings = ["_rotl64"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "uint64_t(uint64_t, int)"; +} + +def Rotr8 : MSLangBuiltin { + let Spellings = ["_rotr8"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned char(unsigned char, unsigned char)"; +} + +def Rotr16 : MSLangBuiltin { + let Spellings = ["_rotr16"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned short(unsigned short, unsigned char)"; +} + +def Rotr : MSLangBuiltin { + let Spellings = ["_rotr"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned int(unsigned int, int)"; +} + +def Lrotr : MSLangBuiltin { + let Spellings = ["_lrotr"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "unsigned long int(unsigned long int, int)"; +} + +def Rotr64 : MSLangBuiltin { + let Spellings = ["_rotr64"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "uint64_t(uint64_t, int)"; +} + +def MSva_start : MSLangBuiltin { + let Spellings = ["__va_start"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(char**, ...)"; +} + +def FastFail : MSLangBuiltin { + let Spellings = ["__fastfail"]; + let Attributes = [NoThrow, NoReturn]; + let Prototype = "void(unsigned int)"; +} + +// Microsoft library builtins. +def SetJmpEx : MSLibBuiltin<"setjmpex.h"> { + let Spellings = ["_setjmpex"]; + let Attributes = [IgnoreSignature, ReturnsTwice]; + let Prototype = "int(jmp_buf)"; +} + +// C99 library functions +// C99 stdarg.h +def VaStart : LibBuiltin<"stdarg.h"> { + let Spellings = ["va_start"]; + let Attributes = [NoThrow]; + let Prototype = "void(__builtin_va_list_ref, ...)"; +} + +def VaEnd : LibBuiltin<"stdarg.h"> { + let Spellings = ["va_end"]; + let Attributes = [NoThrow]; + let Prototype = "void(__builtin_va_list_ref)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VaCopy : LibBuiltin<"stdarg.h"> { + let Spellings = ["va_copy"]; + let Attributes = [NoThrow]; + let Prototype = "void(__builtin_va_list_ref, __builtin_va_list_ref)"; + let AddBuiltinPrefixedAlias = 1; +} + +// C99 stdlib.h +def Abort : LibBuiltin<"stdlib.h"> { + let Spellings = ["abort"]; + let Attributes = [NoThrow, NoReturn]; + let Prototype = "void()"; + let AddBuiltinPrefixedAlias = 1; +} + +def Abs : IntMathTemplate, LibBuiltin<"stdlib.h"> { + let Spellings = ["abs"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Calloc : LibBuiltin<"stdlib.h"> { + let Spellings = ["calloc"]; + let Prototype = "void*(size_t, size_t)"; +} + +def Exit : LibBuiltin<"stdlib.h"> { + let Spellings = ["exit", "_Exit"]; + let Attributes = [NoReturn]; + let Prototype = "void(int)"; +} + +def Malloc : LibBuiltin<"stdlib.h"> { + let Spellings = ["malloc"]; + let Prototype = "void*(size_t)"; +} + +def Realloc : LibBuiltin<"stdlib.h"> { + let Spellings = ["realloc"]; + let Prototype = "void*(void*, size_t)"; +} + +def Free : LibBuiltin<"stdlib.h"> { + let Spellings = ["free"]; + let Prototype = "void(void*)"; +} + +def StrToD : LibBuiltin<"stdlib.h"> { + let Spellings = ["strtod"]; + let Prototype = "double(char const*, char**)"; +} + +def StrToF : LibBuiltin<"stdlib.h"> { + let Spellings = ["strtof"]; + let Prototype = "float(char const*, char**)"; +} + +def StrToLd : LibBuiltin<"stdlib.h"> { + let Spellings = ["strtold"]; + let Prototype = "long double(char const*, char**)"; +} + +def StrToL : LibBuiltin<"stdlib.h"> { + let Spellings = ["strtol"]; + let Prototype = "long int(char const*, char**, int)"; +} + +def StrToLL : LibBuiltin<"stdlib.h"> { + let Spellings = ["strtoll"]; + let Prototype = "long long int(char const*, char**, int)"; +} + +def StrToUL : LibBuiltin<"stdlib.h"> { + let Spellings = ["strtoul"]; + let Prototype = "unsigned long int(char const*, char**, int)"; +} + +def StrToULL : LibBuiltin<"stdlib.h"> { + let Spellings = ["strtoull"]; + let Prototype = "unsigned long long int(char const*, char**, int)"; +} + +// C11 stdlib.h +def AlignedAlloc : LibBuiltin<"stdlib.h"> { + let Spellings = ["aligned_alloc"]; + let Prototype = "void*(size_t, size_t)"; +} + +// C99 string.h +def MemCpy : LibBuiltin<"string.h"> { + let Spellings = ["memcpy"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "void*(void*, void const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def BuiltinMemCmp : Builtin { + let Spellings = ["__builtin_memcmp"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Constexpr]; + let Prototype = "int(void const*, void const*, size_t)"; +} + +def MemCmp : LibBuiltin<"string.h"> { + let Spellings = ["memcmp"]; + let Attributes = [Constexpr]; + let Prototype = "int(void const*, void const*, size_t)"; +} + +def MemMove : LibBuiltin<"string.h"> { + let Spellings = ["memmove"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "void*(void*, void const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrCpy : LibBuiltin<"string.h"> { + let Spellings = ["strcpy"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char*, char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrNCpy : LibBuiltin<"string.h"> { + let Spellings = ["strncpy"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char*, char const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrCmp : LibBuiltin<"string.h"> { + let Spellings = ["strcmp"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "int(char const*, char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrNCmp : LibBuiltin<"string.h"> { + let Spellings = ["strncmp"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "int(char const*, char const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrCat : LibBuiltin<"string.h"> { + let Spellings = ["strcat"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char*, char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrNCat : LibBuiltin<"string.h"> { + let Spellings = ["strncat"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char*, char const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrxFrm : LibBuiltin<"string.h"> { + let Spellings = ["strxfrm"]; + let Prototype = "size_t(char*, char const*, size_t)"; +} + +def MemChr : LibBuiltin<"string.h"> { + let Spellings = ["memchr"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "void*(void const*, int, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrChr : LibBuiltin<"string.h"> { + let Spellings = ["strchr"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "char*(char const*, int)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrcSpn : LibBuiltin<"string.h"> { + let Spellings = ["strcspn"]; + let Prototype = "size_t(char const*, char const*)"; +} + +def StrpBrk : LibBuiltin<"string.h"> { + let Spellings = ["strpbrk"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char const*, char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrrChr : LibBuiltin<"string.h"> { + let Spellings = ["strrchr"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char const*, int)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrSpn : LibBuiltin<"string.h"> { + let Spellings = ["strspn"]; + let Attributes = [NoThrow]; + let Prototype = "size_t(char const*, char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrStr : LibBuiltin<"string.h"> { + let Spellings = ["strstr"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char const*, char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrTok : LibBuiltin<"string.h"> { + let Spellings = ["strtok"]; + let Prototype = "char*(char*, char const*)"; +} + +def MemSet : LibBuiltin<"string.h"> { + let Spellings = ["memset"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void*, int, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrError : LibBuiltin<"string.h"> { + let Spellings = ["strerror"]; + let Prototype = "char*(int)"; +} + +def StrLen : LibBuiltin<"string.h"> { + let Spellings = ["strlen"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "size_t(char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +// C99 stdio.h +// FIXME: This list is incomplete. +def Printf : LibBuiltin<"stdio.h"> { + let Spellings = ["printf"]; + let Attributes = [PrintfFormat<0>]; + let Prototype = "int(char const*, ...)"; +} + +// FIXME: The builtin and library function should have the same signature. +def BuiltinPrintf : Builtin { + let Spellings = ["__builtin_printf"]; + let Attributes = [NoThrow, PrintfFormat<0>, FunctionWithBuiltinPrefix]; + let Prototype = "int(char const* restrict, ...)"; +} + +def FPrintf : LibBuiltin<"stdio.h"> { + let Spellings = ["fprintf"]; + let Attributes = [NoThrow, PrintfFormat<1>]; + let Prototype = "int(FILE* restrict, char const* restrict, ...)"; + let AddBuiltinPrefixedAlias = 1; +} + +def SnPrintf : LibBuiltin<"stdio.h"> { + let Spellings = ["snprintf"]; + let Attributes = [NoThrow, PrintfFormat<2>]; + let Prototype = "int(char* restrict, size_t, char const* restrict, ...)"; + let AddBuiltinPrefixedAlias = 1; +} + +def SPrintf : LibBuiltin<"stdio.h"> { + let Spellings = ["sprintf"]; + let Attributes = [NoThrow, PrintfFormat<1>]; + let Prototype = "int(char* restrict, char const* restrict, ...)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VPrintf : LibBuiltin<"stdio.h"> { + let Spellings = ["vprintf"]; + let Attributes = [NoThrow, VPrintfFormat<0>]; + let Prototype = "int(char const* restrict, __builtin_va_list)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VfPrintf : LibBuiltin<"stdio.h"> { + let Spellings = ["vfprintf"]; + let Attributes = [NoThrow, VPrintfFormat<1>]; + let Prototype = "int(FILE* restrict, char const* restrict, __builtin_va_list)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VsnPrintf : LibBuiltin<"stdio.h"> { + let Spellings = ["vsnprintf"]; + let Attributes = [NoThrow, VPrintfFormat<2>]; + let Prototype = "int(char* restrict, size_t, char const* restrict, __builtin_va_list)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VsPrintf : LibBuiltin<"stdio.h"> { + let Spellings = ["vsprintf"]; + let Attributes = [NoThrow, VPrintfFormat<1>]; + let Prototype = "int(char* restrict, char const* restrict, __builtin_va_list)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Scanf : LibBuiltin<"stdio.h"> { + let Spellings = ["scanf"]; + let Attributes = [ScanfFormat<0>]; + let Prototype = "int(char const* restrict, ...)"; + let AddBuiltinPrefixedAlias = 1; +} + +def FScanf : LibBuiltin<"stdio.h"> { + let Spellings = ["fscanf"]; + let Attributes = [ScanfFormat<1>]; + let Prototype = "int(FILE* restrict, char const* restrict, ...)"; + let AddBuiltinPrefixedAlias = 1; +} + +def SScanf : LibBuiltin<"stdio.h"> { + let Spellings = ["sscanf"]; + let Attributes = [ScanfFormat<1>]; + let Prototype = "int(char const* restrict, char const* restrict, ...)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VScanf : LibBuiltin<"stdio.h"> { + let Spellings = ["vscanf"]; + let Attributes = [VScanfFormat<0>]; + let Prototype = "int(char const* restrict, __builtin_va_list)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VFScanf : LibBuiltin<"stdio.h"> { + let Spellings = ["vfscanf"]; + let Attributes = [VScanfFormat<1>]; + let Prototype = "int(FILE* restrict, char const* restrict, __builtin_va_list)"; + let AddBuiltinPrefixedAlias = 1; +} + +def VSScanf : LibBuiltin<"stdio.h"> { + let Spellings = ["vsscanf"]; + let Attributes = [VScanfFormat<1>]; + let Prototype = "int(char const* restrict, char const* restrict, __builtin_va_list)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Fopen : LibBuiltin<"stdio.h"> { + let Spellings = ["fopen"]; + let Prototype = "FILE*(char const*, char const*)"; +} + +def Fread : LibBuiltin<"stdio.h"> { + let Spellings = ["fread"]; + let Prototype = "size_t(void*, size_t, size_t, FILE*)"; +} + +def Fwrite : LibBuiltin<"stdio.h"> { + let Spellings = ["fwrite"]; + let Prototype = "size_t(void const*, size_t, size_t, FILE*)"; +} + +// C99 ctype.h + +def IsAlNum : LibBuiltin<"ctype.h"> { + let Spellings = ["isalnum"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsAlpha : LibBuiltin<"ctype.h"> { + let Spellings = ["isalpha"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsBlank : LibBuiltin<"ctype.h"> { + let Spellings = ["isblank"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsCntrl : LibBuiltin<"ctype.h"> { + let Spellings = ["iscntrl"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsDigit : LibBuiltin<"ctype.h"> { + let Spellings = ["isdigit"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsGraph : LibBuiltin<"ctype.h"> { + let Spellings = ["isgraph"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsLower : LibBuiltin<"ctype.h"> { + let Spellings = ["islower"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsPrint : LibBuiltin<"ctype.h"> { + let Spellings = ["isprint"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsPunct : LibBuiltin<"ctype.h"> { + let Spellings = ["ispunct"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsSpace : LibBuiltin<"ctype.h"> { + let Spellings = ["isspace"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsUpper : LibBuiltin<"ctype.h"> { + let Spellings = ["isupper"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def IsXDigit : LibBuiltin<"ctype.h"> { + let Spellings = ["isxdigit"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def ToLower : LibBuiltin<"ctype.h"> { + let Spellings = ["tolower"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +def ToUpper : LibBuiltin<"ctype.h"> { + let Spellings = ["toupper"]; + let Attributes = [NoThrow, Pure]; + let Prototype = "int(int)"; +} + +// C99 wchar.h +// FIXME: This list is incomplete. We should cover at least the functions that +// take format strings. + +def WcsChr : LibBuiltin<"wchar.h"> { + let Spellings = ["wcschr"]; + let Attributes = [NoThrow, Pure, Constexpr]; + let Prototype = "wchar_t*(wchar_t const*, wchar_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def WcsCmp : LibBuiltin<"wchar.h"> { + let Spellings = ["wcscmp"]; + let Attributes = [NoThrow, Pure, Constexpr]; + let Prototype = "int(wchar_t const*, wchar_t const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def WcsLen : LibBuiltin<"wchar.h"> { + let Spellings = ["wcslen"]; + let Attributes = [NoThrow, Pure, Constexpr]; + let Prototype = "size_t(wchar_t const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def WcsnCmp : LibBuiltin<"wchar.h"> { + let Spellings = ["wcsncmp"]; + let Attributes = [NoThrow, Pure, Constexpr]; + let Prototype = "int(wchar_t const*, wchar_t const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def WMemChr : LibBuiltin<"wchar.h"> { + let Spellings = ["wmemchr"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "wchar_t*(wchar_t const*, wchar_t, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def WMemCmp : LibBuiltin<"wchar.h"> { + let Spellings = ["wmemcmp"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "int(wchar_t const*, wchar_t const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def WMemCpy : LibBuiltin<"wchar.h"> { + let Spellings = ["wmemcpy"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "wchar_t*(wchar_t*, wchar_t const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def WMemMove : LibBuiltin<"wchar.h"> { + let Spellings = ["wmemmove"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "wchar_t*(wchar_t*, wchar_t const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +// C99 + +// FIXME: MinGW _setjmp has an additional void* parameter. +def SetJmp : LibBuiltin<"setjmp.h"> { + let Spellings = ["setjmp", "_setjmp"]; + let Attributes = [ReturnsTwice, IgnoreSignature]; + let Prototype = "int(jmp_buf)"; + let RequiresUndef = 1; +} + +def LongJmp : LibBuiltin<"setjmp.h"> { + let Spellings = ["longjmp"]; + let Attributes = [NoReturn, IgnoreSignature]; + let Prototype = "void(jmp_buf, int)"; +} + +// Non-C library functions, active in GNU mode only. +// Functions with [[gnu::returns_twice]] attribute are still active in +// all languages, because losing this attribute would result in miscompilation +// when these functions are used in non-GNU mode. PR16138. + +def AllocA : GNULibBuiltin<"stdlib.h"> { + let Spellings = ["alloca"]; + let Attributes = [NoThrow]; + let Prototype = "void*(size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +// POSIX malloc.h + +def MemAlign : GNULibBuiltin<"malloc.h"> { + let Spellings = ["memalign"]; + let Prototype = "void*(size_t, size_t)"; +} + +// POSIX string.h + +def MemcCpy : GNULibBuiltin<"string.h"> { + let Spellings = ["memccpy"]; + let Prototype = "void*(void*, void const*, int, size_t)"; +} + +def MempCpy : GNULibBuiltin<"string.h"> { + let Spellings = ["mempcpy"]; + let Prototype = "void*(void*, void const*, size_t)"; +} + +def StpCpy : GNULibBuiltin<"string.h"> { + let Spellings = ["stpcpy"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char*, char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StpnCpy : GNULibBuiltin<"string.h"> { + let Spellings = ["stpncpy"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char*, char const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrDup : GNULibBuiltin<"string.h"> { + let Spellings = ["strdup"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char const*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def StrnDup : GNULibBuiltin<"string.h"> { + let Spellings = ["strndup"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +// POSIX strings.h + +def Index : GNULibBuiltin<"strings.h"> { + let Spellings = ["index"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char const*, int)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Rindex : GNULibBuiltin<"strings.h"> { + let Spellings = ["rindex"]; + let Attributes = [NoThrow]; + let Prototype = "char*(char const*, int)"; + let AddBuiltinPrefixedAlias = 1; +} + +def BZero : GNULibBuiltin<"strings.h"> { + let Spellings = ["bzero"]; + let Attributes = [NoThrow]; + let Prototype = "void(void*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Bcopy : GNULibBuiltin<"strings.h"> { + let Spellings = ["bcopy"]; + let Attributes = [NoThrow]; + let Prototype = "void(void const*, void*, size_t)"; + let AddBuiltinPrefixedAlias = 1; +} + +// FIXME: This should be part of BCmp. +def BuiltinBCmp : Builtin { + let Spellings = ["__builtin_bcmp"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, Constexpr]; + let Prototype = "int(void const*, void const*, size_t)"; +} + +def BCmp : GNULibBuiltin<"strings.h"> { + let Spellings = ["bcmp"]; + let Attributes = [Constexpr]; + let Prototype = "int(void const*, void const*, size_t)"; +} + +def StrCaseCmp : GNULibBuiltin<"strings.h"> { + let Spellings = ["strcasecmp"]; + let Prototype = "int(char const*, char const*)"; + let AddBuiltinPrefixedAlias = 1; + let RequiresUndef = 1; +} + +def StrnCaseCmp : GNULibBuiltin<"strings.h"> { + let Spellings = ["strncasecmp"]; + let Prototype = "int(char const*, char const*, size_t)"; + let AddBuiltinPrefixedAlias = 1; + let RequiresUndef = 1; +} + +def GNU_Exit : GNULibBuiltin<"unistd.h"> { + let Spellings = ["_exit"]; + let Attributes = [NoReturn]; + let Prototype = "void(int)"; +} + +def VFork : LibBuiltin<"unistd.h"> { + let Spellings = ["vfork"]; + let Attributes = [ReturnsTwice, IgnoreSignature]; + let Prototype = "pid_t()"; +} + +// POSIX pthread.h +// FIXME: This should be a GNULibBuiltin, but it's currently missing the prototype. + +def PthreadCreate : CustomEntry { + let Entry = "LIBBUILTIN(pthread_create, \"\", \"fC<2,3>\", PTHREAD_H, ALL_GNU_LANGUAGES)"; +} + +def SigSetJmp : LibBuiltin<"setjmp.h"> { + let Spellings = ["sigsetjmp", "__sigsetjmp"]; + let Attributes = [ReturnsTwice, IgnoreSignature]; + let Prototype = "int(sigjmp_buf, int)"; +} + +def SaveCtx : LibBuiltin<"setjmp.h"> { + let Spellings = ["savectx"]; + let Attributes = [ReturnsTwice, IgnoreSignature]; + let Prototype = "int(sigjmp_buf)"; +} + +def GetContext : LibBuiltin<"setjmp.h"> { + let Spellings = ["getcontext"]; + let Attributes = [ReturnsTwice, IgnoreSignature]; + let Prototype = "int(ucontext_t*)"; +} + +def GNU_LongJmp : GNULibBuiltin<"setjmp.h"> { + let Spellings = ["_longjmp"]; + let Attributes = [NoReturn, IgnoreSignature]; + let Prototype = "void(jmp_buf, int)"; +} + +def SigLongJmp : GNULibBuiltin<"setjmp.h"> { + let Spellings = ["siglongjmp"]; + let Attributes = [NoReturn, IgnoreSignature]; + let Prototype = "void(sigjmp_buf, int)"; +} + +// non-standard but very common + +def StrlCpy : GNULibBuiltin<"string.h"> { + let Spellings = ["strlcpy"]; + let Prototype = "size_t(char*, char const*, size_t)"; +} + +def StrlCat : GNULibBuiltin<"string.h"> { + let Spellings = ["strlcat"]; + let Prototype = "size_t(char*, char const*, size_t)"; +} + +def ObjcMsgSend : ObjCLibBuiltin<"objc_message.h"> { + let Spellings = ["objc_msgSend"]; + let Prototype = "id(id, SEL, ...)"; +} + +def ObjcMsgSendFpret : ObjCLibBuiltin<"objc_message.h"> { + let Spellings = ["objc_msgSend_fpret"]; + let Prototype = "long double(id, SEL, ...)"; +} + +def ObjcMsgSendFp2ret : ObjCLibBuiltin<"objc/message.h"> { + let Spellings = ["objc_msgSend_fp2ret"]; + let Prototype = "_Complex long double(id, SEL, ...)"; +} + +def ObjcMsgSendStret : ObjCLibBuiltin<"objc/message.h"> { + let Spellings = ["objc_msgSend_stret"]; + let Prototype = "void(id, SEL, ...)"; +} + +def ObjcMsgSendSuper : ObjCLibBuiltin<"objc/message.h"> { + let Spellings = ["objc_msgSendSuper"]; + let Prototype = "id(objc_super*, SEL, ...)"; +} + +def ObjcMsgSendSuperStret : ObjCLibBuiltin<"objc/message.h"> { + let Spellings = ["objc_msgSendSuper_stret"]; + let Prototype = "void(objc_super*, SEL, ...)"; +} + +def ObjcGetClass : ObjCLibBuiltin<"objc/runtime.h"> { + let Spellings = ["objc_getClass"]; + let Prototype = "id(char const*)"; +} + +def ObjcGetMetaClass : ObjCLibBuiltin<"objc/runtime.h"> { + let Spellings = ["objc_getMetaClass"]; + let Prototype = "id(char const*)"; +} + +def ObjcEnumerationMutation : ObjCLibBuiltin<"objc/runtime.h"> { + let Spellings = ["objc_enumerationMutation"]; + let Prototype = "void(id)"; +} + +def ObjcReadWeak : ObjCLibBuiltin<"objc/objc-auto.h"> { + let Spellings = ["objc_read_weak"]; + let Prototype = "id(id*)"; +} + +def ObjcAssignWeak : ObjCLibBuiltin<"objc/objc-auto.h"> { + let Spellings = ["objc_assign_weak"]; + let Prototype = "id(id, id*)"; +} + +def ObjcAssignIvar : ObjCLibBuiltin<"objc/objc-auto.h"> { + let Spellings = ["objc_assign_ivar"]; + let Prototype = "id(id, id, ptrdiff_t)"; +} + +def ObjcAssignGlobal : ObjCLibBuiltin<"objc/objc-auto.h"> { + let Spellings = ["objc_assign_global"]; + let Prototype = "id(id, id*)"; +} + +def ObjcAssignStrongCast : ObjCLibBuiltin<"objc/objc-auto.h"> { + let Spellings = ["objc_assign_strongCast"]; + let Prototype = "id(id, id*)"; +} + +def ObjcExceptionExtract : ObjCLibBuiltin<"objc/objc_exception.h"> { + let Spellings = ["objc_exception_extract"]; + let Prototype = "id(void*)"; +} + +def ObjcExceptionTryEnter : ObjCLibBuiltin<"objc/objc_exception.h"> { + let Spellings = ["objc_exception_try_enter"]; + let Prototype = "void(void*)"; +} + +def ObjcExceptionTryExit : ObjCLibBuiltin<"objc/objc_exception.h"> { + let Spellings = ["objc_exception_try_exit"]; + let Prototype = "void(void*)"; +} + +def ObjcExceptionMatch : ObjCLibBuiltin<"objc/objc_exception.h"> { + let Spellings = ["objc_exception_match"]; + let Prototype = "int(id, id)"; +} + +def ObjcExceptionThrow : ObjCLibBuiltin<"objc/objc_exception.h"> { + let Spellings = ["objc_exception_throw"]; + let Prototype = "void(id)"; +} + +def ObjcSyncEnter : ObjCLibBuiltin<"objc_objc_sync.h"> { + let Spellings = ["objc_sync_enter"]; + let Prototype = "int(id)"; +} + +def ObjcSyncExit : ObjCLibBuiltin<"objc_objc_sync.h"> { + let Spellings = ["objc_sync_exit"]; + let Prototype = "int(id)"; +} + +def ObjcMemmoveCollectable : Builtin { + let Spellings = ["__builtin_objc_memmove_collectable"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix]; + let Prototype = "void*(void*, void const*, size_t)"; +} + +def NSLog : ObjCLibBuiltin<"foundation_nsobjcruntime.h"> { + let Spellings = ["NSLog"]; + let Attributes = [PrintfFormat<0>]; + let Prototype = "void(id, ...)"; +} + +def NSLogv : ObjCLibBuiltin<"foundation_nsobjcruntime.h"> { + let Spellings = ["NSLogv"]; + let Attributes = [VPrintfFormat<0>]; + let Prototype = "void(id, __builtin_va_list)"; +} + +def Atan2 : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["atan2"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Copysign : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["copysign"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; + let OnlyBuiltinPrefixedAliasIsConstexpr = 1; +} + +def Fabs : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["fabs"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; + let OnlyBuiltinPrefixedAliasIsConstexpr = 1; +} + +def Finite : FPMathTemplate, GNULibBuiltin<"math.h"> { + let Spellings = ["finite"]; + let Attributes = [NoThrow, Const]; + let Prototype = "int(T)"; + let RequiresUndef = 1; +} + +def OSXFinite : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["__finite"]; + let Attributes = [NoThrow, Const]; + let Prototype = "int(T)"; +} + +def Fmod : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["fmod"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Frexp : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["frexp"]; + let Attributes = [NoThrow]; + let Prototype = "T(T, int*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Ldexp : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["ldexp"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, int)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Modf : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["modf"]; + let Attributes = [NoThrow]; + let Prototype = "T(T, T*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Nan : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["nan"]; + let Attributes = [Pure, NoThrow]; + let Prototype = "T(char const*)"; + let AddBuiltinPrefixedAlias = 1; + let OnlyBuiltinPrefixedAliasIsConstexpr = 1; +} + +def Pow : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["pow"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Acos : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["acos"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Acosh : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["acosh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Asin : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["asin"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Asinh : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["asinh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Atan : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["atan"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Atanh : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["atanh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cbrt : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["cbrt"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Ceil : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["ceil"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cos : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["cos"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cosh : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["cosh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Erf : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["erf"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Erfc : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["erfc"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Exp : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["exp"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Exp2 : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["exp2"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +// FIXME: Why is there no builtin without the prefix? +def Exp10 : FPMathTemplate, Builtin { + let Spellings = ["__builtin_exp10"]; + let Attributes = [FunctionWithBuiltinPrefix, NoThrow, + ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def Expm1 : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["expm1"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Fdim : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["fdim"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Floor : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["floor"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Fma : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["fma"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Fmax : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["fmax"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; + let OnlyBuiltinPrefixedAliasIsConstexpr = 1; +} + +def Fmin : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["fmin"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; + let OnlyBuiltinPrefixedAliasIsConstexpr = 1; +} + +def Hypot : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["hypot"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Ilogb : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["ilogb"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "int(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Lgamma : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["lgamma"]; + let Attributes = [NoThrow]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Llrint : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["llrint"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long long int(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Llround : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["llround"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long long int(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Log : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["log"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Log10 : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["log10"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Log1p : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["log1p"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Log2 : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["log2"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Logb : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["logb"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Lrint : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["lrint"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long int(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Lround : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["lround"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "long int(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Nearbyint : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["nearbyint"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Nextafter : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["nextafter"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Nexttoward : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["nexttoward"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, long double)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Remainder : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["remainder"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Remquo : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["remquo"]; + let Attributes = [NoThrow]; + let Prototype = "T(T, T, int*)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Rint : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["rint"]; + let Attributes = [NoThrow, ConstIgnoringExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Round : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["round"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def RoundEven : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["roundeven"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Scalbln : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["scalbln"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, long int)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Scalbn : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["scalbn"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T, int)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Sin : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["sin"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Sinh : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["sinh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Sqrt : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["sqrt"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Tan : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["tan"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Tanh : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["tanh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Tgamma : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["tgamma"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Trunc : FPMathTemplate, LibBuiltin<"math.h"> { + let Spellings = ["trunc"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cabs : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["cabs"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cacos : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["cacos"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cacosh : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["cacosh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Carg : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["carg"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Casin : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["casin"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Casinh : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["casinh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Catan : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["catan"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Catanh : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["catanh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Ccos : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["ccos"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Ccosh : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["ccosh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cexp : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["cexp"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cimag : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["cimag"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Conj : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["conj"]; + let Attributes = [NoThrow, Const]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Clog : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["clog"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cproj : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["cproj"]; + let Attributes = [NoThrow, Const]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Cpow : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["cpow"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T, _Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Creal : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["creal"]; + let Attributes = [NoThrow, Const]; + let Prototype = "T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Csin : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["csin"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Csinh : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["csinh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Csqrt : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["csqrt"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Ctan : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["ctan"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +def Ctanh : FPMathTemplate, LibBuiltin<"complex.h"> { + let Spellings = ["ctanh"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "_Complex T(_Complex T)"; + let AddBuiltinPrefixedAlias = 1; +} + +// __sinpi and friends are OS X specific library functions, but otherwise much +// like the standard (non-complex) sin (etc). +def Sinpi : LibBuiltin<"math.h">, FloatDoubleTemplate { + let Spellings = ["__sinpi"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def Cospi : LibBuiltin<"math.h">, FloatDoubleTemplate { + let Spellings = ["__cospi"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +def Tanpi : LibBuiltin<"math.h">, FloatDoubleTemplate { + let Spellings = ["__tanpi"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +// Similarly, __exp10 is OS X only +def OSXExp10 : LibBuiltin<"math.h">, FloatDoubleTemplate { + let Spellings = ["__exp10"]; + let Attributes = [NoThrow, ConstIgnoringErrnoAndExceptions]; + let Prototype = "T(T)"; +} + +// Blocks runtime Builtin math library functions. +def BlockObjectAssign : LibBuiltin<"blocks.h"> { + let Spellings = ["_Block_object_assign"]; + let Prototype = "void(void*, void const*, int const)"; +} + +def BlockObjectDispose : LibBuiltin<"blocks.h"> { + let Spellings = ["_Block_object_dispose"]; + let Prototype = "void(void const*, int const)"; +} +// FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock. + +def __Addressof : LangBuiltin<"CXX_LANG"> { + let Spellings = ["__addressof"]; + let Attributes = [FunctionWithoutBuiltinPrefix, NoThrow, Const, + IgnoreSignature, Constexpr]; + let Prototype = "void*(void&)"; + let Namespace = "std"; +} + +def Addressof : CxxLibBuiltin<"memory"> { + let Spellings = ["addressof"]; + let Attributes = [NoThrow, Const, IgnoreSignature, RequireDeclaration, + Constexpr]; + let Prototype = "void*(void&)"; + let Namespace = "std"; +} + +def AsConst : CxxLibBuiltin<"utility"> { + let Spellings = ["as_const"]; + let Attributes = [NoThrow, Const, IgnoreSignature, RequireDeclaration, + Constexpr]; + let Prototype = "void&(void&)"; + let Namespace = "std"; +} + +def Forward : CxxLibBuiltin<"utility"> { + let Spellings = ["forward"]; + let Attributes = [NoThrow, Const, IgnoreSignature, RequireDeclaration, + Constexpr]; + let Prototype = "void&(void&)"; + let Namespace = "std"; +} + +def ForwardLike : CxxLibBuiltin<"utility"> { + let Spellings = ["forward_like"]; + let Attributes = [NoThrow, Const, IgnoreSignature, RequireDeclaration, + Constexpr]; + let Prototype = "void&(void&)"; + let Namespace = "std"; +} + +def Move : CxxLibBuiltin<"utility"> { + let Spellings = ["move"]; + let Attributes = [NoThrow, Const, IgnoreSignature, RequireDeclaration, + Constexpr]; + let Prototype = "void&(void&)"; + let Namespace = "std"; +} + +def MoveIfNsoexcept : CxxLibBuiltin<"utility"> { + let Spellings = ["move_if_noexcept"]; + let Attributes = [NoThrow, Const, IgnoreSignature, RequireDeclaration, + Constexpr]; + let Prototype = "void&(void&)"; + let Namespace = "std"; +} + +def Annotation : Builtin { + let Spellings = ["__builtin_annotation"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(...)"; +} + +// Invariants +def Assume : Builtin { + let Spellings = ["__builtin_assume"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "void(bool)"; +} + +def AssumeSeparateStorage : Builtin { + let Spellings = ["__builtin_assume_separate_storage"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "void(void const volatile*, void const volatile*)"; +} + +// Multiprecision Arithmetic Builtins. + +class MPATemplate : Template< + ["unsigned char", "unsigned short", "unsigned int", + "unsigned long int", "unsigned long long int"], + ["b", "s", "", + "l", "ll"]>; + +def Addc : Builtin, MPATemplate { + let Spellings = ["__builtin_addc"]; + let Attributes = [NoThrow, Constexpr]; + // FIXME: Why are these argumentes marked const? + let Prototype = "T(T const, T const, T const, T*)"; +} + +def Subc : Builtin, MPATemplate { + let Spellings = ["__builtin_subc"]; + let Attributes = [NoThrow, Constexpr]; + // FIXME: Why are these argumentes marked const? + let Prototype = "T(T const, T const, T const, T*)"; +} + +// Checked Arithmetic Builtins for Security. +def AddOverflow : Builtin { + let Spellings = ["__builtin_add_overflow"]; + let Attributes = [NoThrow, CustomTypeChecking, Constexpr]; + let Prototype = "bool(...)"; +} + +def SubOverflow : Builtin { + let Spellings = ["__builtin_sub_overflow"]; + let Attributes = [NoThrow, CustomTypeChecking, Constexpr]; + let Prototype = "bool(...)"; +} + +def MulOverflow : Builtin { + let Spellings = ["__builtin_mul_overflow"]; + let Attributes = [NoThrow, CustomTypeChecking, Constexpr]; + let Prototype = "bool(...)"; +} + +class UOverflowTemplate : + Template<["unsigned int", "unsigned long int", "unsigned long long int"], + ["_overflow", "l_overflow", "ll_overflow"]>; + +def UaddOverflow : Builtin, UOverflowTemplate { + let Spellings = ["__builtin_uadd"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(T const, T const, T*)"; +} + +def UsubOverflow : Builtin, UOverflowTemplate { + let Spellings = ["__builtin_usub"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(T const, T const, T*)"; +} + +def UmulOverflow : Builtin, UOverflowTemplate { + let Spellings = ["__builtin_umul"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(T const, T const, T*)"; +} + +class SOverflowTemplate : + Template<["int", "long int", "long long int"], + ["_overflow", "l_overflow", "ll_overflow"]>; + +def SaddOverflow : Builtin, SOverflowTemplate { + let Spellings = ["__builtin_sadd"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(T const, T const, T*)"; +} + +def SsubOverflow : Builtin, SOverflowTemplate { + let Spellings = ["__builtin_ssub"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(T const, T const, T*)"; +} + +def SmulOverflow : Builtin, SOverflowTemplate { + let Spellings = ["__builtin_smul"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "bool(T const, T const, T*)"; +} + +// Clang builtins (not available in GCC). +def BuiltinAddressof : Builtin { + let Spellings = ["__builtin_addressof"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "void*(void&)"; +} + +def BuiltinFunctionStart : Builtin { + let Spellings = ["__builtin_function_start"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "void*(void&)"; +} + +def BuiltinOperatorNew : Builtin { + let Spellings = ["__builtin_operator_new"]; + let Attributes = [Const, CustomTypeChecking, Constexpr]; + let Prototype = "void*(size_t)"; +} + +def BuiltinOperatorDelete : Builtin { + let Spellings = ["__builtin_operator_delete"]; + let Attributes = [NoThrow, CustomTypeChecking, Constexpr]; + let Prototype = "void(void*)"; +} + +def BuiltinCharMemchr : Builtin { + let Spellings = ["__builtin_char_memchr"]; + let Attributes = [NoThrow, Constexpr]; + let Prototype = "char*(char const*, int, size_t)"; +} + +def BuiltinDumpStruct : Builtin { + let Spellings = ["__builtin_dump_struct"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def BuiltinPreserveAccessIndex : Builtin { + let Spellings = ["__builtin_preserve_access_index"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def IsAligned : Builtin { + let Spellings = ["__builtin_is_aligned"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "bool(void const*, size_t)"; +} + +def AlignUp : Builtin { + let Spellings = ["__builtin_align_up"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "void*(void const*, size_t)"; +} + +def AlignDown : Builtin { + let Spellings = ["__builtin_align_down"]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; + let Prototype = "void*(void const*, size_t)"; +} + +// Safestack builtins. +def GetUnsafeStackStart : Builtin { + let Spellings = ["__builtin___get_unsafe_stack_start"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix]; + let Prototype = "void*()"; +} + +def GetUnsafeStackBottom : Builtin { + let Spellings = ["__builtin___get_unsafe_stack_bottom"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix]; + let Prototype = "void*()"; +} + +def GetUnsafeStackTop : Builtin { + let Spellings = ["__builtin___get_unsafe_stack_top"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix]; + let Prototype = "void*()"; +} + +def GetUnsafeStackPtr : Builtin { + let Spellings = ["__builtin___get_unsafe_stack_ptr"]; + let Attributes = [NoThrow, FunctionWithBuiltinPrefix]; + let Prototype = "void*()"; +} + +// Nontemporal loads/stores builtins. +def NontemporalStore : Builtin { + let Spellings = ["__builtin_nontemporal_store"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +def NontemporalLoad : Builtin { + let Spellings = ["__builtin_nontemporal_load"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "void(...)"; +} + +// Coroutine intrinsics +def CoroResume : CoroLangBuiltin { + let Spellings = ["__builtin_coro_resume"]; + let Prototype = "void(void*)"; +} + +def CoroDestroy : CoroLangBuiltin { + let Spellings = ["__builtin_coro_destroy"]; + let Prototype = "void(void*)"; +} + +def CoroDone : CoroLangBuiltin { + let Spellings = ["__builtin_coro_done"]; + let Attributes = [NoThrow]; + let Prototype = "bool(void*)"; +} + +def CoroPromise : CoroLangBuiltin { + let Spellings = ["__builtin_coro_promise"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void*, _Constant int, _Constant bool)"; +} + +def CoroSize : CoroLangBuiltin { + let Spellings = ["__builtin_coro_size"]; + let Attributes = [NoThrow]; + let Prototype = "size_t()"; +} + +def CoroAlign : CoroLangBuiltin { + let Spellings = ["__builtin_coro_align"]; + let Attributes = [NoThrow]; + let Prototype = "size_t()"; +} + +def CoroFrame : CoroLangBuiltin { + let Spellings = ["__builtin_coro_frame"]; + let Attributes = [NoThrow]; + let Prototype = "void*()"; +} + +def CoroNoop : CoroLangBuiltin { + let Spellings = ["__builtin_coro_noop"]; + let Attributes = [NoThrow]; + let Prototype = "void*()"; +} + +def CoroFree : CoroLangBuiltin { + let Spellings = ["__builtin_coro_free"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void*)"; +} + +def CoroId : CoroLangBuiltin { + let Spellings = ["__builtin_coro_id"]; + let Attributes = [NoThrow]; + let Prototype = "void*(_Constant int, void*, void*, void*)"; +} + +def CoroAlloc : CoroLangBuiltin { + let Spellings = ["__builtin_coro_alloc"]; + let Attributes = [NoThrow]; + let Prototype = "bool()"; +} + +def CoroBegin : CoroLangBuiltin { + let Spellings = ["__builtin_coro_begin"]; + let Attributes = [NoThrow]; + let Prototype = "void*(void*)"; +} + +def CoroEnd : CoroLangBuiltin { + let Spellings = ["__builtin_coro_end"]; + let Attributes = [NoThrow]; + let Prototype = "bool(void*, _Constant bool)"; +} + +def CoroSuspend : CoroLangBuiltin { + let Spellings = ["__builtin_coro_suspend"]; + let Attributes = [NoThrow]; + let Prototype = "char(_Constant bool)"; +} + +// Pointer authentication builtins. +def PtrauthStrip : Builtin { + let Spellings = ["__builtin_ptrauth_strip"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "void*(void*,int)"; +} + +def PtrauthBlendDiscriminator : Builtin { + let Spellings = ["__builtin_ptrauth_blend_discriminator"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "size_t(void*,int)"; +} + +def PtrauthSignUnauthenticated : Builtin { + let Spellings = ["__builtin_ptrauth_sign_unauthenticated"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "void*(void*,int,void*)"; +} + +def PtrauthSignConstant : Builtin { + let Spellings = ["__builtin_ptrauth_sign_constant"]; + let Attributes = [CustomTypeChecking, NoThrow, Const, Constexpr]; + let Prototype = "void*(void*,int,void*)"; +} + +def PtrauthSignGenericData : Builtin { + let Spellings = ["__builtin_ptrauth_sign_generic_data"]; + let Attributes = [CustomTypeChecking, NoThrow, Const]; + let Prototype = "size_t(void*,void*)"; +} + +def PtrauthAuthAndResign : Builtin { + let Spellings = ["__builtin_ptrauth_auth_and_resign"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void*(void*,int,void*,int,void*)"; +} + +def PtrauthAuth : Builtin { + let Spellings = ["__builtin_ptrauth_auth"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void*(void*,int,void*)"; +} + +def PtrauthStringDiscriminator : Builtin { + let Spellings = ["__builtin_ptrauth_string_discriminator"]; + let Attributes = [NoThrow, Const, Constexpr]; + let Prototype = "size_t(char const*)"; +} + +// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. +// We need the generic prototype, since the packet type could be anything. +def ReadPipe : OCLPipeLangBuiltin { + let Spellings = ["read_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def WritePipe : OCLPipeLangBuiltin { + let Spellings = ["write_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def ReserveReadPipe : OCLPipeLangBuiltin { + let Spellings = ["reserve_read_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def ReserveWritePipe : OCLPipeLangBuiltin { + let Spellings = ["reserve_write_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def CommitWritePipe : OCLPipeLangBuiltin { + let Spellings = ["commit_write_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void(...)"; +} + +def CommitReadPipe : OCLPipeLangBuiltin { + let Spellings = ["commit_read_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void(...)"; +} + +def SubGroupReserveReadPipe : OCLPipeLangBuiltin { + let Spellings = ["sub_group_reserve_read_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def SubGroupReserveWritePipe : OCLPipeLangBuiltin { + let Spellings = ["sub_group_reserve_write_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def SubGroupCommitWritePipe : OCLPipeLangBuiltin { + let Spellings = ["sub_group_commit_write_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void(...)"; +} + +def SubGroupCommitReadPipe : OCLPipeLangBuiltin { + let Spellings = ["sub_group_commit_read_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void(...)"; +} + +def WorkGroupReserveReadPipe : OCLPipeLangBuiltin { + let Spellings = ["work_group_reserve_read_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def WorkGroupReserveWritePipe : OCLPipeLangBuiltin { + let Spellings = ["work_group_reserve_write_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def WorkGroupCommitWritePipe : OCLPipeLangBuiltin { + let Spellings = ["work_group_commit_write_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void(...)"; +} + +def WorkGroupCommitReadPipe : OCLPipeLangBuiltin { + let Spellings = ["work_group_commit_read_pipe"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void(...)"; +} + +def GetPipeNumPackets : OCLPipeLangBuiltin { + let Spellings = ["get_pipe_num_packets"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "unsigned int(...)"; +} + +def GetPipeMaxPackets : OCLPipeLangBuiltin { + let Spellings = ["get_pipe_max_packets"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "unsigned int(...)"; +} + +// OpenCL v2.0 s6.13.17 - Enqueue kernel functions. +// Custom builtin check allows to perform special check of passed block arguments. +def EnqueueKernel : OCL_DSELangBuiltin { + let Spellings = ["enqueue_kernel"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "int(...)"; +} + +def GetKernelWorkGroupSize : OCL_DSELangBuiltin { + let Spellings = ["get_kernel_work_group_size"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "unsigned int(...)"; +} + +def GetKernelPreferredWorkGroupSizeMultiple : OCL_DSELangBuiltin { + let Spellings = ["get_kernel_preferred_work_group_size_multiple"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "unsigned int(...)"; +} + +def GetKernelMaxSubGroupSizeForNDRange : OCL_DSELangBuiltin { + let Spellings = ["get_kernel_max_sub_group_size_for_ndrange"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "unsigned int(...)"; +} + +def GetKernelSubGroupCountForNDRange : OCL_DSELangBuiltin { + let Spellings = ["get_kernel_sub_group_count_for_ndrange"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "unsigned int(...)"; +} + +// OpenCL v2.0 s6.13.9 - Address space qualifier functions. +// FIXME: Pointer parameters of OpenCL builtins should have their address space +// requirement defined. +def ToGlobal : OCL_GASLangBuiltin { + let Spellings = ["to_global"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void*(void*)"; +} + +def ToLocal : OCL_GASLangBuiltin { + let Spellings = ["to_local"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void*(void*)"; +} + +def ToPrivate : OCL_GASLangBuiltin { + let Spellings = ["to_private"]; + let Attributes = [CustomTypeChecking, NoThrow]; + let Prototype = "void*(void*)"; +} + +// OpenCL half load/store builtin. +def StoreHalf : OCLLangBuiltin, FloatDoubleTemplate { + let Spellings = ["__builtin_store_half"]; + let Attributes = [NoThrow]; + let Prototype = "void(T, __fp16*)"; +} + +def LoadHalf : OCLLangBuiltin, FloatDoubleTemplate { + let Spellings = ["__builtin_load_half"]; + // FIXME: Is this actually Const? This looks like it shoud be Pure. + let Attributes = [NoThrow, Const]; + let Prototype = "T(__fp16 const*)"; +} + +// Builtins for os_log/os_trace. +def OSLogFormatBufferSize : Builtin { + let Spellings = ["__builtin_os_log_format_buffer_size"]; + let Attributes = [PrintfFormat<0>, NoThrow, UnevaluatedArguments, + CustomTypeChecking, Constexpr]; + let Prototype = "size_t(char const*, ...)"; +} + +def OSLogFormat : Builtin { + let Spellings = ["__builtin_os_log_format"]; + // FIXME: The printf attribute looks suspiciously like it should be argument #1. + let Attributes = [PrintfFormat<0>, NoThrow, CustomTypeChecking]; + let Prototype = "void*(void*, char const*, ...)"; +} + +// CUDA/HIP +def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> { + let Spellings = ["__builtin_get_device_side_mangled_name"]; + let Attributes = [NoThrow, Const, IgnoreSignature]; + let Prototype = "char const*(...)"; +} + +// HLSL +def HLSLAll : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_all"]; + let Attributes = [NoThrow, Const]; + let Prototype = "bool(...)"; +} + +def HLSLAny : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_any"]; + let Attributes = [NoThrow, Const]; + let Prototype = "bool(...)"; +} + +def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_active_count_bits"]; + let Attributes = [NoThrow, Const]; + let Prototype = "unsigned int(bool)"; +} + +def HLSLWaveGetLaneIndex : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_get_lane_index"]; + let Attributes = [NoThrow, Const]; + let Prototype = "unsigned int()"; +} + +def HLSLClamp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_clamp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_create_handle"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void*(unsigned char)"; +} + +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +def HLSLFrac : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_frac"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +def HLSLIsinf : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_isinf"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +def HLSLLerp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_lerp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +def HLSLMad : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_mad"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +def HLSLRcp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_rcp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_rsqrt"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + +// Builtins for XRay. +def XRayCustomEvent : Builtin { + let Spellings = ["__xray_customevent"]; + let Prototype = "void(char const*, size_t)"; +} + +def XRayTypedEvent : Builtin { + let Spellings = ["__xray_typedevent"]; + let Prototype = "void(size_t, char const*, size_t)"; +} + +// Win64-compatible va_list functions. +def MSVaStart : Builtin { + let Spellings = ["__builtin_ms_va_start"]; + let Attributes = [NoThrow, CustomTypeChecking]; + let Prototype = "void(char*&, ...)"; +} + +def MSVaEnd : Builtin { + let Spellings = ["__builtin_ms_va_end"]; + let Attributes = [NoThrow]; + let Prototype = "void(char*&)"; +} + +def MSVaCopy : Builtin { + let Spellings = ["__builtin_ms_va_copy"]; + let Attributes = [NoThrow]; + let Prototype = "void(char*&, char*&)"; +} + +// Arithmetic Fence: to prevent FP reordering and reassociation optimizations +// FIXME: Should this just be a Builtin? +def ArithmeticFence : LangBuiltin<"ALL_LANGUAGES"> { + let Spellings = ["__arithmetic_fence"]; + let Attributes = [CustomTypeChecking, Constexpr]; + let Prototype = "void(...)"; +} diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def index 31ec84143f6..473b1d4698f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAArch64.def @@ -49,6 +49,10 @@ BUILTIN(__builtin_arm_wfe, "v", "") BUILTIN(__builtin_arm_wfi, "v", "") BUILTIN(__builtin_arm_sev, "v", "") BUILTIN(__builtin_arm_sevl, "v", "") +BUILTIN(__builtin_arm_chkfeat, "WUiWUi", "") + +// Like __builtin_trap but provide an 16-bit immediate reason code (which goes into `brk #N`). +BUILTIN(__builtin_arm_trap, "vUIs", "nr") // CRC32 TARGET_BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc", "crc") @@ -69,7 +73,7 @@ TARGET_BUILTIN(__builtin_arm_stg, "vv*", "t", "mte") TARGET_BUILTIN(__builtin_arm_subp, "Uiv*v*", "t", "mte") // SME state function -BUILTIN(__builtin_arm_get_sme_state, "vULi*ULi*", "n") +BUILTIN(__builtin_arm_get_sme_state, "vWUi*WUi*", "n") // Memory Operations TARGET_BUILTIN(__builtin_arm_mops_memset_tag, "v*v*iz", "", "mte,mops") @@ -133,12 +137,17 @@ TARGET_BUILTIN(__builtin_arm_st64b, "vv*WUiC*", "n", "ls64") TARGET_BUILTIN(__builtin_arm_st64bv, "WUiv*WUiC*", "n", "ls64") TARGET_BUILTIN(__builtin_arm_st64bv0, "WUiv*WUiC*", "n", "ls64") +// Armv9.3-A Guarded Control Stack +TARGET_BUILTIN(__builtin_arm_gcspopm, "WUiWUi", "n", "gcs") +TARGET_BUILTIN(__builtin_arm_gcsss, "vC*vC*", "n", "gcs") + TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanForward64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse64, "UcUNi*ULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedAdd, "NiNiD*Ni", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAdd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") @@ -286,7 +295,9 @@ TARGET_HEADER_BUILTIN(_CountLeadingZeros64, "UiULLi", "nh", INTRIN_H, ALL_MS_LAN TARGET_HEADER_BUILTIN(_CountOneBits, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(__prefetch, "vv*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__prefetch, "vvC*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") + +TARGET_HEADER_BUILTIN(__hlt, "UiUi.", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") #undef BUILTIN #undef LANGBUILTIN diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def index 74dfd1d214e..ab29ef38f77 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -61,14 +61,16 @@ BUILTIN(__builtin_amdgcn_s_waitcnt, "vIi", "n") BUILTIN(__builtin_amdgcn_s_sendmsg, "vIiUi", "n") BUILTIN(__builtin_amdgcn_s_sendmsghalt, "vIiUi", "n") BUILTIN(__builtin_amdgcn_s_barrier, "v", "n") +BUILTIN(__builtin_amdgcn_s_ttracedata, "vi", "n") BUILTIN(__builtin_amdgcn_wave_barrier, "v", "n") BUILTIN(__builtin_amdgcn_sched_barrier, "vIi", "n") BUILTIN(__builtin_amdgcn_sched_group_barrier, "vIiIiIi", "n") BUILTIN(__builtin_amdgcn_iglp_opt, "vIi", "n") BUILTIN(__builtin_amdgcn_s_dcache_inv, "v", "n") BUILTIN(__builtin_amdgcn_buffer_wbinvl1, "v", "n") -BUILTIN(__builtin_amdgcn_fence, "vUicC*", "n") +BUILTIN(__builtin_amdgcn_fence, "vUicC*.", "n") BUILTIN(__builtin_amdgcn_groupstaticsize, "Ui", "n") +BUILTIN(__builtin_amdgcn_wavefrontsize, "Ui", "nc") BUILTIN(__builtin_amdgcn_atomic_inc32, "UZiUZiD*UZiUicC*", "n") BUILTIN(__builtin_amdgcn_atomic_inc64, "UWiUWiD*UWiUicC*", "n") @@ -146,12 +148,26 @@ BUILTIN(__builtin_amdgcn_qsad_pk_u16_u8, "WUiWUiUiWUi", "nc") BUILTIN(__builtin_amdgcn_mqsad_pk_u16_u8, "WUiWUiUiWUi", "nc") BUILTIN(__builtin_amdgcn_mqsad_u32_u8, "V4UiWUiUiV4Ui", "nc") +BUILTIN(__builtin_amdgcn_make_buffer_rsrc, "Qbv*sii", "nc") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b8, "vUcQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b16, "vUsQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b32, "vUiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b64, "vV2UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b96, "vV3UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_store_b128, "vV4UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b8, "UcQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b16, "UsQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b32, "UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b64, "V2UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b96, "V3UiQbiiIi", "n") +BUILTIN(__builtin_amdgcn_raw_buffer_load_b128, "V4UiQbiiIi", "n") + //===----------------------------------------------------------------------===// // Ballot builtins. //===----------------------------------------------------------------------===// TARGET_BUILTIN(__builtin_amdgcn_ballot_w32, "ZUib", "nc", "wavefrontsize32") -TARGET_BUILTIN(__builtin_amdgcn_ballot_w64, "WUib", "nc", "wavefrontsize64") +BUILTIN(__builtin_amdgcn_ballot_w64, "WUib", "nc") // Deprecated intrinsics in favor of __builtin_amdgn_ballot_{w32|w64} BUILTIN(__builtin_amdgcn_uicmp, "WUiUiUiIi", "nc") @@ -238,6 +254,7 @@ TARGET_BUILTIN(__builtin_amdgcn_flat_atomic_fadd_v2bf16, "V2sV2s*0V2s", "t", "at TARGET_BUILTIN(__builtin_amdgcn_global_atomic_fadd_v2bf16, "V2sV2s*1V2s", "t", "atomic-global-pk-add-bf16-inst") TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2bf16, "V2sV2s*3V2s", "t", "atomic-ds-pk-add-16-insts") TARGET_BUILTIN(__builtin_amdgcn_ds_atomic_fadd_v2f16, "V2hV2h*3V2h", "t", "atomic-ds-pk-add-16-insts") +TARGET_BUILTIN(__builtin_amdgcn_global_load_lds, "vv*1v*3IUiIiIUi", "t", "gfx940-insts") //===----------------------------------------------------------------------===// // Deep learning builtins. @@ -255,10 +272,10 @@ TARGET_BUILTIN(__builtin_amdgcn_sudot4, "iIbiIbiiIb", "nc", "dot8-insts") TARGET_BUILTIN(__builtin_amdgcn_sdot8, "SiSiSiSiIb", "nc", "dot1-insts") TARGET_BUILTIN(__builtin_amdgcn_udot8, "UiUiUiUiIb", "nc", "dot7-insts") TARGET_BUILTIN(__builtin_amdgcn_sudot8, "iIbiIbiiIb", "nc", "dot8-insts") -TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_bf8, "fUiUif", "nc", "gfx12-insts") -TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_fp8, "fUiUif", "nc", "gfx12-insts") -TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_fp8, "fUiUif", "nc", "gfx12-insts") -TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_bf8, "fUiUif", "nc", "gfx12-insts") +TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_bf8, "fUiUif", "nc", "dot11-insts") +TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_fp8, "fUiUif", "nc", "dot11-insts") +TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_fp8_fp8, "fUiUif", "nc", "dot11-insts") +TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_bf8, "fUiUif", "nc", "dot11-insts") //===----------------------------------------------------------------------===// // GFX10+ only builtins. @@ -266,6 +283,7 @@ TARGET_BUILTIN(__builtin_amdgcn_dot4_f32_bf8_bf8, "fUiUif", "nc", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_permlane16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts") TARGET_BUILTIN(__builtin_amdgcn_permlanex16, "UiUiUiUiUiIbIb", "nc", "gfx10-insts") TARGET_BUILTIN(__builtin_amdgcn_mov_dpp8, "UiUiIUi", "nc", "gfx10-insts") +TARGET_BUILTIN(__builtin_amdgcn_s_ttracedata_imm, "vIs", "n", "gfx10-insts") //===----------------------------------------------------------------------===// // Raytracing builtins. @@ -292,23 +310,23 @@ TARGET_BUILTIN(__builtin_amdgcn_s_wait_event_export_ready, "v", "n", "gfx11-inst // Postfix w32 indicates the builtin requires wavefront size of 32. // Postfix w64 indicates the builtin requires wavefront size of 64. //===----------------------------------------------------------------------===// -TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w32, "V8fV16hV16hV8f", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w32, "V8fV16sV16sV8f", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w32, "V16hV16hV16hV16hIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w32, "V16sV16sV16sV16sIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_tied_w32, "V16hV16hV16hV16hIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_tied_w32, "V16sV16sV16sV16sIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w32, "V8iIbV4iIbV4iV8iIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w32, "V8iIbV2iIbV2iV8iIb", "nc", "gfx11-insts") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w32, "V8fV16hV16hV8f", "nc", "gfx11-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w32, "V8fV16sV16sV8f", "nc", "gfx11-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w32, "V16hV16hV16hV16hIb", "nc", "gfx11-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w32, "V16sV16sV16sV16sIb", "nc", "gfx11-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_tied_w32, "V16hV16hV16hV16hIb", "nc", "gfx11-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_tied_w32, "V16sV16sV16sV16sIb", "nc", "gfx11-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w32, "V8iIbV4iIbV4iV8iIb", "nc", "gfx11-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w32, "V8iIbV2iIbV2iV8iIb", "nc", "gfx11-insts,wavefrontsize32") -TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w64, "V4fV16hV16hV4f", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w64, "V4fV16sV16sV4f", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w64, "V8hV16hV16hV8hIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w64, "V8sV16sV16sV8sIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_tied_w64, "V8hV16hV16hV8hIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_tied_w64, "V8sV16sV16sV8sIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w64, "V4iIbV4iIbV4iV4iIb", "nc", "gfx11-insts") -TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w64, "V4iIbV2iIbV2iV4iIb", "nc", "gfx11-insts") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_f16_w64, "V4fV16hV16hV4f", "nc", "gfx11-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x16_bf16_w64, "V4fV16sV16sV4f", "nc", "gfx11-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_w64, "V8hV16hV16hV8hIb", "nc", "gfx11-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w64, "V8sV16sV16sV8sIb", "nc", "gfx11-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x16_f16_tied_w64, "V8hV16hV16hV8hIb", "nc", "gfx11-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_wmma_bf16_16x16x16_bf16_tied_w64, "V8sV16sV16sV8sIb", "nc", "gfx11-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu8_w64, "V4iIbV4iIbV4iV4iIb", "nc", "gfx11-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_wmma_i32_16x16x16_iu4_w64, "V4iIbV2iIbV2iV4iIb", "nc", "gfx11-insts,wavefrontsize64") TARGET_BUILTIN(__builtin_amdgcn_s_sendmsg_rtn, "UiUIi", "n", "gfx11-insts") TARGET_BUILTIN(__builtin_amdgcn_s_sendmsg_rtnl, "UWiUIi", "n", "gfx11-insts") @@ -324,6 +342,9 @@ BUILTIN(__builtin_amdgcn_read_exec_hi, "Ui", "nc") BUILTIN(__builtin_amdgcn_endpgm, "v", "nr") +BUILTIN(__builtin_amdgcn_get_fpenv, "WUi", "n") +BUILTIN(__builtin_amdgcn_set_fpenv, "vWUi", "n") + //===----------------------------------------------------------------------===// // R600-NI only builtins. //===----------------------------------------------------------------------===// @@ -428,13 +449,14 @@ TARGET_BUILTIN(__builtin_amdgcn_s_wakeup_barrier, "vi", "n", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_s_barrier_leave, "b", "n", "gfx12-insts") TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts") -TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32") -TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32") -TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32") - -TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64") -TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64") -TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8bf16, "V8yV8y*1", "nc", "gfx12-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64") +TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64") +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") //===----------------------------------------------------------------------===// // WMMA builtins. diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBPF.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBPF.def deleted file mode 100644 index 190062645ec..00000000000 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBPF.def +++ /dev/null @@ -1,33 +0,0 @@ -//===--- BuiltinsBPF.def - BPF 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 BPF-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 - -// Get record field information. -TARGET_BUILTIN(__builtin_preserve_field_info, "Ui.", "t", "") - -// Get BTF type id. -TARGET_BUILTIN(__builtin_btf_type_id, "LUi.", "t", "") - -// Get type information. -TARGET_BUILTIN(__builtin_preserve_type_info, "Ui.", "t", "") - -// Preserve enum value. -TARGET_BUILTIN(__builtin_preserve_enum_value, "Li.", "t", "") - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBPF.td b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBPF.td new file mode 100644 index 00000000000..169d05c8709 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBPF.td @@ -0,0 +1,37 @@ +//===--- BuiltinsBPF.td - BPF 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 +// +//===----------------------------------------------------------------------===// + +include "clang/Basic/BuiltinsBase.td" + +// Get record field information +def PreserveFieldInfo : TargetBuiltin { + let Spellings = ["__builtin_preserve_field_info"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "unsigned int(...)"; +} + +// Get BTF type id +def BtfTypeID : TargetBuiltin { + let Spellings = ["__builtin_btf_type_id"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "long unsigned int(...)"; +} + +// Get type information +def PreserveTypeInfo : TargetBuiltin { + let Spellings = ["__builtin_preserve_type_info"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "long unsigned int(...)"; +} + +// Preserve enum value +def PreserveEnumValue : TargetBuiltin { + let Spellings = ["__builtin_preserve_enum_value"]; + let Attributes = [CustomTypeChecking]; + let Prototype = "long int(...)"; +} diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBase.td b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBase.td new file mode 100644 index 00000000000..58dee22fc0a --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsBase.td @@ -0,0 +1,127 @@ +//===--- BuiltinsBase.td - common structured used by builtins ---*- 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 +// +//===----------------------------------------------------------------------===// + +// Attributes +// ========== + +class Attribute { + string Mangling = mangling; +} + +class IndexedAttribute : Attribute { + int Index = I; +} + +// Standard Attributes +// ------------------- +def NoReturn : Attribute<"r">; + +// Attributes from the gnu:: namespace +// ----------------------------------- +def Const : Attribute<"c">; +def NoThrow : Attribute<"n">; +def Pure : Attribute<"U">; +def ReturnsTwice : Attribute<"j">; +// FIXME: gcc has nonnull + +// builtin-specific attributes +// --------------------------- + +// Signature is meaningless, use custom typechecking. +def CustomTypeChecking : Attribute<"t">; + +// Type is not important to semantic analysis and codegen; recognize as builtin +// even if type doesn't match signature, and don't warn if we can't be sure the +// type is right. +def IgnoreSignature : Attribute<"T">; + +// Arguments are not evaluated for their side-effects. +def UnevaluatedArguments : Attribute<"u">; + +// FIXME: This is misused in a lot of the places it is used currently. +// This function is equivalent to a library function without the __builtin_ +// prefix. This is relevant for CodeGen; it should not be used if custom CodeGen +// is required for a builtin. +def FunctionWithBuiltinPrefix : Attribute<"F">; + +def FunctionWithoutBuiltinPrefix : Attribute<"f">; + +// const, but only when -fno-math-errno and FP exceptions are ignored. +def ConstIgnoringErrnoAndExceptions : Attribute<"e">; + +// const when FP exceptions are ignored. +def ConstIgnoringExceptions : Attribute<"g">; + +// This function requires a specific header or an explicit declaration. +def RequireDeclaration : Attribute<"h">; + +class PrintfFormat : IndexedAttribute<"p", I>; +class VPrintfFormat : IndexedAttribute<"P", I>; +class ScanfFormat : IndexedAttribute<"s", I>; +class VScanfFormat : IndexedAttribute<"S", I>; + +// Other Attributes +// ---------------- + +// Builtin can be constant evaluated +def Constexpr : Attribute<"E">; +// Builtin is immediate and must be constant evaluated. Implies Constexpr, and will only be supported in C++20 mode. +def Consteval : Attribute<"EG">; + +// Builtin kinds +// ============= + +class Builtin { + list Spellings; + list Attributes = []; + string Prototype; + string Namespace; + // On some platforms, some functions are actually macros. In that case we need + // to #undef them. + bit RequiresUndef = 0; +} + +class CustomEntry { + string Entry; +} + +class AtomicBuiltin : Builtin; +class TargetBuiltin : Builtin { + string Features = ""; +} + +class LibBuiltin : Builtin { + string Header = header; + string Languages = languages; + bit AddBuiltinPrefixedAlias = 0; + bit OnlyBuiltinPrefixedAliasIsConstexpr = 0; +} + +class MSLibBuiltin : LibBuiltin; +class GNULibBuiltin : LibBuiltin; +class ObjCLibBuiltin : LibBuiltin; +class CxxLibBuiltin : LibBuiltin; + +class LangBuiltin : Builtin { + string Languages = languages; +} + +class MSLangBuiltin : LangBuiltin<"ALL_MS_LANGUAGES">; +class CoroLangBuiltin : LangBuiltin<"COR_LANG">; +class OCLPipeLangBuiltin : LangBuiltin<"OCL_PIPE">; +class OCL_DSELangBuiltin : LangBuiltin<"OCL_DSE">; +class OCL_GASLangBuiltin : LangBuiltin<"OCL_GAS">; +class OCLLangBuiltin : LangBuiltin<"ALL_OCL_LANGUAGES">; + +class Template substitutions, + list affixes, + bit as_prefix = 0> { + list Substitutions = substitutions; + list Affixes = affixes; + bit AsPrefix = as_prefix; +} diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def index 0f2e8260143..504314d8d96 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsNVPTX.def @@ -44,6 +44,7 @@ #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") @@ -60,7 +61,11 @@ #pragma push_macro("PTX81") #pragma push_macro("PTX82") #pragma push_macro("PTX83") -#define PTX83 "ptx83" +#pragma push_macro("PTX84") +#pragma push_macro("PTX85") +#define PTX85 "ptx85" +#define PTX84 "ptx84|" PTX85 +#define PTX83 "ptx83|" PTX84 #define PTX82 "ptx82|" PTX83 #define PTX81 "ptx81|" PTX82 #define PTX80 "ptx80|" PTX81 @@ -76,7 +81,8 @@ #define PTX65 "ptx65|" PTX70 #define PTX64 "ptx64|" PTX65 #define PTX63 "ptx63|" PTX64 -#define PTX61 "ptx61|" PTX63 +#define PTX62 "ptx62|" PTX63 +#define PTX61 "ptx61|" PTX62 #define PTX60 "ptx60|" PTX61 #define PTX42 "ptx42|" PTX60 @@ -146,6 +152,7 @@ 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") @@ -155,6 +162,9 @@ 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 @@ -632,6 +642,9 @@ 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)) @@ -1065,6 +1078,7 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78)) #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") @@ -1081,3 +1095,5 @@ TARGET_BUILTIN(__nvvm_getctarank_shared_cluster, "iv*3", "", AND(SM_90,PTX78)) #pragma pop_macro("PTX81") #pragma pop_macro("PTX82") #pragma pop_macro("PTX83") +#pragma pop_macro("PTX84") +#pragma pop_macro("PTX85") diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def deleted file mode 100644 index 1528b18c82e..00000000000 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.def +++ /dev/null @@ -1,93 +0,0 @@ -//==- BuiltinsRISCV.def - RISC-V 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 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 - -// Zbb extension -TARGET_BUILTIN(__builtin_riscv_orc_b_32, "UiUi", "nc", "zbb") -TARGET_BUILTIN(__builtin_riscv_orc_b_64, "UWiUWi", "nc", "zbb,64bit") -TARGET_BUILTIN(__builtin_riscv_clz_32, "UiUi", "nc", "zbb|xtheadbb") -TARGET_BUILTIN(__builtin_riscv_clz_64, "UiUWi", "nc", "zbb|xtheadbb,64bit") -TARGET_BUILTIN(__builtin_riscv_ctz_32, "UiUi", "nc", "zbb") -TARGET_BUILTIN(__builtin_riscv_ctz_64, "UiUWi", "nc", "zbb,64bit") - -// Zbc or Zbkc extension -TARGET_BUILTIN(__builtin_riscv_clmul_32, "UiUiUi", "nc", "zbc|zbkc") -TARGET_BUILTIN(__builtin_riscv_clmul_64, "UWiUWiUWi", "nc", "zbc|zbkc,64bit") -TARGET_BUILTIN(__builtin_riscv_clmulh_32, "UiUiUi", "nc", "zbc|zbkc,32bit") -TARGET_BUILTIN(__builtin_riscv_clmulh_64, "UWiUWiUWi", "nc", "zbc|zbkc,64bit") -TARGET_BUILTIN(__builtin_riscv_clmulr_32, "UiUiUi", "nc", "zbc,32bit") -TARGET_BUILTIN(__builtin_riscv_clmulr_64, "UWiUWiUWi", "nc", "zbc,64bit") - -// Zbkx -TARGET_BUILTIN(__builtin_riscv_xperm4_32, "UiUiUi", "nc", "zbkx,32bit") -TARGET_BUILTIN(__builtin_riscv_xperm4_64, "UWiUWiUWi", "nc", "zbkx,64bit") -TARGET_BUILTIN(__builtin_riscv_xperm8_32, "UiUiUi", "nc", "zbkx,32bit") -TARGET_BUILTIN(__builtin_riscv_xperm8_64, "UWiUWiUWi", "nc", "zbkx,64bit") - -// Zbkb extension -TARGET_BUILTIN(__builtin_riscv_brev8_32, "UiUi", "nc", "zbkb") -TARGET_BUILTIN(__builtin_riscv_brev8_64, "UWiUWi", "nc", "zbkb,64bit") -TARGET_BUILTIN(__builtin_riscv_zip_32, "UiUi", "nc", "zbkb,32bit") -TARGET_BUILTIN(__builtin_riscv_unzip_32, "UiUi", "nc", "zbkb,32bit") - -// Zknd extension -TARGET_BUILTIN(__builtin_riscv_aes32dsi, "UiUiUiIUi", "nc", "zknd,32bit") -TARGET_BUILTIN(__builtin_riscv_aes32dsmi, "UiUiUiIUi", "nc", "zknd,32bit") -TARGET_BUILTIN(__builtin_riscv_aes64ds, "UWiUWiUWi", "nc", "zknd,64bit") -TARGET_BUILTIN(__builtin_riscv_aes64dsm, "UWiUWiUWi", "nc", "zknd,64bit") -TARGET_BUILTIN(__builtin_riscv_aes64im, "UWiUWi", "nc", "zknd,64bit") - -// Zknd & Zkne -TARGET_BUILTIN(__builtin_riscv_aes64ks1i, "UWiUWiIUi", "nc", "zknd|zkne,64bit") -TARGET_BUILTIN(__builtin_riscv_aes64ks2, "UWiUWiUWi", "nc", "zknd|zkne,64bit") - -// Zkne extension -TARGET_BUILTIN(__builtin_riscv_aes32esi, "UiUiUiIUi", "nc", "zkne,32bit") -TARGET_BUILTIN(__builtin_riscv_aes32esmi, "UiUiUiIUi", "nc", "zkne,32bit") -TARGET_BUILTIN(__builtin_riscv_aes64es, "UWiUWiUWi", "nc", "zkne,64bit") -TARGET_BUILTIN(__builtin_riscv_aes64esm, "UWiUWiUWi", "nc", "zkne,64bit") - -// Zknh extension -TARGET_BUILTIN(__builtin_riscv_sha256sig0, "UiUi", "nc", "zknh") -TARGET_BUILTIN(__builtin_riscv_sha256sig1, "UiUi", "nc", "zknh") -TARGET_BUILTIN(__builtin_riscv_sha256sum0, "UiUi", "nc", "zknh") -TARGET_BUILTIN(__builtin_riscv_sha256sum1, "UiUi", "nc", "zknh") - -TARGET_BUILTIN(__builtin_riscv_sha512sig0h, "UiUiUi", "nc", "zknh,32bit") -TARGET_BUILTIN(__builtin_riscv_sha512sig0l, "UiUiUi", "nc", "zknh,32bit") -TARGET_BUILTIN(__builtin_riscv_sha512sig1h, "UiUiUi", "nc", "zknh,32bit") -TARGET_BUILTIN(__builtin_riscv_sha512sig1l, "UiUiUi", "nc", "zknh,32bit") -TARGET_BUILTIN(__builtin_riscv_sha512sum0r, "UiUiUi", "nc", "zknh,32bit") -TARGET_BUILTIN(__builtin_riscv_sha512sum1r, "UiUiUi", "nc", "zknh,32bit") -TARGET_BUILTIN(__builtin_riscv_sha512sig0, "UWiUWi", "nc", "zknh,64bit") -TARGET_BUILTIN(__builtin_riscv_sha512sig1, "UWiUWi", "nc", "zknh,64bit") -TARGET_BUILTIN(__builtin_riscv_sha512sum0, "UWiUWi", "nc", "zknh,64bit") -TARGET_BUILTIN(__builtin_riscv_sha512sum1, "UWiUWi", "nc", "zknh,64bit") - -// Zksed extension -TARGET_BUILTIN(__builtin_riscv_sm4ed, "UiUiUiIUi", "nc", "zksed") -TARGET_BUILTIN(__builtin_riscv_sm4ks, "UiUiUiIUi", "nc", "zksed") - -// Zksh extension -TARGET_BUILTIN(__builtin_riscv_sm3p0, "UiUi", "nc", "zksh") -TARGET_BUILTIN(__builtin_riscv_sm3p1, "UiUi", "nc", "zksh") - -// Zihintntl extension -TARGET_BUILTIN(__builtin_riscv_ntl_load, "v.", "t", "zihintntl") -TARGET_BUILTIN(__builtin_riscv_ntl_store, "v.", "t", "zihintntl") - -#undef BUILTIN -#undef TARGET_BUILTIN diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.td b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.td new file mode 100644 index 00000000000..4cc89a8a9d8 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsRISCV.td @@ -0,0 +1,148 @@ +//==- BuiltinsRISCV.td - RISC-V Builtin function database ---*- tablegen -*-==// +// +// 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. +// +//===----------------------------------------------------------------------===// + +include "clang/Basic/BuiltinsBase.td" + +class RISCVBuiltin : TargetBuiltin { + let Spellings = ["__builtin_riscv_" # NAME]; + let Prototype = prototype; + let Features = features; +} + +let Attributes = [NoThrow, Const] in { +//===----------------------------------------------------------------------===// +// Zbb extension. +//===----------------------------------------------------------------------===// +def orc_b_32 : RISCVBuiltin<"unsigned int(unsigned int)", "zbb">; +def orc_b_64 : RISCVBuiltin<"uint64_t(uint64_t)", "zbb,64bit">; +def clz_32 : RISCVBuiltin<"unsigned int(unsigned int)", "zbb|xtheadbb">; +def clz_64 : RISCVBuiltin<"unsigned int(uint64_t)", "zbb|xtheadbb,64bit">; +def ctz_32 : RISCVBuiltin<"unsigned int(unsigned int)", "zbb">; +def ctz_64 : RISCVBuiltin<"unsigned int(uint64_t)", "zbb,64bit">; + +//===----------------------------------------------------------------------===// +// Zbc or Zbkc extension. +//===----------------------------------------------------------------------===// +def clmul_32 : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)", "zbc|zbkc">; +def clmul_64 : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)", "zbc|zbkc,64bit">; +def clmulh_32 : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)", "zbc|zbkc,32bit">; +def clmulh_64 : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)", "zbc|zbkc,64bit">; +def clmulr_32 : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)", "zbc,32bit">; +def clmulr_64 : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)", "zbc,64bit">; + +//===----------------------------------------------------------------------===// +// Zbkx extension. +//===----------------------------------------------------------------------===// +let Features = "zbkx,32bit" in { +def xperm4_32 : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +def xperm8_32 : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +} // Features = "zbkx,32bit" + +let Features = "zbkx,64bit" in { +def xperm4_64 : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)">; +def xperm8_64 : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)">; +} // Features = "zbkx,64bit" + +//===----------------------------------------------------------------------===// +// Zbkb extension. +//===----------------------------------------------------------------------===// +def brev8_32 : RISCVBuiltin<"unsigned int(unsigned int)", "zbkb">; +def brev8_64 : RISCVBuiltin<"uint64_t(uint64_t)", "zbkb,64bit">; +def zip_32 : RISCVBuiltin<"unsigned int(unsigned int)", "zbkb,32bit">; +def unzip_32 : RISCVBuiltin<"unsigned int(unsigned int)", "zbkb,32bit">; + +//===----------------------------------------------------------------------===// +// Zknd extension. +//===----------------------------------------------------------------------===// +let Features = "zknd,32bit" in { +def aes32dsi : RISCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)">; +def aes32dsmi : RISCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)">; +} // Features = "zknd,32bit" + +let Features = "zknd,64bit" in { +def aes64ds : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)">; +def aes64dsm : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)">; +def aes64im : RISCVBuiltin<"uint64_t(uint64_t)">; +} // Features = "zknd,64bit" + +//===----------------------------------------------------------------------===// +// Zknd & Zkne extension. +//===----------------------------------------------------------------------===// +let Features = "zknd|zkne,64bit" in { +def aes64ks1i : RISCVBuiltin<"uint64_t(uint64_t, _Constant unsigned int)">; +def aes64ks2 : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)">; +} // Features = "zknd|zkne,64bit" + +//===----------------------------------------------------------------------===// +// Zkne extension. +//===----------------------------------------------------------------------===// +let Features = "zkne,32bit" in { +def aes32esi : RISCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)">; +def aes32esmi : RISCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)">; +} // Features = "zkne,32bit" + +let Features = "zkne,64bit" in { +def aes64es : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)">; +def aes64esm : RISCVBuiltin<"uint64_t(uint64_t, uint64_t)">; +} // Features = "zkne,64bit" + +//===----------------------------------------------------------------------===// +// Zknh extension. +//===----------------------------------------------------------------------===// +let Features = "zknh" in { +def sha256sig0 : RISCVBuiltin<"unsigned int(unsigned int)">; +def sha256sig1 : RISCVBuiltin<"unsigned int(unsigned int)">; +def sha256sum0 : RISCVBuiltin<"unsigned int(unsigned int)">; +def sha256sum1 : RISCVBuiltin<"unsigned int(unsigned int)">; +} // Features = "zknh" + +let Features = "zknh,32bit" in { +def sha512sig0h : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +def sha512sig0l : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +def sha512sig1h : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +def sha512sig1l : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +def sha512sum0r : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +def sha512sum1r : RISCVBuiltin<"unsigned int(unsigned int, unsigned int)">; +} // Features = "zknh,32bit" + +let Features = "zknh,64bit" in { +def sha512sig0 : RISCVBuiltin<"uint64_t(uint64_t)">; +def sha512sig1 : RISCVBuiltin<"uint64_t(uint64_t)">; +def sha512sum0 : RISCVBuiltin<"uint64_t(uint64_t)">; +def sha512sum1 : RISCVBuiltin<"uint64_t(uint64_t)">; +} // Features = "zknh,64bit" + +//===----------------------------------------------------------------------===// +// Zksed extension. +//===----------------------------------------------------------------------===// +let Features = "zksed" in { +def sm4ed : RISCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int )">; +def sm4ks : RISCVBuiltin<"unsigned int(unsigned int, unsigned int, _Constant unsigned int)">; +} // Features = "zksed" + +//===----------------------------------------------------------------------===// +// Zksh extension. +//===----------------------------------------------------------------------===// +let Features = "zksh" in { +def sm3p0 : RISCVBuiltin<"unsigned int(unsigned int)">; +def sm3p1 : RISCVBuiltin<"unsigned int(unsigned int)">; +} // Features = "zksh" + +} // Attributes = [Const, NoThrow] + +//===----------------------------------------------------------------------===// +// Zihintntl extension. +//===----------------------------------------------------------------------===// +let Features = "zihintntl", Attributes = [CustomTypeChecking] in { +def ntl_load : RISCVBuiltin<"void(...)">; +def ntl_store : RISCVBuiltin<"void(...)">; +} // Features = "zihintntl", Attributes = [CustomTypeChecking] diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def index 7e950914ad9..2a45f8a6582 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -135,6 +135,10 @@ TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_pmin_f64x2, "V2dV2dV2d", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_pmax_f64x2, "V2dV2dV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_f16x8, "V8hV8hV8h", "nc", "half-precision") +TARGET_BUILTIN(__builtin_wasm_max_f16x8, "V8hV8hV8h", "nc", "half-precision") +TARGET_BUILTIN(__builtin_wasm_pmin_f16x8, "V8hV8hV8h", "nc", "half-precision") +TARGET_BUILTIN(__builtin_wasm_pmax_f16x8, "V8hV8hV8h", "nc", "half-precision") TARGET_BUILTIN(__builtin_wasm_ceil_f32x4, "V4fV4f", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_floor_f32x4, "V4fV4f", "nc", "simd128") @@ -166,6 +170,8 @@ TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f32x4, "V4fV4fV4fV4f", "nc", "relaxed TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f32x4, "V4fV4fV4fV4f", "nc", "relaxed-simd") TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f64x2, "V2dV2dV2dV2d", "nc", "relaxed-simd") TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f64x2, "V2dV2dV2dV2d", "nc", "relaxed-simd") +TARGET_BUILTIN(__builtin_wasm_relaxed_madd_f16x8, "V8hV8hV8hV8h", "nc", "half-precision") +TARGET_BUILTIN(__builtin_wasm_relaxed_nmadd_f16x8, "V8hV8hV8hV8h", "nc", "half-precision") TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i8x16, "V16ScV16ScV16ScV16Sc", "nc", "relaxed-simd") TARGET_BUILTIN(__builtin_wasm_relaxed_laneselect_i16x8, "V8sV8sV8sV8s", "nc", "relaxed-simd") @@ -190,6 +196,12 @@ TARGET_BUILTIN(__builtin_wasm_relaxed_dot_i8x16_i7x16_s_i16x8, "V8sV16ScV16Sc", TARGET_BUILTIN(__builtin_wasm_relaxed_dot_i8x16_i7x16_add_s_i32x4, "V4iV16ScV16ScV4i", "nc", "relaxed-simd") TARGET_BUILTIN(__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4, "V4fV8UsV8UsV4f", "nc", "relaxed-simd") +// Half-Precision (fp16) +TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision") +TARGET_BUILTIN(__builtin_wasm_storef16_f32, "vfh*", "n", "half-precision") +TARGET_BUILTIN(__builtin_wasm_splat_f16x8, "V8hf", "nc", "half-precision") +TARGET_BUILTIN(__builtin_wasm_extract_lane_f16x8, "fV8hi", "nc", "half-precision") + // Reference Types builtins // Some builtins are custom type-checked - see 't' as part of the third argument, // in which case the argument spec (second argument) is unused. diff --git a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def index 60b752ad485..a85e7918f4d 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def +++ b/contrib/llvm-project/clang/include/clang/Basic/BuiltinsX86.def @@ -26,13 +26,6 @@ # define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANG, FEATURE) BUILTIN(ID, TYPE, ATTRS) #endif -// Miscellaneous builtin for checking x86 cpu features. -// TODO: Make this somewhat generic so that other backends -// can use it? -BUILTIN(__builtin_cpu_init, "v", "n") -BUILTIN(__builtin_cpu_supports, "bcC*", "nc") -BUILTIN(__builtin_cpu_is, "bcC*", "nc") - // Undefined Values // TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "ncV:128:", "") @@ -44,36 +37,6 @@ TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "ncV:512:", "") TARGET_BUILTIN(__builtin_ia32_readeflags_u32, "Ui", "n", "") TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "") -// 3DNow! -// -TARGET_BUILTIN(__builtin_ia32_femms, "v", "n", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "ncV:64:", "3dnow") -TARGET_BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "ncV:64:", "3dnow") -// 3DNow! Extensions (3dnowa). -TARGET_BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "ncV:64:", "3dnowa") -TARGET_BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "ncV:64:", "3dnowa") -TARGET_BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "ncV:64:", "3dnowa") -TARGET_BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "ncV:64:", "3dnowa") -TARGET_BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "ncV:64:", "3dnowa") -TARGET_BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "ncV:64:", "3dnowa") - // MMX // // All MMX instructions will be generated via builtins. Any MMX vector @@ -233,6 +196,8 @@ TARGET_BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "sse") TARGET_BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "ncV:128:", "sse2") @@ -250,6 +215,8 @@ TARGET_BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "ncV:128:", "sse2") TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "ncV:128:", "sse2") @@ -469,12 +436,8 @@ TARGET_BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_shufpd256, "V4dV4dV4dIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_shufps256, "V8fV8fV8fIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "ncV:256:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "avx") -TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "avx") TARGET_BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fIi", "ncV:256:", "avx") TARGET_BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8iIi", "ncV:256:", "avx") @@ -839,23 +802,11 @@ TARGET_BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512") -TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512") - TARGET_BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "ncV:512:", "avx512f,evex512") -TARGET_BUILTIN(__builtin_ia32_rcp28sd_round_mask, "V2dV2dV2dV2dUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rcp28ss_round_mask, "V4fV4fV4fV4fUcIi", "ncV:128:", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "ncV:512:", "avx512er,evex512") -TARGET_BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "ncV:512:", "avx512er,evex512") - TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "ncV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "ncV:512:", "avx512f,evex512") @@ -967,15 +918,6 @@ TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "nV:512:", "avx TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8OiV8OiIi", "nV:512:", "avx512f,evex512") TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8OiV8iIi", "nV:512:", "avx512f,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8OivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8OivC*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf,evex512") -TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8Oiv*IiIi", "nV:512:", "avx512pf,evex512") - TARGET_BUILTIN(__builtin_ia32_knotqi, "UcUc", "nc", "avx512dq") TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "nc", "avx512f") TARGET_BUILTIN(__builtin_ia32_knotsi, "UiUi", "nc", "avx512bw") diff --git a/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h b/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h index 7d411938350..87626eeb8a7 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h +++ b/contrib/llvm-project/clang/include/clang/Basic/CharInfo.h @@ -28,8 +28,7 @@ namespace charinfo { CHAR_LOWER = 0x0040, // a-z CHAR_UNDER = 0x0080, // _ CHAR_PERIOD = 0x0100, // . - CHAR_RAWDEL = 0x0200, // {}[]#<>%:;?*+-/^&|~!=,"' - CHAR_PUNCT = 0x0400 // `$@() + CHAR_PUNCT = 0x0200, // {}[]#<>%:;?*+-/^&|~!=,"'`$@() }; enum { @@ -59,12 +58,28 @@ LLVM_READONLY inline bool isAsciiIdentifierStart(unsigned char c, return AllowDollar && c == '$'; } +LLVM_READONLY inline bool isAsciiIdentifierContinue(unsigned char c) { + // Precomputed CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER + static constexpr unsigned char IDContinue[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + return IDContinue[c]; +} + /// Returns true if this is a body character of a C identifier, /// which is [a-zA-Z0-9_]. LLVM_READONLY inline bool isAsciiIdentifierContinue(unsigned char c, - bool AllowDollar = false) { - using namespace charinfo; - if (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_DIGIT|CHAR_UNDER)) + bool AllowDollar) { + if (isAsciiIdentifierContinue(c)) return true; return AllowDollar && c == '$'; } @@ -136,7 +151,7 @@ LLVM_READONLY inline bool isHexDigit(unsigned char c) { /// Note that '_' is both a punctuation character and an identifier character! LLVM_READONLY inline bool isPunctuation(unsigned char c) { using namespace charinfo; - return (InfoTable[c] & (CHAR_UNDER|CHAR_PERIOD|CHAR_RAWDEL|CHAR_PUNCT)) != 0; + return (InfoTable[c] & (CHAR_UNDER | CHAR_PERIOD | CHAR_PUNCT)) != 0; } /// Return true if this character is an ASCII printable character; that is, a @@ -144,8 +159,8 @@ LLVM_READONLY inline bool isPunctuation(unsigned char c) { /// terminal. LLVM_READONLY inline bool isPrintable(unsigned char c) { using namespace charinfo; - return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD|CHAR_PUNCT| - CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL|CHAR_SPACE)) != 0; + return (InfoTable[c] & (CHAR_UPPER | CHAR_LOWER | CHAR_PERIOD | CHAR_PUNCT | + CHAR_DIGIT | CHAR_UNDER | CHAR_SPACE)) != 0; } /// Return true if this is the body character of a C preprocessing number, @@ -159,8 +174,9 @@ LLVM_READONLY inline bool isPreprocessingNumberBody(unsigned char c) { /// Return true if this is the body character of a C++ raw string delimiter. LLVM_READONLY inline bool isRawStringDelimBody(unsigned char c) { using namespace charinfo; - return (InfoTable[c] & (CHAR_UPPER|CHAR_LOWER|CHAR_PERIOD| - CHAR_DIGIT|CHAR_UNDER|CHAR_RAWDEL)) != 0; + return (InfoTable[c] & (CHAR_UPPER | CHAR_LOWER | CHAR_PERIOD | CHAR_DIGIT | + CHAR_UNDER | CHAR_PUNCT)) != 0 && + c != '(' && c != ')' && c != '\\'; } enum class EscapeChar { diff --git a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def index 7c0bfe32849..12808eb275f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def +++ b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def @@ -36,7 +36,9 @@ VALUE_CODEGENOPT(Name, Bits, Default) #endif CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as +CODEGENOPT(Crel, 1, 0) ///< -Wa,--crel CODEGENOPT(RelaxELFRelocations, 1, 1) ///< -Wa,-mrelax-relocations={yes,no} +CODEGENOPT(SSE2AVX , 1, 0) ///< -msse2avx CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm. CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments. CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new @@ -57,9 +59,11 @@ CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block-section-names, ///< Produce unique section names with ///< basic block sections. +CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for -fseparate-named-sections. CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX. CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr. -ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none +CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata +ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,reserved,none CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running backend code generation. Only works with -disable-free. CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory. @@ -96,6 +100,7 @@ ENUM_CODEGENOPT(InlineAsmDialect, InlineAsmDialectKind, 1, IAD_ATT) CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables ///< are required. CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled. +CODEGENOPT(BBAddrMap , 1, 0) ///< Set when -fbasic-block-address-map is enabled. CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is ///< enabled. CODEGENOPT(InstrumentFunctionsAfterInlining , 1, 0) ///< Set when @@ -184,6 +189,7 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enable CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. CODEGENOPT(OpenCLCorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt CODEGENOPT(HIPCorrectlyRoundedDivSqrt, 1, 1) ///< -fno-hip-fp32-correctly-rounded-divide-sqrt +CODEGENOPT(DisableBlockSignatureString, 1, 0) ///< Set when -fdisable-block-signature-string is enabled. CODEGENOPT(HIPSaveKernelArgName, 1, 0) ///< Set when -fhip-kernel-arg-name is enabled. CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names. CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information. @@ -220,12 +226,15 @@ CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping ///< regions. CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code coverage criteria. +VALUE_CODEGENOPT(MCDCMaxConds, 16, 32767) ///< MC/DC Maximum conditions. +VALUE_CODEGENOPT(MCDCMaxTVs, 32, 0x7FFFFFFE) ///< MC/DC Maximum test vectors. /// If -fpcc-struct-return or -freg-struct-return is specified. ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default) CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. +CODEGENOPT(PointerTBAA, 1, 0) ///< Whether or not to use distinct TBAA tags for pointers. CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-path TBAA. CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. @@ -306,6 +315,7 @@ 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. VALUE_CODEGENOPT(UnwindTables, 2, 0) ///< Unwind tables (1) or asynchronous unwind tables (2) +CODEGENOPT(LinkBitcodePostopt, 1, 0) ///< Link builtin bitcodes after optimization pipeline. CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer. CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer. CODEGENOPT(ProfileSampleAccurate, 1, 0) ///< Sample profile is accurate. diff --git a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h index 3f8fe385fef..f2a707a8ba8 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h +++ b/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_BASIC_CODEGENOPTIONS_H #define LLVM_CLANG_BASIC_CODEGENOPTIONS_H +#include "clang/Basic/PointerAuthOptions.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/XRayInstr.h" #include "llvm/ADT/FloatingPointMode.h" @@ -127,15 +128,18 @@ public: std::string BinutilsVersion; enum class FramePointerKind { - None, // Omit all frame pointers. - NonLeaf, // Keep non-leaf frame pointers. - All, // Keep all frame pointers. + None, // Omit all frame pointers. + Reserved, // Maintain valid frame pointer chain. + NonLeaf, // Keep non-leaf frame pointers. + All, // Keep all frame pointers. }; static StringRef getFramePointerKindName(FramePointerKind Kind) { switch (Kind) { case FramePointerKind::None: return "none"; + case FramePointerKind::Reserved: + return "reserved"; case FramePointerKind::NonLeaf: return "non-leaf"; case FramePointerKind::All: @@ -388,6 +392,9 @@ public: std::vector Reciprocals; + /// Configuration for pointer-signing. + PointerAuthOptions PointerAuth; + /// The preferred width for auto-vectorization transforms. This is intended to /// override default transforms based on the width of the architected vector /// registers. @@ -404,6 +411,12 @@ public: /// List of pass builder callbacks. std::vector> PassBuilderCallbacks; + /// List of global variables explicitly specified by the user as toc-data. + std::vector TocDataVarsUserSpecified; + + /// List of global variables that over-ride the toc-data default. + std::vector NoTocDataVars; + /// Path to allowlist file specifying which objects /// (files, functions) should exclusively be instrumented /// by sanitizer coverage pass. diff --git a/contrib/llvm-project/clang/include/clang/Basic/Cuda.h b/contrib/llvm-project/clang/include/clang/Basic/Cuda.h index 916cb4b7ef3..83699f8897f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Cuda.h +++ b/contrib/llvm-project/clang/include/clang/Basic/Cuda.h @@ -41,22 +41,26 @@ enum class CudaVersion { CUDA_121, CUDA_122, CUDA_123, + CUDA_124, + CUDA_125, FULLY_SUPPORTED = CUDA_123, PARTIALLY_SUPPORTED = - CUDA_123, // Partially supported. Proceed with a warning. + CUDA_125, // Partially supported. Proceed with a warning. NEW = 10000, // Too new. Issue a warning, but allow using it. }; const char *CudaVersionToString(CudaVersion V); // Input is "Major.Minor" CudaVersion CudaStringToVersion(const llvm::Twine &S); -enum class CudaArch { +enum class OffloadArch { UNUSED, UNKNOWN, + // TODO: Deprecate and remove GPU architectures older than sm_52. SM_20, SM_21, SM_30, - SM_32, + // This has a name conflict with sys/mac.h on AIX, rename it as a workaround. + SM_32_, SM_35, SM_37, SM_50, @@ -88,6 +92,7 @@ enum class CudaArch { GFX803, GFX805, GFX810, + GFX9_GENERIC, GFX900, GFX902, GFX904, @@ -99,10 +104,12 @@ enum class CudaArch { GFX940, GFX941, GFX942, + GFX10_1_GENERIC, GFX1010, GFX1011, GFX1012, GFX1013, + GFX10_3_GENERIC, GFX1030, GFX1031, GFX1032, @@ -110,42 +117,54 @@ enum class CudaArch { GFX1034, GFX1035, GFX1036, + GFX11_GENERIC, GFX1100, GFX1101, GFX1102, GFX1103, GFX1150, GFX1151, + GFX1152, + GFX12_GENERIC, GFX1200, GFX1201, + AMDGCNSPIRV, Generic, // A processor model named 'generic' if the target backend defines a // public one. LAST, - CudaDefault = CudaArch::SM_52, - HIPDefault = CudaArch::GFX803, + CudaDefault = OffloadArch::SM_52, + HIPDefault = OffloadArch::GFX906, }; -static inline bool IsNVIDIAGpuArch(CudaArch A) { - return A >= CudaArch::SM_20 && A < CudaArch::GFX600; +enum class CUDAFunctionTarget { + Device, + Global, + Host, + HostDevice, + InvalidTarget +}; + +static inline bool IsNVIDIAOffloadArch(OffloadArch A) { + return A >= OffloadArch::SM_20 && A < OffloadArch::GFX600; } -static inline bool IsAMDGpuArch(CudaArch A) { +static inline bool IsAMDOffloadArch(OffloadArch A) { // Generic processor model is for testing only. - return A >= CudaArch::GFX600 && A < CudaArch::Generic; + return A >= OffloadArch::GFX600 && A < OffloadArch::Generic; } -const char *CudaArchToString(CudaArch A); -const char *CudaArchToVirtualArchString(CudaArch A); +const char *OffloadArchToString(OffloadArch A); +const char *OffloadArchToVirtualArchString(OffloadArch A); // The input should have the form "sm_20". -CudaArch StringToCudaArch(llvm::StringRef S); +OffloadArch StringToOffloadArch(llvm::StringRef S); -/// Get the earliest CudaVersion that supports the given CudaArch. -CudaVersion MinVersionForCudaArch(CudaArch A); +/// Get the earliest CudaVersion that supports the given OffloadArch. +CudaVersion MinVersionForOffloadArch(OffloadArch A); -/// Get the latest CudaVersion that supports the given CudaArch. -CudaVersion MaxVersionForCudaArch(CudaArch A); +/// Get the latest CudaVersion that supports the given OffloadArch. +CudaVersion MaxVersionForOffloadArch(OffloadArch A); // Various SDK-dependent features that affect CUDA compilation enum class CudaFeature { diff --git a/contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h b/contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h index 84d40025ee4..2d6ae6a781a 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h +++ b/contrib/llvm-project/clang/include/clang/Basic/CustomizableOptional.h @@ -97,14 +97,6 @@ public: template T value_or(U &&alt) && { return has_value() ? std::move(operator*()) : std::forward(alt); } - - // Allow conversion to std::optional. - explicit operator std::optional &() const & { - return *this ? **this : std::optional(); - } - explicit operator std::optional &&() const && { - return *this ? std::move(**this) : std::optional(); - } }; template diff --git a/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h b/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h index dedfbd934a7..db20b968a89 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h +++ b/contrib/llvm-project/clang/include/clang/Basic/DarwinSDKInfo.h @@ -105,6 +105,30 @@ public: map(const VersionTuple &Key, const VersionTuple &MinimumValue, std::optional MaximumValue) const; + /// Remap the 'introduced' availability version. + /// If None is returned, the 'unavailable' availability should be used + /// instead. + std::optional + mapIntroducedAvailabilityVersion(const VersionTuple &Key) const { + // API_TO_BE_DEPRECATED is 100000. + if (Key.getMajor() == 100000) + return VersionTuple(100000); + // Use None for maximum to force unavailable behavior for + return map(Key, MinimumValue, std::nullopt); + } + + /// Remap the 'deprecated' and 'obsoleted' availability version. + /// If None is returned for 'obsoleted', the 'unavailable' availability + /// should be used instead. If None is returned for 'deprecated', the + /// 'deprecated' version should be dropped. + std::optional + mapDeprecatedObsoletedAvailabilityVersion(const VersionTuple &Key) const { + // API_TO_BE_DEPRECATED is 100000. + if (Key.getMajor() == 100000) + return VersionTuple(100000); + return map(Key, MinimumValue, MaximumValue); + } + static std::optional parseJSON(const llvm::json::Object &Obj, VersionTuple MaximumDeploymentTarget); diff --git a/contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def b/contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def index 7cd3edf08a1..bc96d5dfdf8 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def +++ b/contrib/llvm-project/clang/include/clang/Basic/DebugOptions.def @@ -68,6 +68,8 @@ BENIGN_DEBUGOPT(NoInlineLineTables, 1, 0) ///< Whether debug info should contain ///< inline line tables. DEBUGOPT(DebugStrictDwarf, 1, 1) ///< Whether or not to use strict DWARF info. +DEBUGOPT(DebugOmitUnreferencedMethods, 1, 0) ///< Omit unreferenced member + ///< functions in type debug info. /// Control the Assignment Tracking debug info feature. BENIGN_ENUM_DEBUGOPT(AssignmentTrackingMode, AssignmentTrackingOpts, 2, @@ -129,6 +131,9 @@ DEBUGOPT(CodeViewCommandLine, 1, 0) /// Whether emit extra debug info for sample pgo profile collection. DEBUGOPT(DebugInfoForProfiling, 1, 0) +/// Whether to emit DW_TAG_template_alias for template aliases. +DEBUGOPT(DebugTemplateAlias, 1, 0) + /// Whether to emit .debug_gnu_pubnames section instead of .debug_pubnames. DEBUGOPT(DebugNameTable, 2, 0) diff --git a/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td b/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td index 8b1f415dd5f..48396e85c5a 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td @@ -95,7 +95,7 @@ def LinkageSpec : DeclNode, DeclContext; def Export : DeclNode, DeclContext; def ObjCPropertyImpl : DeclNode; def FileScopeAsm : DeclNode; -def TopLevelStmt : DeclNode; +def TopLevelStmt : DeclNode, DeclContext; def AccessSpec : DeclNode; def Friend : DeclNode; def FriendTemplate : DeclNode; diff --git a/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td b/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td index 8d66e265fba..0b8b3af939b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td +++ b/contrib/llvm-project/clang/include/clang/Basic/Diagnostic.td @@ -162,6 +162,7 @@ include "DiagnosticCommonKinds.td" include "DiagnosticCrossTUKinds.td" include "DiagnosticDriverKinds.td" include "DiagnosticFrontendKinds.td" +include "DiagnosticInstallAPIKinds.td" include "DiagnosticLexKinds.td" include "DiagnosticParseKinds.td" include "DiagnosticRefactoringKinds.td" diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td index c81d17ed641..a024f9b2a9f 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -399,6 +399,8 @@ def note_constexpr_unsupported_flexible_array : Note< "flexible array initialization is not yet supported">; def note_constexpr_non_const_vectorelements : Note< "cannot determine number of elements for sizeless vectors in a constant expression">; +def note_constexpr_assumption_failed : Note< + "assumption evaluated to false">; def err_experimental_clang_interp_failed : Error< "the experimental clang interpreter failed to evaluate an expression">; diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td index 08bb1d81ba2..33b1d58bb5b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -45,6 +45,11 @@ def note_using : Note<"using">; def note_possibility : Note<"one possibility">; def note_also_found : Note<"also found">; +def warn_next_larger_fp_type_same_size_than_fp : Warning< + "higher precision floating-point type size has the same size than " + "floating-point type size">, + InGroup>; + // Parse && Lex let CategoryName = "Lexical or Preprocessor Issue" in { @@ -229,6 +234,9 @@ def err_cxx23_size_t_suffix: Error< def err_size_t_literal_too_large: Error< "%select{signed |}0'size_t' literal is out of range of possible " "%select{signed |}0'size_t' values">; +def ext_cxx_bitint_suffix : Extension< + "'_BitInt' suffix for literals is a Clang extension">, + InGroup; def ext_c23_bitint_suffix : ExtWarn< "'_BitInt' suffix for literals is a C23 extension">, InGroup; @@ -267,6 +275,9 @@ def err_too_large_for_fixed_point : Error< def err_unimplemented_conversion_with_fixed_point_type : Error< "conversion between fixed point and %0 is not yet supported">; +def err_requires_positive_value : Error< + "%select{invalid value '%0'; must be positive|value '%0' is too large}1">; + // SEH def err_seh_expected_handler : Error< "expected '__except' or '__finally' block">; @@ -353,9 +364,17 @@ def warn_invalid_feature_combination : Warning< def warn_target_unrecognized_env : Warning< "mismatch between architecture and environment in target triple '%0'; did you mean '%1'?">, InGroup; -def warn_knl_knm_isa_support_removed : Warning< - "KNL, KNM related Intel Xeon Phi CPU's specific ISA's supports will be removed in LLVM 19.">, - InGroup>; +def err_target_unsupported_abi_with_fpu : Error< + "'%0' ABI is not supported with FPU">; + +def err_ppc_impossible_musttail: Error< + "'musttail' attribute for this call is impossible because %select{" + "long calls can not be tail called on PPC|" + "indirect calls can not be tail called on PPC|" + "external calls can not be tail called on PPC}0" + >; +def err_aix_musttail_unsupported: Error< + "'musttail' attribute is not supported on AIX">; // Source manager def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal; diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td index 094fe195094..3d8240f8357 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -57,6 +57,8 @@ def warn_drv_avr_stdlib_not_linked: Warning< InGroup; def err_drv_cuda_bad_gpu_arch : Error<"unsupported CUDA gpu architecture: %0">; def err_drv_offload_bad_gpu_arch : Error<"unsupported %0 gpu architecture: %1">; +def err_drv_offload_missing_gpu_arch : Error< + "must pass in an explicit %0 gpu architecture to '%1'">; def err_drv_no_cuda_installation : Error< "cannot find CUDA installation; provide its path via '--cuda-path', or pass " "'-nocudainc' to build without CUDA includes">; @@ -88,9 +90,13 @@ def err_drv_no_hipspv_device_lib : Error< "'--hip-path' or '--hip-device-lib-path', or pass '-nogpulib' to build " "without HIP device library">; def err_drv_hipspv_no_hip_path : Error< - "'--hip-path' must be specified when offloading to " - "SPIR-V%select{| unless %1 is given}0.">; + "'--hip-path' must be specified when offloading to SPIR-V unless '-nogpuinc' " + "is given">; +// TODO: Remove when COV6 is fully supported by ROCm. +def warn_drv_amdgpu_cov6: Warning< + "code object v6 is still in development and not ready for production use yet;" + " use at your own risk">; def err_drv_undetermined_gpu_arch : Error< "cannot determine %0 architecture: %1; consider passing it via " "'%2'">; @@ -131,11 +137,14 @@ def warn_drv_unsupported_option_for_flang : Warning< "the argument '%0' is not supported for option '%1'. Mapping to '%1%2'">, InGroup; def warn_drv_unsupported_diag_option_for_flang : Warning< - "The warning option '-%0' is not supported">, + "the warning option '-%0' is not supported">, InGroup; def warn_drv_unsupported_option_for_processor : Warning< "ignoring '%0' option as it is not currently supported for processor '%1'">, InGroup; +def warn_drv_unsupported_openmp_library : Warning< + "the library '%0=%1' is not supported, OpenMP will not be enabled">, + InGroup; def err_drv_invalid_thread_model_for_target : Error< "invalid thread model '%0' in '%1' for this target">; @@ -147,6 +156,8 @@ def err_drv_unsupported_rtlib_for_platform : Error< "unsupported runtime library '%0' for platform '%1'">; def err_drv_invalid_unwindlib_name : Error< "invalid unwind library name in argument '%0'">; +def err_drv_unsupported_unwind_for_platform : Error< + "unsupported unwind library '%0' for platform '%1'">; def err_drv_incompatible_unwindlib : Error< "--rtlib=libgcc requires --unwindlib=libgcc">; def err_drv_incompatible_options : Error< @@ -347,7 +358,7 @@ def err_drv_expecting_fopenmp_with_fopenmp_targets : Error< "compatible with offloading; e.g., '-fopenmp=libomp' or '-fopenmp=libiomp5'">; def err_drv_failed_to_deduce_target_from_arch : Error< "failed to deduce triple for target architecture '%0'; specify the triple " - "using '-fopenmp-targets' and '-Xopenmp-target' instead.">; + "using '-fopenmp-targets' and '-Xopenmp-target' instead">; def err_drv_omp_offload_target_missingbcruntime : Error< "no library '%0' found in the default clang lib directory or in LIBRARY_PATH" "; use '--libomptarget-%1-bc-path' to specify %1 bitcode library">; @@ -366,6 +377,9 @@ def err_drv_negative_columns : Error< "invalid value '%1' in '%0', value must be 'none' or a positive integer">; def err_drv_small_columns : Error< "invalid value '%1' in '%0', value must be '%2' or greater">; +def warn_drv_fraw_string_literals_in_cxx11 : Warning< + "ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C and C++ standards before C++11">, + InGroup; def err_drv_invalid_malign_branch_EQ : Error< "invalid argument '%0' to -malign-branch=; each element must be one of: %1">; @@ -426,7 +440,14 @@ def warn_drv_diagnostics_misexpect_requires_pgo : Warning< def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; def warn_drv_deprecated_arg : Warning< - "argument '%0' is deprecated, use '%1' instead">, InGroup; + "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">, + InGroup; def warn_drv_deprecated_custom : Warning< "argument '%0' is deprecated, %1">, InGroup; def warn_drv_assuming_mfloat_abi_is : Warning< @@ -503,14 +524,6 @@ def err_analyzer_checker_incompatible_analyzer_option : Error< def err_analyzer_not_built_with_z3 : Error< "analyzer constraint manager 'z3' is only available if LLVM was built with " "-DLLVM_ENABLE_Z3_SOLVER=ON">; -def warn_analyzer_deprecated_option : Warning< - "analyzer option '%0' is deprecated. This flag will be removed in %1, and " - "passing this option will be an error.">, - InGroup; -def warn_analyzer_deprecated_option_with_alternative : Warning< - "analyzer option '%0' is deprecated. This flag will be removed in %1, and " - "passing this option will be an error. Use '%2' instead.">, - InGroup; def warn_drv_needs_hvx : Warning< "%0 requires HVX, use -mhvx/-mhvx= to enable it">, @@ -542,6 +555,14 @@ def err_drv_extract_api_wrong_kind : Error< "header file '%0' input '%1' does not match the type of prior input " "in api extraction; use '-x %2' to override">; +def err_drv_missing_symbol_graph_dir: Error< + "must provide a symbol graph output directory using " + "'--symbol-graph-dir='">; + +def err_drv_unexpected_symbol_graph_output : Error< + "unexpected output symbol graph '%1'; please provide " + "'--symbol-graph-dir=' instead">; + def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">, InGroup>; def note_use_dashdash : Note< @@ -648,6 +669,7 @@ def warn_drv_darwin_sdk_invalid_settings : Warning< "SDK settings were ignored as 'SDKSettings.json' could not be parsed">, InGroup>; +def err_missing_sysroot : Error<"no such sysroot directory: '%0'">; def err_drv_darwin_sdk_missing_arclite : Error< "SDK does not contain 'libarclite' at the path '%0'; try increasing the minimum deployment target">; @@ -687,7 +709,6 @@ def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">; def err_drv_invalid_object_mode : Error< "OBJECT_MODE setting %0 is not recognized and is not a valid setting">; -def err_aix_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">; def err_roptr_requires_data_sections: Error<"-mxcoff-roptr is supported only with -fdata-sections">; def err_roptr_cannot_build_shared: Error<"-mxcoff-roptr is not supported with -shared">; @@ -745,22 +766,23 @@ def err_drv_hlsl_unsupported_target : Error< "HLSL code generation is unsupported for target '%0'">; def err_drv_hlsl_bad_shader_required_in_target : Error< "%select{shader model|Vulkan environment|shader stage}0 is required as %select{OS|environment}1 in target '%2' for HLSL code generation">; - +def err_drv_hlsl_16bit_types_unsupported: Error< + "'%0' option requires target HLSL Version >= 2018%select{| and shader model >= 6.2}1, but HLSL Version is '%2'%select{| and shader model is '%3'}1">; def err_drv_hlsl_bad_shader_unsupported : Error< "%select{shader model|Vulkan environment|shader stage}0 '%1' in target '%2' is invalid for HLSL code generation">; -def warn_drv_dxc_missing_dxv : Warning<"dxv not found. " - "Resulting DXIL will not be validated or signed for use in release environments.">, - InGroup; +def warn_drv_dxc_missing_dxv : Warning< + "dxv not found; resulting DXIL will not be validated or signed for use in " + "release environment">, InGroup; def err_drv_invalid_range_dxil_validator_version : Error< - "invalid validator version : %0\n" - "Validator version must be less than or equal to current internal version.">; + "invalid validator version : %0; validator version must be less than or " + "equal to current internal version">; def err_drv_invalid_format_dxil_validator_version : Error< - "invalid validator version : %0\n" - "Format of validator version is \".\" (ex:\"1.4\").">; + "invalid validator version : %0; format of validator version is " + "\".\" (ex:\"1.4\")">; def err_drv_invalid_empty_dxil_validator_version : Error< - "invalid validator version : %0\n" - "If validator major version is 0, minor version must also be 0.">; + "invalid validator version : %0; if validator major version is 0, minor " + "version must also be 0">; def warn_drv_sarif_format_unstable : Warning< "diagnostic formatting in SARIF mode is currently unstable">, @@ -774,12 +796,12 @@ def warn_drv_loongarch_conflicting_implied_val : Warning< InGroup; def err_drv_loongarch_invalid_mfpu_EQ : Error< "invalid argument '%0' to -mfpu=; must be one of: 64, 32, none, 0 (alias for none)">; -def err_drv_loongarch_wrong_fpu_width_for_lsx : Error< - "wrong fpu width; LSX depends on 64-bit FPU.">; -def err_drv_loongarch_wrong_fpu_width_for_lasx : Error< - "wrong fpu width; LASX depends on 64-bit FPU.">; +def err_drv_loongarch_wrong_fpu_width : Error< + "wrong fpu width; %select{LSX|LASX}0 depends on 64-bit FPU">; def err_drv_loongarch_invalid_simd_option_combination : Error< - "invalid option combination; LASX depends on LSX.">; + "invalid option combination; LASX depends on LSX">; +def err_drv_loongarch_invalid_msimd_EQ : Error< + "invalid argument '%0' to -msimd=; must be one of: none, lsx, lasx">; def err_drv_expand_response_file : Error< "failed to expand response file: %0">; @@ -790,12 +812,19 @@ def warn_drv_missing_multilib : Warning< def note_drv_available_multilibs : Note< "available multilibs are:%0">; +def err_drv_experimental_crel : Error< + "-Wa,--allow-experimental-crel must be specified to use -Wa,--crel. " + "CREL is experimental and uses a non-standard section type code">; + def warn_android_unversioned_fallback : Warning< - "Using unversioned Android target directory %0 for target %1. Unversioned" - " directories will not be used in Clang 19. Provide a versioned directory" - " for the target version or lower instead.">, + "using unversioned Android target directory %0 for target %1; unversioned " + "directories will not be used in Clang 19 -- provide a versioned directory " + "for the target version or lower instead">, InGroup>; def err_drv_triple_version_invalid : Error< "version '%0' in target triple '%1' is invalid">; + +def warn_missing_include_dirs : Warning< + "no such include directory: '%0'">, InGroup, DefaultIgnore; } diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 85ecfdf9de6..12a4617c64d 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -71,14 +71,14 @@ def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo, InGroup; def remark_fe_backend_optimization_remark_analysis_fpcommute : Remark<"%0; " "allow reordering by specifying '#pragma clang loop vectorize(enable)' " - "before the loop or by providing the compiler option '-ffast-math'.">, + "before the loop or by providing the compiler option '-ffast-math'">, BackendInfo, InGroup; def remark_fe_backend_optimization_remark_analysis_aliasing : Remark<"%0; " "allow reordering by specifying '#pragma clang loop vectorize(enable)' " - "before the loop. If the arrays will always be independent specify " + "before the loop; if the arrays will always be independent, specify " "'#pragma clang loop vectorize(assume_safety)' before the loop or provide " - "the '__restrict__' qualifier with the independent array arguments. " - "Erroneous results will occur if these options are incorrectly applied!">, + "the '__restrict__' qualifier with the independent array arguments -- " + "erroneous results will occur if these options are incorrectly applied">, BackendInfo, InGroup; def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo, @@ -94,6 +94,8 @@ def err_fe_backend_error_attr : def warn_fe_backend_warning_attr : Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo, InGroup; +def warn_toc_unsupported_type : Warning<"-mtocdata option is ignored " + "for %0 because %1">, InGroup; def err_fe_invalid_code_complete_file : Error< "cannot locate code-completion file %0">, DefaultFatal; @@ -132,6 +134,8 @@ def err_fe_no_pch_in_dir : Error< "no suitable precompiled header file found in directory '%0'">; def err_fe_action_not_available : Error< "action %0 not compiled in">; +def err_fe_invalid_multiple_actions : Error< + "'%0' action ignored; '%1' action specified previously">; def err_fe_invalid_alignment : Error< "invalid value '%1' in '%0'; alignment must be a power of 2">; def err_fe_invalid_exception_model @@ -148,8 +152,8 @@ def warn_fe_serialized_diag_merge_failure : Warning< def warn_fe_serialized_diag_failure : Warning< "unable to open file %0 for serializing diagnostics (%1)">, InGroup; -def warn_fe_serialized_diag_failure_during_finalisation : Warning< - "Received warning after diagnostic serialization teardown was underway: %0">, +def warn_fe_serialized_diag_failure_during_finalization : Warning< + "received warning after diagnostic serialization teardown was underway: %0">, InGroup; def err_verify_missing_line : Error< @@ -176,10 +180,10 @@ def err_verify_inconsistent_diags : Error< "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: " "%2">; def err_verify_invalid_no_diags : Error< - "%select{expected|'expected-no-diagnostics'}0 directive cannot follow " - "%select{'expected-no-diagnostics' directive|other expected directives}0">; + "%select{expected|'%0-no-diagnostics'}1 directive cannot follow " + "%select{'%0-no-diagnostics' directive|other expected directives}1">; def err_verify_no_directives : Error< - "no expected directives found: consider use of 'expected-no-diagnostics'">; + "no expected directives found: consider use of '%0-no-diagnostics'">; def err_verify_nonconst_addrspace : Error< "qualifier 'const' is needed for variables in address space '%0'">; @@ -222,6 +226,7 @@ def err_module_map_not_found : Error<"module map file '%0' not found">, def err_missing_module_name : Error< "no module name provided; specify one with -fmodule-name=">, DefaultFatal; +def err_file_is_not_module : Error<"file '%0' is not a module file">, DefaultFatal; def err_missing_module : Error< "no module named '%0' declared in module map file '%1'">, DefaultFatal; def err_no_submodule : Error<"no submodule named %0 in module '%1'">; @@ -280,12 +285,22 @@ def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +let CategoryName = "Codegen ABI Check" in { +def err_function_always_inline_attribute_mismatch : Error< + "always_inline function %1 and its caller %0 have mismatching %2 attributes">; +def err_function_always_inline_new_za : Error< + "always_inline function %0 has new za state">; + def warn_avx_calling_convention : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' " "enabled changes the ABI">, InGroup>; def err_avx_calling_convention : Error; +def err_target_unsupported_type_for_abi + : Error<"%0 requires %1 type support, but ABI '%2' does not support it">; +} + def err_alias_to_undefined : Error< "%select{alias|ifunc}0 must point to a defined " "%select{variable or |}1function">; @@ -323,7 +338,7 @@ def warn_atomic_op_oversized : Warning< InGroup; def warn_sync_op_misaligned : Warning< - "__sync builtin operation MUST have natural alignment (consider using __atomic).">, + "__sync builtin operation must have natural alignment (consider using __atomic)">, InGroup; def warn_alias_with_section : Warning< @@ -345,13 +360,19 @@ def warn_profile_data_unprofiled : Warning< "no profile data available for file \"%0\"">, InGroup; def warn_profile_data_misexpect : Warning< - "Potential performance regression from use of __builtin_expect(): " - "Annotation was correct on %0 of profiled executions.">, - BackendInfo, - InGroup; + "potential performance regression from use of __builtin_expect(): " + "annotation was correct on %0 of profiled executions">, + BackendInfo, InGroup; } // end of instrumentation issue category def err_extract_api_ignores_file_not_found : Error<"file '%0' specified by '--extract-api-ignores=' not found">, DefaultFatal; +def warn_missing_symbol_graph_dir : Warning< + "missing symbol graph output directory, defaulting to working directory">, + InGroup; + +def err_ast_action_on_llvm_ir : Error< + "cannot apply AST actions to LLVM IR file '%0'">, + DefaultFatal; } diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td index 6765721ae70..19c3f1e0433 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticGroups.td @@ -15,8 +15,6 @@ def Implicit : DiagGroup<"implicit", [ ImplicitInt ]>; -def DeprecatedStaticAnalyzerFlag : DiagGroup<"deprecated-static-analyzer-flag">; - // Empty DiagGroups are recognized by clang but ignored. def ODR : DiagGroup<"odr">; def : DiagGroup<"abi">; @@ -44,10 +42,8 @@ def DeprecatedModuleDotMap : DiagGroup<"deprecated-module-dot-map">; def FrameworkHdrAtImport : DiagGroup<"atimport-in-framework-header">; def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">; def CXXPre14CompatBinaryLiteral : DiagGroup<"c++98-c++11-compat-binary-literal">; -def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">; def BinaryLiteral : DiagGroup<"binary-literal", [CXX14BinaryLiteral, - CXXPre14CompatBinaryLiteral, - GNUBinaryLiteral]>; + CXXPre14CompatBinaryLiteral]>; def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">; def SingleBitBitFieldConstantConversion : DiagGroup<"single-bit-bitfield-constant-conversion">; @@ -106,10 +102,14 @@ 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">; +def Shorten64To32 : DiagGroup<"shorten-64-to-32">; def ImplicitIntConversion : DiagGroup<"implicit-int-conversion", - [ObjCSignedCharBoolImplicitIntConversion]>; + [Shorten64To32, + ObjCSignedCharBoolImplicitIntConversion]>; def ImplicitConstIntFloatConversion : DiagGroup<"implicit-const-int-float-conversion">; def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion", [ImplicitConstIntFloatConversion]>; @@ -228,6 +228,8 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion, DeprecatedLiteralOperator, DeprecatedPragma, DeprecatedRegister, + DeprecatedNoRelaxedTemplateTemplateArgs, + DeprecatedOFast, DeprecatedThisCapture, DeprecatedType, DeprecatedVolatile, @@ -290,12 +292,19 @@ def : DiagGroup<"c++1z-compat-mangling", [CXX17CompatMangling]>; def NoexceptType : DiagGroup<"noexcept-type", [CXX17CompatMangling]>; // Warnings for C code which is not compatible with previous C standards. +def CPre11Compat : DiagGroup<"pre-c11-compat">; +def CPre11CompatPedantic : DiagGroup<"pre-c11-compat-pedantic", + [CPre11Compat]>; def CPre23Compat : DiagGroup<"pre-c23-compat">; def CPre23CompatPedantic : DiagGroup<"pre-c23-compat-pedantic", [CPre23Compat]>; def : DiagGroup<"pre-c2x-compat", [CPre23Compat]>; def : DiagGroup<"pre-c2x-compat-pedantic", [CPre23CompatPedantic]>; +def CPre2yCompat : DiagGroup<"pre-c2y-compat">; +def CPre2yCompatPedantic : DiagGroup<"pre-c2y-compat-pedantic", + [CPre2yCompat]>; + // Warnings for C++ code which is not compatible with previous C++ standards. def CXXPre14Compat : DiagGroup<"pre-c++14-compat">; def : DiagGroup<"c++98-c++11-compat", [CXXPre14Compat]>; @@ -337,7 +346,8 @@ def CXX98Compat : DiagGroup<"c++98-compat", CXXPre14Compat, CXXPre17Compat, CXXPre20Compat, - CXXPre23Compat]>; + CXXPre23Compat, + CXXPre26Compat]>; // Warnings for C++11 features which are Extensions in C++98 mode. def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat, @@ -346,7 +356,8 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", CXXPre14CompatPedantic, CXXPre17CompatPedantic, CXXPre20CompatPedantic, - CXXPre23CompatPedantic]>; + CXXPre23CompatPedantic, + CXXPre26CompatPedantic]>; def CXX11NarrowingConstReference : DiagGroup<"c++11-narrowing-const-reference">; def CXX11Narrowing : DiagGroup<"c++11-narrowing", [CXX11NarrowingConstReference]>; @@ -377,42 +388,54 @@ def CXX11Compat : DiagGroup<"c++11-compat", CXXPre14Compat, CXXPre17Compat, CXXPre20Compat, - CXXPre23Compat]>; + CXXPre23Compat, + CXXPre26Compat]>; def : DiagGroup<"c++0x-compat", [CXX11Compat]>; def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic", [CXX11Compat, CXXPre14CompatPedantic, CXXPre17CompatPedantic, CXXPre20CompatPedantic, - CXXPre23CompatPedantic]>; + CXXPre23CompatPedantic, + CXXPre26CompatPedantic]>; def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat, CXXPre20Compat, - CXXPre23Compat]>; + CXXPre23Compat, + CXXPre26Compat]>; def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic", [CXX14Compat, CXXPre17CompatPedantic, CXXPre20CompatPedantic, - CXXPre23CompatPedantic]>; + CXXPre23CompatPedantic, + CXXPre26CompatPedantic]>; def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister, DeprecatedIncrementBool, CXX17CompatMangling, CXXPre20Compat, - CXXPre23Compat]>; + CXXPre23Compat, + CXXPre26Compat]>; def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic", [CXX17Compat, CXXPre20CompatPedantic, - CXXPre23CompatPedantic]>; + CXXPre23CompatPedantic, + CXXPre26CompatPedantic]>; def : DiagGroup<"c++1z-compat", [CXX17Compat]>; -def CXX20Compat : DiagGroup<"c++20-compat", [CXXPre23Compat]>; +def CXX20Compat : DiagGroup<"c++20-compat", [CXXPre23Compat, + CXXPre26Compat]>; def CXX20CompatPedantic : DiagGroup<"c++20-compat-pedantic", [CXX20Compat, - CXXPre23CompatPedantic]>; + CXXPre23CompatPedantic, + CXXPre26CompatPedantic]>; def : DiagGroup<"c++2a-compat", [CXX20Compat]>; def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>; +def CXX23Compat : DiagGroup<"c++23-compat", [CXXPre26Compat]>; + +def CXX26Compat : DiagGroup<"c++2c-compat", [DeleteIncomplete]>; + def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">; def FourByteMultiChar : DiagGroup<"four-char-constants">; @@ -427,6 +450,8 @@ def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">; def LogicalNotParentheses: DiagGroup<"logical-not-parentheses">; def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">; def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">; +def DanglingAssignment: DiagGroup<"dangling-assignment">; +def DanglingAssignmentGsl : DiagGroup<"dangling-assignment-gsl">; def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DanglingInitializerList : DiagGroup<"dangling-initializer-list">; @@ -434,7 +459,9 @@ def DanglingGsl : DiagGroup<"dangling-gsl">; def ReturnStackAddress : DiagGroup<"return-stack-address">; // Name of this warning in GCC def : DiagGroup<"return-local-addr", [ReturnStackAddress]>; -def Dangling : DiagGroup<"dangling", [DanglingField, +def Dangling : DiagGroup<"dangling", [DanglingAssignment, + DanglingAssignmentGsl, + DanglingField, DanglingInitializerList, DanglingGsl, ReturnStackAddress]>; @@ -503,7 +530,7 @@ def MaxUnsignedZero : DiagGroup<"max-unsigned-zero">; def MissingBraces : DiagGroup<"missing-braces">; def MissingDeclarations: DiagGroup<"missing-declarations">; def : DiagGroup<"missing-format-attribute">; -def : DiagGroup<"missing-include-dirs">; +def MissingIncludeDirs : DiagGroup<"missing-include-dirs">; def MissingNoreturn : DiagGroup<"missing-noreturn">; def MultiChar : DiagGroup<"multichar">; def : DiagGroup<"nested-externs">; @@ -514,7 +541,15 @@ def MethodSignatures : DiagGroup<"method-signatures">; def MismatchedParameterTypes : DiagGroup<"mismatched-parameter-types">; def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">; def MismatchedTags : DiagGroup<"mismatched-tags">; -def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; +def MissingDesignatedFieldInitializers : DiagGroup<"missing-designated-field-initializers">{ + code Documentation = [{ +Warn about designated initializers with some fields missing (only in C++). + }]; +} +// Default -Wmissing-field-initializers matches gcc behavior, +// but missing-designated-field-initializers can be turned off to match old clang behavior. +def MissingFieldInitializers : DiagGroup<"missing-field-initializers", + [MissingDesignatedFieldInitializers]>; def ModuleLock : DiagGroup<"module-lock">; def ModuleBuild : DiagGroup<"module-build">; def ModuleImport : DiagGroup<"module-import">; @@ -562,7 +597,10 @@ def SelTypeCast : DiagGroup<"cast-of-sel-type">; def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">; def BadFunctionCast : DiagGroup<"bad-function-cast">; def CastFunctionTypeStrict : DiagGroup<"cast-function-type-strict">; -def CastFunctionType : DiagGroup<"cast-function-type", [CastFunctionTypeStrict]>; +def CastFunctionTypeMismatch : DiagGroup<"cast-function-type-mismatch">; +def CastFunctionType : DiagGroup<"cast-function-type", + [CastFunctionTypeStrict, + CastFunctionTypeMismatch]>; def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">; def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">; def ObjCPropertyAssignOnObjectType : DiagGroup<"objc-property-assign-on-object-type">; @@ -606,7 +644,9 @@ def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">; def RedundantMove : DiagGroup<"redundant-move">; def Register : DiagGroup<"register", [DeprecatedRegister]>; def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">; -def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>; +def ReturnMismatch : DiagGroup<"return-mismatch">; +def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage, ReturnMismatch]>; + def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy", [CXX98CompatBindToTemporaryCopy]>; def SelfAssignmentField : DiagGroup<"self-assign-field">; @@ -631,7 +671,6 @@ def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified, def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor, ShadowUncapturedLocal, ShadowField]>; -def Shorten64To32 : DiagGroup<"shorten-64-to-32">; def : DiagGroup<"sign-promo">; def SignCompare : DiagGroup<"sign-compare">; def SwitchDefault : DiagGroup<"switch-default">; @@ -863,6 +902,7 @@ def ZeroLengthArray : DiagGroup<"zero-length-array">; def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">; def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">; def MisleadingIndentation : DiagGroup<"misleading-indentation">; +def PtrAuthNullPointers : DiagGroup<"ptrauth-null-pointers">; // This covers both the deprecated case (in C++98) // and the extension case (in C++11 onwards). @@ -942,7 +982,6 @@ def Conversion : DiagGroup<"conversion", EnumConversion, BitFieldEnumConversion, FloatConversion, - Shorten64To32, IntConversion, ImplicitIntConversion, ImplicitFloatConversion, @@ -970,6 +1009,7 @@ def FormatSecurity : DiagGroup<"format-security">; def FormatNonStandard : DiagGroup<"format-non-iso">; def FormatY2K : DiagGroup<"format-y2k">; def FormatPedantic : DiagGroup<"format-pedantic">; +def FormatSignedness : DiagGroup<"format-signedness">; def FormatTypeConfusion : DiagGroup<"format-type-confusion">; def FormatOverflowNonKprintf: DiagGroup<"format-overflow-non-kprintf">; @@ -1026,6 +1066,7 @@ def Extra : DiagGroup<"extra", [ EmptyInitStatement, StringConcatation, FUseLdPath, + CastFunctionTypeMismatch, ]>; def Most : DiagGroup<"most", [ @@ -1124,9 +1165,11 @@ def NonGCC : DiagGroup<"non-gcc", def CXX14Attrs : DiagGroup<"c++14-attribute-extensions">; def CXX17Attrs : DiagGroup<"c++17-attribute-extensions">; def CXX20Attrs : DiagGroup<"c++20-attribute-extensions">; +def CXX23Attrs : DiagGroup<"c++23-attribute-extensions">; def FutureAttrs : DiagGroup<"future-attribute-extensions", [CXX14Attrs, CXX17Attrs, - CXX20Attrs]>; + CXX20Attrs, + CXX23Attrs]>; def CXX23AttrsOnLambda : DiagGroup<"c++23-lambda-attributes">; @@ -1176,10 +1219,16 @@ def C23 : DiagGroup<"c23-extensions">; def : DiagGroup<"c2x-extensions", [C23]>; +// A warning group for warnings about using C2y features as extensions. +def C2y : DiagGroup<"c2y-extensions">; + +// Previously supported warning group which is no longer pertinent as binary +// literals are a C++14 and C23 extension now instead of a GNU extension. +def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">; + // A warning group for warnings about GCC extensions. def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct, - GNUAutoType, - GNUBinaryLiteral, GNUCaseRange, + GNUAutoType, GNUBinaryLiteral, GNUCaseRange, GNUComplexInteger, GNUCompoundLiteralInitializer, GNUConditionalOmittedOperand, GNUDesignator, GNUEmptyStruct, @@ -1390,6 +1439,9 @@ def MultiGPU: DiagGroup<"multi-gpu">; // libc and the CRT to be skipped. def AVRRtlibLinkingQuirks : DiagGroup<"avr-rtlib-linking-quirks">; +// A warning group related to AArch64 SME function attribues. +def AArch64SMEAttributes : DiagGroup<"aarch64-sme-attributes">; + // A warning group for things that will change semantics in the future. def FutureCompat : DiagGroup<"future-compat">; @@ -1420,6 +1472,10 @@ def FunctionMultiVersioning def NoDeref : DiagGroup<"noderef">; +// -fbounds-safety and bounds annotation related warnings +def BoundsSafetyCountedByEltTyUnknownSize : + DiagGroup<"bounds-safety-counted-by-elt-type-unknown-size">; + // A group for cross translation unit static analysis related warnings. def CrossTU : DiagGroup<"ctu">; @@ -1482,12 +1538,35 @@ def BranchProtection : DiagGroup<"branch-protection">; // Warnings for HLSL Clang extensions def HLSLExtension : DiagGroup<"hlsl-extensions">; +// Warning for mix packoffset and non-packoffset. +def HLSLMixPackOffset : DiagGroup<"mix-packoffset">; + // Warnings for DXIL validation def DXILValidation : DiagGroup<"dxil-validation">; +// Warning for HLSL API availability +def HLSLAvailability : DiagGroup<"hlsl-availability">; + // Warnings and notes related to const_var_decl_type attribute checks def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">; // Warnings and fixes to support the "safe buffers" programming model. def UnsafeBufferUsageInContainer : DiagGroup<"unsafe-buffer-usage-in-container">; def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer]>; + +// Warnings and notes related to the function effects system underlying +// the nonblocking and nonallocating attributes. +def FunctionEffects : DiagGroup<"function-effects">; + +// Warnings and notes InstallAPI verification. +def InstallAPIViolation : DiagGroup<"installapi-violation">; + +// Warnings related to _BitInt extension +def BitIntExtension : DiagGroup<"bit-int-extension">; + +// Warnings about misuse of ExtractAPI options. +def ExtractAPIMisuse : DiagGroup<"extractapi-misuse">; + +// Warnings about using the non-standard extension having an explicit specialization +// with a storage class specifier. +def ExplicitSpecializationStorageClass : DiagGroup<"explicit-specialization-storage-class">; diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h index 0cdda42793f..bce7605b95b 100644 --- a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticIDs.h @@ -32,7 +32,7 @@ namespace clang { enum { DIAG_SIZE_COMMON = 300, DIAG_SIZE_DRIVER = 400, - DIAG_SIZE_FRONTEND = 150, + DIAG_SIZE_FRONTEND = 200, DIAG_SIZE_SERIALIZATION = 120, DIAG_SIZE_LEX = 400, DIAG_SIZE_PARSE = 700, @@ -42,6 +42,7 @@ namespace clang { DIAG_SIZE_SEMA = 4500, DIAG_SIZE_ANALYSIS = 100, DIAG_SIZE_REFACTORING = 1000, + DIAG_SIZE_INSTALLAPI = 100, }; // Start position for diagnostics. enum { @@ -57,7 +58,8 @@ namespace clang { DIAG_START_SEMA = DIAG_START_CROSSTU + static_cast(DIAG_SIZE_CROSSTU), DIAG_START_ANALYSIS = DIAG_START_SEMA + static_cast(DIAG_SIZE_SEMA), DIAG_START_REFACTORING = DIAG_START_ANALYSIS + static_cast(DIAG_SIZE_ANALYSIS), - DIAG_UPPER_LIMIT = DIAG_START_REFACTORING + static_cast(DIAG_SIZE_REFACTORING) + DIAG_START_INSTALLAPI = DIAG_START_REFACTORING + static_cast(DIAG_SIZE_REFACTORING), + DIAG_UPPER_LIMIT = DIAG_START_INSTALLAPI + static_cast(DIAG_SIZE_INSTALLAPI) }; class CustomDiagInfo; @@ -276,6 +278,9 @@ public: /// category. static bool isARCDiagnostic(unsigned DiagID); + /// Return true if a given diagnostic is a codegen-time ABI check. + static bool isCodegenABICheckDiagnostic(unsigned DiagID); + /// Enumeration describing how the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. enum SFINAEResponse { diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticInstallAPI.h b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticInstallAPI.h new file mode 100644 index 00000000000..a76f6e087a2 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticInstallAPI.h @@ -0,0 +1,26 @@ +//===--- DiagnosticInstallAPI.h - Diagnostics for InstallAPI-----*- 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_BASIC_DIAGNOSTICINSTALLAPI_H +#define LLVM_CLANG_BASIC_DIAGNOSTICINSTALLAPI_H + +#include "clang/Basic/Diagnostic.h" +namespace clang { +namespace diag { +enum { +#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \ + SHOWINSYSHEADER, SHOWINSYSMACRO, DEFERRABLE, CATEGORY) \ + ENUM, +#define INSTALLAPISTART +#include "clang/Basic/DiagnosticInstallAPIKinds.inc" +#undef DIAG + NUM_BUILTIN_INSTALLAPI_DIAGNOSTICS +}; +} // namespace diag +} // namespace clang +#endif // LLVM_CLANG_BASIC_DIAGNOSTICINSTALLAPI_H diff --git a/contrib/llvm-project/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td new file mode 100644 index 00000000000..e10fa71011f --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td @@ -0,0 +1,77 @@ +//==--- DiagnosticInstallAPIKinds.td - installapi diagnostics -------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// InstallAPI Diagnostics +//===----------------------------------------------------------------------===// + +let Component = "InstallAPI" in { +let CategoryName = "Command line" in { +def err_cannot_write_file : Error<"cannot write file '%0': %1">; +def err_no_install_name : Error<"no install name specified: add -install_name ">; +def err_no_output_file: Error<"no output file specified">; +def err_no_such_header_file : Error<"no such %select{public|private|project}1 header file: '%0'">; +def warn_no_such_excluded_header_file : Warning<"no such excluded %select{public|private}0 header file: '%1'">, InGroup; +def warn_glob_did_not_match: Warning<"glob '%0' did not match any header file">, InGroup; +def err_no_such_umbrella_header_file : Error<"%select{public|private|project}1 umbrella header file not found in input: '%0'">; +def err_cannot_find_reexport : Error<"cannot find re-exported %select{framework|library}0: '%1'">; +def err_no_matching_target : Error<"no matching target found for target variant '%0'">; +def err_unsupported_vendor : Error<"vendor '%0' is not supported: '%1'">; +def err_unsupported_environment : Error<"environment '%0' is not supported: '%1'">; +def err_unsupported_os : Error<"os '%0' is not supported: '%1'">; +def err_cannot_read_input_list : Error<"could not read %0 input list '%1': %2">; +def err_invalid_label: Error<"label '%0' is reserved: use a different label name for -X