1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

Merge llvm-project main llvmorg-12-init-17869-g8e464dd76bef

This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-12-init-17869-g8e464dd76bef, the last commit before the
upstream release/12.x branch was created.

PR:		255570
MFC after:	6 weeks
This commit is contained in:
Dimitry Andric 2021-06-13 21:31:46 +02:00
commit e8d8bef961
4831 changed files with 364154 additions and 165756 deletions

View File

@ -40,6 +40,290 @@
# xargs -n1 | sort | uniq -d;
# done
# 20210613: new clang import which bumps version from 11.0.1 to 12.0.0.
OLD_FILES+=usr/lib/clang/11.0.1/include/cuda_wrappers/algorithm
OLD_FILES+=usr/lib/clang/11.0.1/include/cuda_wrappers/complex
OLD_FILES+=usr/lib/clang/11.0.1/include/cuda_wrappers/new
OLD_DIRS+=usr/lib/clang/11.0.1/include/cuda_wrappers
OLD_FILES+=usr/lib/clang/11.0.1/include/fuzzer/FuzzedDataProvider.h
OLD_DIRS+=usr/lib/clang/11.0.1/include/fuzzer
OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/__clang_openmp_device_functions.h
OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/cmath
OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/complex
OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/complex.h
OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/math.h
OLD_FILES+=usr/lib/clang/11.0.1/include/openmp_wrappers/new
OLD_DIRS+=usr/lib/clang/11.0.1/include/openmp_wrappers
OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/emmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/mm_malloc.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/mmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/pmmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/smmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/tmmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ppc_wrappers/xmmintrin.h
OLD_DIRS+=usr/lib/clang/11.0.1/include/ppc_wrappers
OLD_FILES+=usr/lib/clang/11.0.1/include/profile/InstrProfData.inc
OLD_DIRS+=usr/lib/clang/11.0.1/include/profile
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/allocator_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/asan_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/common_interface_defs.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/coverage_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/dfsan_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/hwasan_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/linux_syscall_hooks.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/lsan_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/msan_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/netbsd_syscall_hooks.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/scudo_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/tsan_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/tsan_interface_atomic.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sanitizer/ubsan_interface.h
OLD_DIRS+=usr/lib/clang/11.0.1/include/sanitizer
OLD_FILES+=usr/lib/clang/11.0.1/include/xray/xray_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xray/xray_log_interface.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xray/xray_records.h
OLD_DIRS+=usr/lib/clang/11.0.1/include/xray
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_builtin_vars.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_cmath.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_complex_builtins.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_device_functions.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_intrinsics.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_libdevice_declares.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_math.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_math_forward_declares.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_cuda_runtime_wrapper.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_hip_libdevice_declares.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_hip_math.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__clang_hip_runtime_wrapper.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__stddef_max_align_t.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__wmmintrin_aes.h
OLD_FILES+=usr/lib/clang/11.0.1/include/__wmmintrin_pclmul.h
OLD_FILES+=usr/lib/clang/11.0.1/include/adxintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/altivec.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ammintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/amxintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm64intr.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_acle.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_bf16.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_cde.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_cmse.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_fp16.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_mve.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_neon.h
OLD_FILES+=usr/lib/clang/11.0.1/include/arm_sve.h
OLD_FILES+=usr/lib/clang/11.0.1/include/armintr.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx2intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512bf16intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512bitalgintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512bwintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512cdintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512dqintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512erintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512fintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512ifmaintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512ifmavlintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512pfintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vbmi2intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vbmiintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vbmivlintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlbf16intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlbitalgintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlbwintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlcdintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vldqintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlvbmi2intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlvnniintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vlvp2intersectintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vnniintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vp2intersectintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vpopcntdqintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avx512vpopcntdqvlintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/avxintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/bmi2intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/bmiintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/cet.h
OLD_FILES+=usr/lib/clang/11.0.1/include/cetintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/cldemoteintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/clflushoptintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/clwbintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/clzerointrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/cpuid.h
OLD_FILES+=usr/lib/clang/11.0.1/include/emmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/enqcmdintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/f16cintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/float.h
OLD_FILES+=usr/lib/clang/11.0.1/include/fma4intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/fmaintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/fxsrintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/gfniintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/htmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/htmxlintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ia32intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/immintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/inttypes.h
OLD_FILES+=usr/lib/clang/11.0.1/include/invpcidintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/iso646.h
OLD_FILES+=usr/lib/clang/11.0.1/include/limits.h
OLD_FILES+=usr/lib/clang/11.0.1/include/lwpintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/lzcntintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/mm3dnow.h
OLD_FILES+=usr/lib/clang/11.0.1/include/mm_malloc.h
OLD_FILES+=usr/lib/clang/11.0.1/include/mmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/module.modulemap
OLD_FILES+=usr/lib/clang/11.0.1/include/movdirintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/msa.h
OLD_FILES+=usr/lib/clang/11.0.1/include/mwaitxintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/nmmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/omp-tools.h
OLD_FILES+=usr/lib/clang/11.0.1/include/omp.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ompt.h
OLD_FILES+=usr/lib/clang/11.0.1/include/opencl-c-base.h
OLD_FILES+=usr/lib/clang/11.0.1/include/opencl-c.h
OLD_FILES+=usr/lib/clang/11.0.1/include/pconfigintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/pkuintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/pmmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/popcntintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/prfchwintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/ptwriteintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/rdseedintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/rtmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/s390intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/serializeintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/sgxintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/shaintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/smmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/stdalign.h
OLD_FILES+=usr/lib/clang/11.0.1/include/stdarg.h
OLD_FILES+=usr/lib/clang/11.0.1/include/stdatomic.h
OLD_FILES+=usr/lib/clang/11.0.1/include/stdbool.h
OLD_FILES+=usr/lib/clang/11.0.1/include/stddef.h
OLD_FILES+=usr/lib/clang/11.0.1/include/stdint.h
OLD_FILES+=usr/lib/clang/11.0.1/include/stdnoreturn.h
OLD_FILES+=usr/lib/clang/11.0.1/include/tbmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/tgmath.h
OLD_FILES+=usr/lib/clang/11.0.1/include/tmmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/tsxldtrkintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/unwind.h
OLD_FILES+=usr/lib/clang/11.0.1/include/vadefs.h
OLD_FILES+=usr/lib/clang/11.0.1/include/vaesintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/varargs.h
OLD_FILES+=usr/lib/clang/11.0.1/include/vecintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/vpclmulqdqintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/waitpkgintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/wasm_simd128.h
OLD_FILES+=usr/lib/clang/11.0.1/include/wbnoinvdintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/wmmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/x86intrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xmmintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xopintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xsavecintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xsaveintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xsaveoptintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xsavesintrin.h
OLD_FILES+=usr/lib/clang/11.0.1/include/xtestintrin.h
OLD_DIRS+=usr/lib/clang/11.0.1/include
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-aarch64.so
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-arm.so
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-armhf.so
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-i386.so
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-preinit-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan-x86_64.so
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.asan_cxx-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.cfi_diag-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.dd-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.dd-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.fuzzer_no_main-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan_cxx-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.msan_cxx-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-powerpc.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-powerpc64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-powerpc64le.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.profile-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.safestack-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.safestack-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.safestack-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.stats_client-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan_cxx-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.tsan_cxx-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_minimal-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-i386.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-basic-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-fdr-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-aarch64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-arm.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-armhf.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-profiling-x86_64.a
OLD_FILES+=usr/lib/clang/11.0.1/lib/freebsd/libclang_rt.xray-x86_64.a
OLD_DIRS+=usr/lib/clang/11.0.1/lib/freebsd
OLD_DIRS+=usr/lib/clang/11.0.1/lib
OLD_DIRS+=usr/lib/clang/11.0.1
# 20210613: Rename OpenZFS manual pages
OLD_FILES+=usr/share/man/man5/spl-module-parameters.5.gz
OLD_FILES+=usr/share/man/man5/zfs-events.5.gz

View File

@ -33,7 +33,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
#define CINDEX_VERSION_MINOR 60
#define CINDEX_VERSION_MINOR 61
#define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1))
@ -2052,62 +2052,58 @@ enum CXCursorKind {
*/
CXCursor_CXXFunctionalCastExpr = 128,
/** OpenCL's addrspace_cast<> expression.
*/
CXCursor_CXXAddrspaceCastExpr = 129,
/** A C++ typeid expression (C++ [expr.typeid]).
*/
CXCursor_CXXTypeidExpr = 130,
CXCursor_CXXTypeidExpr = 129,
/** [C++ 2.13.5] C++ Boolean Literal.
*/
CXCursor_CXXBoolLiteralExpr = 131,
CXCursor_CXXBoolLiteralExpr = 130,
/** [C++0x 2.14.7] C++ Pointer Literal.
*/
CXCursor_CXXNullPtrLiteralExpr = 132,
CXCursor_CXXNullPtrLiteralExpr = 131,
/** Represents the "this" expression in C++
*/
CXCursor_CXXThisExpr = 133,
CXCursor_CXXThisExpr = 132,
/** [C++ 15] C++ Throw Expression.
*
* This handles 'throw' and 'throw' assignment-expression. When
* assignment-expression isn't present, Op will be null.
*/
CXCursor_CXXThrowExpr = 134,
CXCursor_CXXThrowExpr = 133,
/** A new expression for memory allocation and constructor calls, e.g:
* "new CXXNewExpr(foo)".
*/
CXCursor_CXXNewExpr = 135,
CXCursor_CXXNewExpr = 134,
/** A delete expression for memory deallocation and destructor calls,
* e.g. "delete[] pArray".
*/
CXCursor_CXXDeleteExpr = 136,
CXCursor_CXXDeleteExpr = 135,
/** A unary expression. (noexcept, sizeof, or other traits)
*/
CXCursor_UnaryExpr = 137,
CXCursor_UnaryExpr = 136,
/** An Objective-C string literal i.e. @"foo".
*/
CXCursor_ObjCStringLiteral = 138,
CXCursor_ObjCStringLiteral = 137,
/** An Objective-C \@encode expression.
*/
CXCursor_ObjCEncodeExpr = 139,
CXCursor_ObjCEncodeExpr = 138,
/** An Objective-C \@selector expression.
*/
CXCursor_ObjCSelectorExpr = 140,
CXCursor_ObjCSelectorExpr = 139,
/** An Objective-C \@protocol expression.
*/
CXCursor_ObjCProtocolExpr = 141,
CXCursor_ObjCProtocolExpr = 140,
/** An Objective-C "bridged" cast expression, which casts between
* Objective-C pointers and C pointers, transferring ownership in the process.
@ -2116,7 +2112,7 @@ enum CXCursorKind {
* NSString *str = (__bridge_transfer NSString *)CFCreateString();
* \endcode
*/
CXCursor_ObjCBridgedCastExpr = 142,
CXCursor_ObjCBridgedCastExpr = 141,
/** Represents a C++0x pack expansion that produces a sequence of
* expressions.
@ -2131,7 +2127,7 @@ enum CXCursorKind {
* }
* \endcode
*/
CXCursor_PackExpansionExpr = 143,
CXCursor_PackExpansionExpr = 142,
/** Represents an expression that computes the length of a parameter
* pack.
@ -2143,7 +2139,7 @@ enum CXCursorKind {
* };
* \endcode
*/
CXCursor_SizeOfPackExpr = 144,
CXCursor_SizeOfPackExpr = 143,
/* Represents a C++ lambda expression that produces a local function
* object.
@ -2157,39 +2153,43 @@ enum CXCursorKind {
* }
* \endcode
*/
CXCursor_LambdaExpr = 145,
CXCursor_LambdaExpr = 144,
/** Objective-c Boolean Literal.
*/
CXCursor_ObjCBoolLiteralExpr = 146,
CXCursor_ObjCBoolLiteralExpr = 145,
/** Represents the "self" expression in an Objective-C method.
*/
CXCursor_ObjCSelfExpr = 147,
CXCursor_ObjCSelfExpr = 146,
/** OpenMP 5.0 [2.1.5, Array Section].
*/
CXCursor_OMPArraySectionExpr = 148,
CXCursor_OMPArraySectionExpr = 147,
/** Represents an @available(...) check.
*/
CXCursor_ObjCAvailabilityCheckExpr = 149,
CXCursor_ObjCAvailabilityCheckExpr = 148,
/**
* Fixed point literal
*/
CXCursor_FixedPointLiteral = 150,
CXCursor_FixedPointLiteral = 149,
/** OpenMP 5.0 [2.1.4, Array Shaping].
*/
CXCursor_OMPArrayShapingExpr = 151,
CXCursor_OMPArrayShapingExpr = 150,
/**
* OpenMP 5.0 [2.1.6 Iterators]
*/
CXCursor_OMPIteratorExpr = 152,
CXCursor_OMPIteratorExpr = 151,
CXCursor_LastExpr = CXCursor_OMPIteratorExpr,
/** OpenCL's addrspace_cast<> expression.
*/
CXCursor_CXXAddrspaceCastExpr = 152,
CXCursor_LastExpr = CXCursor_CXXAddrspaceCastExpr,
/* Statements */
CXCursor_FirstStmt = 200,
@ -2940,6 +2940,26 @@ CINDEX_LINKAGE int clang_getCursorPlatformAvailability(
CINDEX_LINKAGE void
clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability);
/**
* If cursor refers to a variable declaration and it has initializer returns
* cursor referring to the initializer otherwise return null cursor.
*/
CINDEX_LINKAGE CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor);
/**
* If cursor refers to a variable declaration that has global storage returns 1.
* If cursor refers to a variable declaration that doesn't have global storage
* returns 0. Otherwise returns -1.
*/
CINDEX_LINKAGE int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor);
/**
* If cursor refers to a variable declaration that has external storage
* returns 1. If cursor refers to a variable declaration that doesn't have
* external storage returns 0. Otherwise returns -1.
*/
CINDEX_LINKAGE int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor);
/**
* Describe the "language" of the entity referred to by a cursor.
*/
@ -3841,7 +3861,15 @@ enum CXTypeNullabilityKind {
/**
* Nullability is not applicable to this type.
*/
CXTypeNullability_Invalid = 3
CXTypeNullability_Invalid = 3,
/**
* Generally behaves like Nullable, except when used in a block parameter that
* was imported into a swift async method. There, swift will assume that the
* parameter can get null even if no error occured. _Nullable parameters are
* assumed to only get null on error.
*/
CXTypeNullability_NullableResult = 4
};
/**

View File

@ -0,0 +1,63 @@
/*===-- clang-c/Rewrite.h - C CXRewriter --------------------------*- 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_C_REWRITE_H
#define LLVM_CLANG_C_REWRITE_H
#include "clang-c/CXString.h"
#include "clang-c/ExternC.h"
#include "clang-c/Index.h"
#include "clang-c/Platform.h"
LLVM_CLANG_C_EXTERN_C_BEGIN
typedef void *CXRewriter;
/**
* Create CXRewriter.
*/
CINDEX_LINKAGE CXRewriter clang_CXRewriter_create(CXTranslationUnit TU);
/**
* Insert the specified string at the specified location in the original buffer.
*/
CINDEX_LINKAGE void clang_CXRewriter_insertTextBefore(CXRewriter Rew, CXSourceLocation Loc,
const char *Insert);
/**
* Replace the specified range of characters in the input with the specified
* replacement.
*/
CINDEX_LINKAGE void clang_CXRewriter_replaceText(CXRewriter Rew, CXSourceRange ToBeReplaced,
const char *Replacement);
/**
* Remove the specified range.
*/
CINDEX_LINKAGE void clang_CXRewriter_removeText(CXRewriter Rew, CXSourceRange ToBeRemoved);
/**
* Save all changed files to disk.
* Returns 1 if any files were not saved successfully, returns 0 otherwise.
*/
CINDEX_LINKAGE int clang_CXRewriter_overwriteChangedFiles(CXRewriter Rew);
/**
* Write out rewritten version of the main file to stdout.
*/
CINDEX_LINKAGE void clang_CXRewriter_writeMainFileToStdOut(CXRewriter Rew);
/**
* Free the given CXRewriter.
*/
CINDEX_LINKAGE void clang_CXRewriter_dispose(CXRewriter Rew);
LLVM_CLANG_C_EXTERN_C_END
#endif

View File

@ -0,0 +1,24 @@
//===-- APINotesYAMLCompiler.h - API Notes YAML Format Reader ---*- 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_APINOTES_APINOTESYAMLCOMPILER_H
#define LLVM_CLANG_APINOTES_APINOTESYAMLCOMPILER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
namespace api_notes {
/// Parses the APINotes YAML content and writes the representation back to the
/// specified stream. This provides a means of testing the YAML processing of
/// the APINotes format.
bool parseAndDumpAPINotes(llvm::StringRef YI, llvm::raw_ostream &OS);
} // namespace api_notes
} // namespace clang
#endif

View File

@ -0,0 +1,734 @@
//===-- Types.h - API Notes Data 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_APINOTES_TYPES_H
#define LLVM_CLANG_APINOTES_TYPES_H
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include <climits>
#include <vector>
namespace clang {
namespace api_notes {
enum class RetainCountConventionKind {
None,
CFReturnsRetained,
CFReturnsNotRetained,
NSReturnsRetained,
NSReturnsNotRetained,
};
/// The payload for an enum_extensibility attribute. This is a tri-state rather
/// than just a boolean because the presence of the attribute indicates
/// auditing.
enum class EnumExtensibilityKind {
None,
Open,
Closed,
};
/// The kind of a swift_wrapper/swift_newtype.
enum class SwiftNewTypeKind {
None,
Struct,
Enum,
};
/// Describes API notes data for any entity.
///
/// This is used as the base of all API notes.
class CommonEntityInfo {
public:
/// Message to use when this entity is unavailable.
std::string UnavailableMsg;
/// Whether this entity is marked unavailable.
unsigned Unavailable : 1;
/// Whether this entity is marked unavailable in Swift.
unsigned UnavailableInSwift : 1;
private:
/// Whether SwiftPrivate was specified.
unsigned SwiftPrivateSpecified : 1;
/// Whether this entity is considered "private" to a Swift overlay.
unsigned SwiftPrivate : 1;
public:
/// Swift name of this entity.
std::string SwiftName;
CommonEntityInfo()
: Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
SwiftPrivate(0) {}
llvm::Optional<bool> isSwiftPrivate() const {
return SwiftPrivateSpecified ? llvm::Optional<bool>(SwiftPrivate)
: llvm::None;
}
void setSwiftPrivate(llvm::Optional<bool> Private) {
SwiftPrivateSpecified = Private.hasValue();
SwiftPrivate = Private.hasValue() ? *Private : 0;
}
friend bool operator==(const CommonEntityInfo &, const CommonEntityInfo &);
CommonEntityInfo &operator|=(const CommonEntityInfo &RHS) {
// Merge unavailability.
if (RHS.Unavailable) {
Unavailable = true;
if (UnavailableMsg.empty())
UnavailableMsg = RHS.UnavailableMsg;
}
if (RHS.UnavailableInSwift) {
UnavailableInSwift = true;
if (UnavailableMsg.empty())
UnavailableMsg = RHS.UnavailableMsg;
}
if (!SwiftPrivateSpecified)
setSwiftPrivate(RHS.isSwiftPrivate());
if (SwiftName.empty())
SwiftName = RHS.SwiftName;
return *this;
}
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};
inline bool operator==(const CommonEntityInfo &LHS,
const CommonEntityInfo &RHS) {
return LHS.UnavailableMsg == RHS.UnavailableMsg &&
LHS.Unavailable == RHS.Unavailable &&
LHS.UnavailableInSwift == RHS.UnavailableInSwift &&
LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified &&
LHS.SwiftPrivate == RHS.SwiftPrivate && LHS.SwiftName == RHS.SwiftName;
}
inline bool operator!=(const CommonEntityInfo &LHS,
const CommonEntityInfo &RHS) {
return !(LHS == RHS);
}
/// Describes API notes for types.
class CommonTypeInfo : public CommonEntityInfo {
/// The Swift type to which a given type is bridged.
///
/// Reflects the swift_bridge attribute.
llvm::Optional<std::string> SwiftBridge;
/// The NS error domain for this type.
llvm::Optional<std::string> NSErrorDomain;
public:
CommonTypeInfo() : CommonEntityInfo() {}
const llvm::Optional<std::string> &getSwiftBridge() const {
return SwiftBridge;
}
void setSwiftBridge(const llvm::Optional<std::string> &SwiftType) {
SwiftBridge = SwiftType;
}
void setSwiftBridge(const llvm::Optional<llvm::StringRef> &SwiftType) {
SwiftBridge = SwiftType
? llvm::Optional<std::string>(std::string(*SwiftType))
: llvm::None;
}
const llvm::Optional<std::string> &getNSErrorDomain() const {
return NSErrorDomain;
}
void setNSErrorDomain(const llvm::Optional<std::string> &Domain) {
NSErrorDomain = Domain;
}
void setNSErrorDomain(const llvm::Optional<llvm::StringRef> &Domain) {
NSErrorDomain =
Domain ? llvm::Optional<std::string>(std::string(*Domain)) : llvm::None;
}
friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &);
CommonTypeInfo &operator|=(const CommonTypeInfo &RHS) {
// Merge inherited info.
static_cast<CommonEntityInfo &>(*this) |= RHS;
if (!SwiftBridge)
setSwiftBridge(RHS.getSwiftBridge());
if (!NSErrorDomain)
setNSErrorDomain(RHS.getNSErrorDomain());
return *this;
}
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};
inline bool operator==(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
LHS.SwiftBridge == RHS.SwiftBridge &&
LHS.NSErrorDomain == RHS.NSErrorDomain;
}
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 {
/// Whether this class has a default nullability.
unsigned HasDefaultNullability : 1;
/// The default nullability.
unsigned DefaultNullability : 2;
/// Whether this class has designated initializers recorded.
unsigned HasDesignatedInits : 1;
unsigned SwiftImportAsNonGenericSpecified : 1;
unsigned SwiftImportAsNonGeneric : 1;
unsigned SwiftObjCMembersSpecified : 1;
unsigned SwiftObjCMembers : 1;
public:
ObjCContextInfo()
: CommonTypeInfo(), HasDefaultNullability(0), DefaultNullability(0),
HasDesignatedInits(0), SwiftImportAsNonGenericSpecified(false),
SwiftImportAsNonGeneric(false), SwiftObjCMembersSpecified(false),
SwiftObjCMembers(false) {}
/// Determine the default nullability for properties and methods of this
/// class.
///
/// eturns the default nullability, if implied, or None if there is no
llvm::Optional<NullabilityKind> getDefaultNullability() const {
return HasDefaultNullability
? llvm::Optional<NullabilityKind>(
static_cast<NullabilityKind>(DefaultNullability))
: llvm::None;
}
/// Set the default nullability for properties and methods of this class.
void setDefaultNullability(NullabilityKind Kind) {
HasDefaultNullability = true;
DefaultNullability = static_cast<unsigned>(Kind);
}
bool hasDesignatedInits() const { return HasDesignatedInits; }
void setHasDesignatedInits(bool Value) { HasDesignatedInits = Value; }
llvm::Optional<bool> getSwiftImportAsNonGeneric() const {
return SwiftImportAsNonGenericSpecified
? llvm::Optional<bool>(SwiftImportAsNonGeneric)
: llvm::None;
}
void setSwiftImportAsNonGeneric(llvm::Optional<bool> Value) {
SwiftImportAsNonGenericSpecified = Value.hasValue();
SwiftImportAsNonGeneric = Value.hasValue() ? *Value : false;
}
llvm::Optional<bool> getSwiftObjCMembers() const {
return SwiftObjCMembersSpecified ? llvm::Optional<bool>(SwiftObjCMembers)
: llvm::None;
}
void setSwiftObjCMembers(llvm::Optional<bool> Value) {
SwiftObjCMembersSpecified = Value.hasValue();
SwiftObjCMembers = Value.hasValue() ? *Value : 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 ObjCContextInfo &, const ObjCContextInfo &);
ObjCContextInfo &operator|=(const ObjCContextInfo &RHS) {
// Merge inherited info.
static_cast<CommonTypeInfo &>(*this) |= RHS;
// Merge nullability.
if (!getDefaultNullability())
if (auto Nullability = RHS.getDefaultNullability())
setDefaultNullability(*Nullability);
if (!SwiftImportAsNonGenericSpecified)
setSwiftImportAsNonGeneric(RHS.getSwiftImportAsNonGeneric());
if (!SwiftObjCMembersSpecified)
setSwiftObjCMembers(RHS.getSwiftObjCMembers());
HasDesignatedInits |= RHS.HasDesignatedInits;
return *this;
}
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
};
inline bool operator==(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
LHS.getDefaultNullability() == RHS.getDefaultNullability() &&
LHS.HasDesignatedInits == RHS.HasDesignatedInits &&
LHS.getSwiftImportAsNonGeneric() == RHS.getSwiftImportAsNonGeneric() &&
LHS.getSwiftObjCMembers() == RHS.getSwiftObjCMembers();
}
inline bool operator!=(const ObjCContextInfo &LHS, const ObjCContextInfo &RHS) {
return !(LHS == RHS);
}
/// API notes for a variable/property.
class VariableInfo : public CommonEntityInfo {
/// Whether this property has been audited for nullability.
unsigned NullabilityAudited : 1;
/// The kind of nullability for this property. Only valid if the nullability
/// has been audited.
unsigned Nullable : 2;
/// The C type of the variable, as a string.
std::string Type;
public:
VariableInfo() : CommonEntityInfo(), NullabilityAudited(false), Nullable(0) {}
llvm::Optional<NullabilityKind> getNullability() const {
return NullabilityAudited ? llvm::Optional<NullabilityKind>(
static_cast<NullabilityKind>(Nullable))
: llvm::None;
}
void setNullabilityAudited(NullabilityKind kind) {
NullabilityAudited = true;
Nullable = static_cast<unsigned>(kind);
}
const std::string &getType() const { return Type; }
void setType(const std::string &type) { Type = type; }
friend bool operator==(const VariableInfo &, const VariableInfo &);
VariableInfo &operator|=(const VariableInfo &RHS) {
static_cast<CommonEntityInfo &>(*this) |= RHS;
if (!NullabilityAudited && RHS.NullabilityAudited)
setNullabilityAudited(*RHS.getNullability());
if (Type.empty())
Type = RHS.Type;
return *this;
}
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};
inline bool operator==(const VariableInfo &LHS, const VariableInfo &RHS) {
return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
LHS.NullabilityAudited == RHS.NullabilityAudited &&
LHS.Nullable == RHS.Nullable && LHS.Type == RHS.Type;
}
inline bool operator!=(const VariableInfo &LHS, const VariableInfo &RHS) {
return !(LHS == RHS);
}
/// Describes API notes data for an Objective-C property.
class ObjCPropertyInfo : public VariableInfo {
unsigned SwiftImportAsAccessorsSpecified : 1;
unsigned SwiftImportAsAccessors : 1;
public:
ObjCPropertyInfo()
: VariableInfo(), SwiftImportAsAccessorsSpecified(false),
SwiftImportAsAccessors(false) {}
llvm::Optional<bool> getSwiftImportAsAccessors() const {
return SwiftImportAsAccessorsSpecified
? llvm::Optional<bool>(SwiftImportAsAccessors)
: llvm::None;
}
void setSwiftImportAsAccessors(llvm::Optional<bool> Value) {
SwiftImportAsAccessorsSpecified = Value.hasValue();
SwiftImportAsAccessors = Value.hasValue() ? *Value : false;
}
friend bool operator==(const ObjCPropertyInfo &, const ObjCPropertyInfo &);
/// Merge class-wide information into the given property.
ObjCPropertyInfo &operator|=(const ObjCContextInfo &RHS) {
static_cast<CommonEntityInfo &>(*this) |= RHS;
// Merge nullability.
if (!getNullability())
if (auto Nullable = RHS.getDefaultNullability())
setNullabilityAudited(*Nullable);
return *this;
}
ObjCPropertyInfo &operator|=(const ObjCPropertyInfo &RHS) {
static_cast<VariableInfo &>(*this) |= RHS;
if (!SwiftImportAsAccessorsSpecified)
setSwiftImportAsAccessors(RHS.getSwiftImportAsAccessors());
return *this;
}
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};
inline bool operator==(const ObjCPropertyInfo &LHS,
const ObjCPropertyInfo &RHS) {
return static_cast<const VariableInfo &>(LHS) == RHS &&
LHS.getSwiftImportAsAccessors() == RHS.getSwiftImportAsAccessors();
}
inline bool operator!=(const ObjCPropertyInfo &LHS,
const ObjCPropertyInfo &RHS) {
return !(LHS == RHS);
}
/// Describes a function or method parameter.
class ParamInfo : public VariableInfo {
/// Whether noescape was specified.
unsigned NoEscapeSpecified : 1;
/// Whether the this parameter has the 'noescape' attribute.
unsigned NoEscape : 1;
/// A biased RetainCountConventionKind, where 0 means "unspecified".
///
/// Only relevant for out-parameters.
unsigned RawRetainCountConvention : 3;
public:
ParamInfo()
: VariableInfo(), NoEscapeSpecified(false), NoEscape(false),
RawRetainCountConvention() {}
llvm::Optional<bool> isNoEscape() const {
if (!NoEscapeSpecified)
return llvm::None;
return NoEscape;
}
void setNoEscape(llvm::Optional<bool> Value) {
NoEscapeSpecified = Value.hasValue();
NoEscape = Value.hasValue() ? *Value : false;
}
llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const {
if (!RawRetainCountConvention)
return llvm::None;
return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
}
void
setRetainCountConvention(llvm::Optional<RetainCountConventionKind> Value) {
RawRetainCountConvention =
Value.hasValue() ? static_cast<unsigned>(Value.getValue()) + 1 : 0;
assert(getRetainCountConvention() == Value && "bitfield too small");
}
ParamInfo &operator|=(const ParamInfo &RHS) {
static_cast<VariableInfo &>(*this) |= RHS;
if (!NoEscapeSpecified && RHS.NoEscapeSpecified) {
NoEscapeSpecified = true;
NoEscape = RHS.NoEscape;
}
if (!RawRetainCountConvention)
RawRetainCountConvention = RHS.RawRetainCountConvention;
return *this;
}
friend bool operator==(const ParamInfo &, const ParamInfo &);
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};
inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) {
return static_cast<const VariableInfo &>(LHS) == RHS &&
LHS.NoEscapeSpecified == RHS.NoEscapeSpecified &&
LHS.NoEscape == RHS.NoEscape &&
LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
}
inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) {
return !(LHS == RHS);
}
/// API notes for a function or method.
class FunctionInfo : public CommonEntityInfo {
private:
static constexpr const unsigned NullabilityKindMask = 0x3;
static constexpr const unsigned NullabilityKindSize = 2;
static constexpr const unsigned ReturnInfoIndex = 0;
public:
// If yes, we consider all types to be non-nullable unless otherwise noted.
// If this flag is not set, the pointer types are considered to have
// unknown nullability.
/// Whether the signature has been audited with respect to nullability.
unsigned NullabilityAudited : 1;
/// Number of types whose nullability is encoded with the NullabilityPayload.
unsigned NumAdjustedNullable : 8;
/// A biased RetainCountConventionKind, where 0 means "unspecified".
unsigned RawRetainCountConvention : 3;
// NullabilityKindSize bits are used to encode the nullability. The info
// about the return type is stored at position 0, followed by the nullability
// of the parameters.
/// Stores the nullability of the return type and the parameters.
uint64_t NullabilityPayload = 0;
/// The result type of this function, as a C type.
std::string ResultType;
/// The function parameters.
std::vector<ParamInfo> Params;
FunctionInfo()
: CommonEntityInfo(), NullabilityAudited(false), NumAdjustedNullable(0),
RawRetainCountConvention() {}
static unsigned getMaxNullabilityIndex() {
return ((sizeof(NullabilityPayload) * CHAR_BIT) / NullabilityKindSize);
}
void addTypeInfo(unsigned index, NullabilityKind kind) {
assert(index <= getMaxNullabilityIndex());
assert(static_cast<unsigned>(kind) < NullabilityKindMask);
NullabilityAudited = true;
if (NumAdjustedNullable < index + 1)
NumAdjustedNullable = index + 1;
// Mask the bits.
NullabilityPayload &=
~(NullabilityKindMask << (index * NullabilityKindSize));
// Set the value.
unsigned kindValue = (static_cast<unsigned>(kind))
<< (index * NullabilityKindSize);
NullabilityPayload |= kindValue;
}
/// Adds the return type info.
void addReturnTypeInfo(NullabilityKind kind) {
addTypeInfo(ReturnInfoIndex, kind);
}
/// Adds the parameter type info.
void addParamTypeInfo(unsigned index, NullabilityKind kind) {
addTypeInfo(index + 1, kind);
}
NullabilityKind getParamTypeInfo(unsigned index) const {
return getTypeInfo(index + 1);
}
NullabilityKind getReturnTypeInfo() const { return getTypeInfo(0); }
llvm::Optional<RetainCountConventionKind> getRetainCountConvention() const {
if (!RawRetainCountConvention)
return llvm::None;
return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
}
void
setRetainCountConvention(llvm::Optional<RetainCountConventionKind> Value) {
RawRetainCountConvention =
Value.hasValue() ? static_cast<unsigned>(Value.getValue()) + 1 : 0;
assert(getRetainCountConvention() == Value && "bitfield too small");
}
friend bool operator==(const FunctionInfo &, const FunctionInfo &);
private:
NullabilityKind getTypeInfo(unsigned index) const {
assert(NullabilityAudited &&
"Checking the type adjustment on non-audited method.");
// If we don't have info about this parameter, return the default.
if (index > NumAdjustedNullable)
return NullabilityKind::NonNull;
auto nullability = NullabilityPayload >> (index * NullabilityKindSize);
return static_cast<NullabilityKind>(nullability & NullabilityKindMask);
}
public:
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};
inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
LHS.NullabilityAudited == RHS.NullabilityAudited &&
LHS.NumAdjustedNullable == RHS.NumAdjustedNullable &&
LHS.NullabilityPayload == RHS.NullabilityPayload &&
LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params &&
LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
}
inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
return !(LHS == RHS);
}
/// Describes API notes data for an Objective-C method.
class ObjCMethodInfo : public FunctionInfo {
public:
/// Whether this is a designated initializer of its class.
unsigned DesignatedInit : 1;
/// Whether this is a required initializer.
unsigned RequiredInit : 1;
ObjCMethodInfo()
: FunctionInfo(), DesignatedInit(false), RequiredInit(false) {}
friend bool operator==(const ObjCMethodInfo &, const ObjCMethodInfo &);
ObjCMethodInfo &operator|=(const ObjCContextInfo &RHS) {
// Merge Nullability.
if (!NullabilityAudited) {
if (auto Nullable = RHS.getDefaultNullability()) {
NullabilityAudited = true;
addTypeInfo(0, *Nullable);
}
}
return *this;
}
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
};
inline bool operator==(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
return static_cast<const FunctionInfo &>(LHS) == RHS &&
LHS.DesignatedInit == RHS.DesignatedInit &&
LHS.RequiredInit == RHS.RequiredInit;
}
inline bool operator!=(const ObjCMethodInfo &LHS, const ObjCMethodInfo &RHS) {
return !(LHS == RHS);
}
/// Describes API notes data for a global variable.
class GlobalVariableInfo : public VariableInfo {
public:
GlobalVariableInfo() : VariableInfo() {}
};
/// Describes API notes data for a global function.
class GlobalFunctionInfo : public FunctionInfo {
public:
GlobalFunctionInfo() : FunctionInfo() {}
};
/// Describes API notes data for an enumerator.
class EnumConstantInfo : public CommonEntityInfo {
public:
EnumConstantInfo() : CommonEntityInfo() {}
};
/// Describes API notes data for a tag.
class TagInfo : public CommonTypeInfo {
unsigned HasFlagEnum : 1;
unsigned IsFlagEnum : 1;
public:
llvm::Optional<EnumExtensibilityKind> EnumExtensibility;
TagInfo() : CommonTypeInfo(), HasFlagEnum(0), IsFlagEnum(0) {}
llvm::Optional<bool> isFlagEnum() const {
if (HasFlagEnum)
return IsFlagEnum;
return llvm::None;
}
void setFlagEnum(llvm::Optional<bool> Value) {
HasFlagEnum = Value.hasValue();
IsFlagEnum = Value.hasValue() ? *Value : false;
}
TagInfo &operator|=(const TagInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
if (!HasFlagEnum && HasFlagEnum)
setFlagEnum(RHS.isFlagEnum());
if (!EnumExtensibility.hasValue())
EnumExtensibility = RHS.EnumExtensibility;
return *this;
}
friend bool operator==(const TagInfo &, const TagInfo &);
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS);
};
inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
LHS.isFlagEnum() == RHS.isFlagEnum() &&
LHS.EnumExtensibility == RHS.EnumExtensibility;
}
inline bool operator!=(const TagInfo &LHS, const TagInfo &RHS) {
return !(LHS == RHS);
}
/// Describes API notes data for a typedef.
class TypedefInfo : public CommonTypeInfo {
public:
llvm::Optional<SwiftNewTypeKind> SwiftWrapper;
TypedefInfo() : CommonTypeInfo() {}
TypedefInfo &operator|=(const TypedefInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
if (!SwiftWrapper.hasValue())
SwiftWrapper = RHS.SwiftWrapper;
return *this;
}
friend bool operator==(const TypedefInfo &, const TypedefInfo &);
LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};
inline bool operator==(const TypedefInfo &LHS, const TypedefInfo &RHS) {
return static_cast<const CommonTypeInfo &>(LHS) == RHS &&
LHS.SwiftWrapper == RHS.SwiftWrapper;
}
inline bool operator!=(const TypedefInfo &LHS, const TypedefInfo &RHS) {
return !(LHS == RHS);
}
} // namespace api_notes
} // namespace clang
#endif

View File

@ -12,11 +12,13 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
namespace llvm {
class MemoryBuffer;
class MemoryBufferRef;
}
namespace clang {
@ -55,6 +57,12 @@ class FileRemapper {
void applyMappings(PreprocessorOptions &PPOpts) const;
/// Iterate through all the mappings.
void forEachMapping(
llvm::function_ref<void(StringRef, StringRef)> CaptureFile,
llvm::function_ref<void(StringRef, const llvm::MemoryBufferRef &)>
CaptureBuffer) const;
void clear(StringRef outputDir = StringRef());
private:

View File

@ -13,14 +13,20 @@
#ifndef LLVM_CLANG_AST_APVALUE_H
#define LLVM_CLANG_AST_APVALUE_H
#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/APFixedPoint.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/Support/AlignOf.h"
namespace clang {
namespace serialization {
template <typename T> class BasicReaderBase;
} // end namespace serialization
class AddrLabelExpr;
class ASTContext;
class CharUnits;
@ -32,6 +38,7 @@ namespace clang {
struct PrintingPolicy;
class Type;
class ValueDecl;
class QualType;
/// Symbolic representation of typeid(T) for some type T.
class TypeInfoLValue {
@ -113,6 +120,7 @@ namespace clang {
/// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
/// [Vector: N * APValue], [Array: N * APValue]
class APValue {
typedef llvm::APFixedPoint APFixedPoint;
typedef llvm::APSInt APSInt;
typedef llvm::APFloat APFloat;
public:
@ -147,6 +155,8 @@ class APValue {
static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
void Profile(llvm::FoldingSetNodeID &ID) const;
template <class T>
bool is() const { return Ptr.is<T>(); }
@ -167,11 +177,14 @@ class APValue {
QualType getTypeInfoType() const;
QualType getDynamicAllocType() const;
QualType getType() const;
friend bool operator==(const LValueBase &LHS, const LValueBase &RHS);
friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) {
return !(LHS == RHS);
}
friend llvm::hash_code hash_value(const LValueBase &Base);
friend struct llvm::DenseMapInfo<LValueBase>;
private:
PtrTy Ptr;
@ -199,8 +212,7 @@ class APValue {
public:
LValuePathEntry() : Value() {}
LValuePathEntry(BaseOrMemberType BaseOrMember)
: Value{reinterpret_cast<uintptr_t>(BaseOrMember.getOpaqueValue())} {}
LValuePathEntry(BaseOrMemberType BaseOrMember);
static LValuePathEntry ArrayIndex(uint64_t Index) {
LValuePathEntry Result;
Result.Value = Index;
@ -213,6 +225,8 @@ class APValue {
}
uint64_t getAsArrayIndex() const { return Value; }
void Profile(llvm::FoldingSetNodeID &ID) const;
friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
return A.Value == B.Value;
}
@ -223,12 +237,22 @@ class APValue {
return llvm::hash_value(A.Value);
}
};
class LValuePathSerializationHelper {
const void *ElemTy;
public:
ArrayRef<LValuePathEntry> Path;
LValuePathSerializationHelper(ArrayRef<LValuePathEntry>, QualType);
QualType getType();
};
struct NoLValuePath {};
struct UninitArray {};
struct UninitStruct {};
friend class ASTReader;
friend class ASTWriter;
template <typename Impl> friend class clang::serialization::BasicReaderBase;
friend class ASTImporter;
friend class ASTNodeImporter;
private:
ValueKind Kind;
@ -302,7 +326,7 @@ class APValue {
MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
}
APValue(const APValue &RHS);
APValue(APValue &&RHS) : Kind(None) { swap(RHS); }
APValue(APValue &&RHS);
APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
bool IsNullPtr = false)
: Kind(None) {
@ -337,6 +361,9 @@ class APValue {
return Result;
}
APValue &operator=(const APValue &RHS);
APValue &operator=(APValue &&RHS);
~APValue() {
if (Kind != None && Kind != Indeterminate)
DestroyDataAndMakeUninit();
@ -352,6 +379,11 @@ class APValue {
/// Swaps the contents of this and the given APValue.
void swap(APValue &RHS);
/// profile this value. There is no guarantee that values of different
/// types will not produce the same profiled value, so the type should
/// typically also be profiled if it's not implied by the context.
void Profile(llvm::FoldingSetNodeID &ID) const;
ValueKind getKind() const { return Kind; }
bool isAbsent() const { return Kind == None; }
@ -375,11 +407,14 @@ class APValue {
void dump(raw_ostream &OS, const ASTContext &Context) const;
void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const;
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy, QualType Ty,
const ASTContext *Ctx = nullptr) const;
std::string getAsString(const ASTContext &Ctx, QualType Ty) const;
APSInt &getInt() {
assert(isInt() && "Invalid accessor");
return *(APSInt*)(char*)Data.buffer;
return *(APSInt *)(char *)&Data;
}
const APSInt &getInt() const {
return const_cast<APValue*>(this)->getInt();
@ -393,7 +428,7 @@ class APValue {
APFloat &getFloat() {
assert(isFloat() && "Invalid accessor");
return *(APFloat*)(char*)Data.buffer;
return *(APFloat *)(char *)&Data;
}
const APFloat &getFloat() const {
return const_cast<APValue*>(this)->getFloat();
@ -401,7 +436,7 @@ class APValue {
APFixedPoint &getFixedPoint() {
assert(isFixedPoint() && "Invalid accessor");
return *(APFixedPoint *)(char *)Data.buffer;
return *(APFixedPoint *)(char *)&Data;
}
const APFixedPoint &getFixedPoint() const {
return const_cast<APValue *>(this)->getFixedPoint();
@ -409,7 +444,7 @@ class APValue {
APSInt &getComplexIntReal() {
assert(isComplexInt() && "Invalid accessor");
return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
return ((ComplexAPSInt *)(char *)&Data)->Real;
}
const APSInt &getComplexIntReal() const {
return const_cast<APValue*>(this)->getComplexIntReal();
@ -417,7 +452,7 @@ class APValue {
APSInt &getComplexIntImag() {
assert(isComplexInt() && "Invalid accessor");
return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
return ((ComplexAPSInt *)(char *)&Data)->Imag;
}
const APSInt &getComplexIntImag() const {
return const_cast<APValue*>(this)->getComplexIntImag();
@ -425,7 +460,7 @@ class APValue {
APFloat &getComplexFloatReal() {
assert(isComplexFloat() && "Invalid accessor");
return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
return ((ComplexAPFloat *)(char *)&Data)->Real;
}
const APFloat &getComplexFloatReal() const {
return const_cast<APValue*>(this)->getComplexFloatReal();
@ -433,7 +468,7 @@ class APValue {
APFloat &getComplexFloatImag() {
assert(isComplexFloat() && "Invalid accessor");
return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
return ((ComplexAPFloat *)(char *)&Data)->Imag;
}
const APFloat &getComplexFloatImag() const {
return const_cast<APValue*>(this)->getComplexFloatImag();
@ -454,20 +489,20 @@ class APValue {
APValue &getVectorElt(unsigned I) {
assert(isVector() && "Invalid accessor");
assert(I < getVectorLength() && "Index out of range");
return ((Vec*)(char*)Data.buffer)->Elts[I];
return ((Vec *)(char *)&Data)->Elts[I];
}
const APValue &getVectorElt(unsigned I) const {
return const_cast<APValue*>(this)->getVectorElt(I);
}
unsigned getVectorLength() const {
assert(isVector() && "Invalid accessor");
return ((const Vec*)(const void *)Data.buffer)->NumElts;
return ((const Vec *)(const void *)&Data)->NumElts;
}
APValue &getArrayInitializedElt(unsigned I) {
assert(isArray() && "Invalid accessor");
assert(I < getArrayInitializedElts() && "Index out of range");
return ((Arr*)(char*)Data.buffer)->Elts[I];
return ((Arr *)(char *)&Data)->Elts[I];
}
const APValue &getArrayInitializedElt(unsigned I) const {
return const_cast<APValue*>(this)->getArrayInitializedElt(I);
@ -478,35 +513,37 @@ class APValue {
APValue &getArrayFiller() {
assert(isArray() && "Invalid accessor");
assert(hasArrayFiller() && "No array filler");
return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
return ((Arr *)(char *)&Data)->Elts[getArrayInitializedElts()];
}
const APValue &getArrayFiller() const {
return const_cast<APValue*>(this)->getArrayFiller();
}
unsigned getArrayInitializedElts() const {
assert(isArray() && "Invalid accessor");
return ((const Arr*)(const void *)Data.buffer)->NumElts;
return ((const Arr *)(const void *)&Data)->NumElts;
}
unsigned getArraySize() const {
assert(isArray() && "Invalid accessor");
return ((const Arr*)(const void *)Data.buffer)->ArrSize;
return ((const Arr *)(const void *)&Data)->ArrSize;
}
unsigned getStructNumBases() const {
assert(isStruct() && "Invalid accessor");
return ((const StructData*)(const char*)Data.buffer)->NumBases;
return ((const StructData *)(const char *)&Data)->NumBases;
}
unsigned getStructNumFields() const {
assert(isStruct() && "Invalid accessor");
return ((const StructData*)(const char*)Data.buffer)->NumFields;
return ((const StructData *)(const char *)&Data)->NumFields;
}
APValue &getStructBase(unsigned i) {
assert(isStruct() && "Invalid accessor");
return ((StructData*)(char*)Data.buffer)->Elts[i];
assert(i < getStructNumBases() && "base class index OOB");
return ((StructData *)(char *)&Data)->Elts[i];
}
APValue &getStructField(unsigned i) {
assert(isStruct() && "Invalid accessor");
return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
assert(i < getStructNumFields() && "field index OOB");
return ((StructData *)(char *)&Data)->Elts[getStructNumBases() + i];
}
const APValue &getStructBase(unsigned i) const {
return const_cast<APValue*>(this)->getStructBase(i);
@ -517,11 +554,11 @@ class APValue {
const FieldDecl *getUnionField() const {
assert(isUnion() && "Invalid accessor");
return ((const UnionData*)(const char*)Data.buffer)->Field;
return ((const UnionData *)(const char *)&Data)->Field;
}
APValue &getUnionValue() {
assert(isUnion() && "Invalid accessor");
return *((UnionData*)(char*)Data.buffer)->Value;
return *((UnionData *)(char *)&Data)->Value;
}
const APValue &getUnionValue() const {
return const_cast<APValue*>(this)->getUnionValue();
@ -533,119 +570,125 @@ class APValue {
const AddrLabelExpr* getAddrLabelDiffLHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
return ((const AddrLabelDiffData *)(const char *)&Data)->LHSExpr;
}
const AddrLabelExpr* getAddrLabelDiffRHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
return ((const AddrLabelDiffData *)(const char *)&Data)->RHSExpr;
}
void setInt(APSInt I) {
assert(isInt() && "Invalid accessor");
*(APSInt *)(char *)Data.buffer = std::move(I);
*(APSInt *)(char *)&Data = std::move(I);
}
void setFloat(APFloat F) {
assert(isFloat() && "Invalid accessor");
*(APFloat *)(char *)Data.buffer = std::move(F);
*(APFloat *)(char *)&Data = std::move(F);
}
void setFixedPoint(APFixedPoint FX) {
assert(isFixedPoint() && "Invalid accessor");
*(APFixedPoint *)(char *)Data.buffer = std::move(FX);
*(APFixedPoint *)(char *)&Data = std::move(FX);
}
void setVector(const APValue *E, unsigned N) {
assert(isVector() && "Invalid accessor");
((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
((Vec*)(char*)Data.buffer)->NumElts = N;
MutableArrayRef<APValue> InternalElts = setVectorUninit(N);
for (unsigned i = 0; i != N; ++i)
((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
InternalElts[i] = E[i];
}
void setComplexInt(APSInt R, APSInt I) {
assert(R.getBitWidth() == I.getBitWidth() &&
"Invalid complex int (type mismatch).");
assert(isComplexInt() && "Invalid accessor");
((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
((ComplexAPSInt *)(char *)&Data)->Real = std::move(R);
((ComplexAPSInt *)(char *)&Data)->Imag = std::move(I);
}
void setComplexFloat(APFloat R, APFloat I) {
assert(&R.getSemantics() == &I.getSemantics() &&
"Invalid complex float (type mismatch).");
assert(isComplexFloat() && "Invalid accessor");
((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
((ComplexAPFloat *)(char *)&Data)->Real = std::move(R);
((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
bool IsNullPtr);
void setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
bool IsNullPtr);
void setUnion(const FieldDecl *Field, const APValue &Value) {
assert(isUnion() && "Invalid accessor");
((UnionData*)(char*)Data.buffer)->Field = Field;
*((UnionData*)(char*)Data.buffer)->Value = Value;
}
void setUnion(const FieldDecl *Field, const APValue &Value);
void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
const AddrLabelExpr* RHSExpr) {
((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
}
/// Assign by swapping from a copy of the RHS.
APValue &operator=(APValue RHS) {
swap(RHS);
return *this;
((AddrLabelDiffData *)(char *)&Data)->LHSExpr = LHSExpr;
((AddrLabelDiffData *)(char *)&Data)->RHSExpr = RHSExpr;
}
private:
void DestroyDataAndMakeUninit();
void MakeInt() {
assert(isAbsent() && "Bad state change");
new ((void*)Data.buffer) APSInt(1);
new ((void *)&Data) APSInt(1);
Kind = Int;
}
void MakeFloat() {
assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) APFloat(0.0);
new ((void *)(char *)&Data) APFloat(0.0);
Kind = Float;
}
void MakeFixedPoint(APFixedPoint &&FX) {
assert(isAbsent() && "Bad state change");
new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
new ((void *)(char *)&Data) APFixedPoint(std::move(FX));
Kind = FixedPoint;
}
void MakeVector() {
assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) Vec();
new ((void *)(char *)&Data) Vec();
Kind = Vector;
}
void MakeComplexInt() {
assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) ComplexAPSInt();
new ((void *)(char *)&Data) ComplexAPSInt();
Kind = ComplexInt;
}
void MakeComplexFloat() {
assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) ComplexAPFloat();
new ((void *)(char *)&Data) ComplexAPFloat();
Kind = ComplexFloat;
}
void MakeLValue();
void MakeArray(unsigned InitElts, unsigned Size);
void MakeStruct(unsigned B, unsigned M) {
assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) StructData(B, M);
new ((void *)(char *)&Data) StructData(B, M);
Kind = Struct;
}
void MakeUnion() {
assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) UnionData();
new ((void *)(char *)&Data) UnionData();
Kind = Union;
}
void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path);
void MakeAddrLabelDiff() {
assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) AddrLabelDiffData();
new ((void *)(char *)&Data) AddrLabelDiffData();
Kind = AddrLabelDiff;
}
private:
/// The following functions are used as part of initialization, during
/// deserialization and importing. Reserve the space so that it can be
/// filled in by those steps.
MutableArrayRef<APValue> setVectorUninit(unsigned N) {
assert(isVector() && "Invalid accessor");
Vec *V = ((Vec *)(char *)&Data);
V->Elts = new APValue[N];
V->NumElts = N;
return {V->Elts, V->NumElts};
}
MutableArrayRef<LValuePathEntry>
setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size,
bool OnePastTheEnd, bool IsNullPtr);
MutableArrayRef<const CXXRecordDecl *>
setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember,
unsigned Size);
};
} // end namespace clang.

View File

@ -36,6 +36,7 @@
#include "clang/Basic/Linkage.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/ProfileList.h"
#include "clang/Basic/SanitizerBlacklist.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
@ -43,6 +44,7 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/MapVector.h"
@ -73,6 +75,8 @@
namespace llvm {
class APFixedPoint;
class FixedPointSemantics;
struct fltSemantics;
template <typename T, unsigned N> class SmallPtrSet;
@ -80,7 +84,6 @@ template <typename T, unsigned N> class SmallPtrSet;
namespace clang {
class APFixedPoint;
class APValue;
class ASTMutationListener;
class ASTRecordLayout;
@ -98,7 +101,6 @@ class ParentMapContext;
class DynTypedNode;
class DynTypedNodeList;
class Expr;
class FixedPointSemantics;
class GlobalDecl;
class MangleContext;
class MangleNumberingContext;
@ -170,6 +172,16 @@ struct TypeInfo {
: Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
};
struct TypeInfoChars {
CharUnits Width;
CharUnits Align;
bool AlignIsRequired : 1;
TypeInfoChars() : AlignIsRequired(false) {}
TypeInfoChars(CharUnits Width, CharUnits Align, bool AlignIsRequired)
: Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
};
/// Holds long-lived AST nodes (such as types and decls) that can be
/// referred to throughout the semantic analysis of a file.
class ASTContext : public RefCountedBase<ASTContext> {
@ -278,8 +290,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Mapping from GUIDs to the corresponding MSGuidDecl.
mutable llvm::FoldingSet<MSGuidDecl> MSGuidDecls;
/// Used to cleanups APValues stored in the AST.
mutable llvm::SmallVector<APValue *, 0> APValueCleanups;
/// Mapping from APValues to the corresponding TemplateParamObjects.
mutable llvm::FoldingSet<TemplateParamObjectDecl> TemplateParamObjectDecls;
/// A cache mapping a string value to a StringLiteral object with the same
/// value.
@ -555,6 +567,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// should be imbued with the XRay "always" or "never" attributes.
std::unique_ptr<XRayFunctionFilter> XRayFilter;
/// ProfileList object that is used by the profile instrumentation
/// to decide which entities should be instrumented.
std::unique_ptr<ProfileList> ProfList;
/// The allocator used to create AST objects.
///
/// AST objects are never destructed; rather, all memory associated with the
@ -562,7 +578,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::BumpPtrAllocator BumpAlloc;
/// Allocator for partial diagnostics.
PartialDiagnostic::StorageAllocator DiagAllocator;
PartialDiagnostic::DiagStorageAllocator DiagAllocator;
/// The current C++ ABI.
std::unique_ptr<CXXABI> ABI;
@ -641,7 +657,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Return the total memory used for various side tables.
size_t getSideTableAllocatedMemory() const;
PartialDiagnostic::StorageAllocator &getDiagAllocator() {
PartialDiagnostic::DiagStorageAllocator &getDiagAllocator() {
return DiagAllocator;
}
@ -664,6 +680,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
const LangOptions& getLangOpts() const { return LangOpts; }
// If this condition is false, typo correction must be performed eagerly
// rather than delayed in many places, as it makes use of dependent types.
// the condition is false for clang's C-only codepath, as it doesn't support
// dependent types yet.
bool isDependenceAllowed() const {
return LangOpts.CPlusPlus || LangOpts.RecoveryAST;
}
const SanitizerBlacklist &getSanitizerBlacklist() const {
return *SanitizerBL;
}
@ -672,6 +696,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
return *XRayFilter;
}
const ProfileList &getProfileList() const { return *ProfList; }
DiagnosticsEngine &getDiagnostics() const;
FullSourceLoc getFullLoc(SourceLocation Loc) const {
@ -988,6 +1014,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
#define SVE_TYPE(Name, Id, SingletonId) \
CanQualType SingletonId;
#include "clang/Basic/AArch64SVEACLETypes.def"
#define PPC_VECTOR_TYPE(Name, Id, Size) \
CanQualType Id##Ty;
#include "clang/Basic/PPCTypes.def"
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
@ -1000,6 +1029,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
// Implicitly-declared type 'struct _GUID'.
mutable TagDecl *MSGuidTagDecl = nullptr;
/// Keep track of CUDA/HIP static device variables referenced by host code.
llvm::DenseSet<const VarDecl *> CUDAStaticDeviceVarReferencedByHost;
ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
SelectorTable &sels, Builtin::Context &builtins);
ASTContext(const ASTContext &) = delete;
@ -1406,7 +1438,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Return the unique reference to the type for the specified
/// typedef-name decl.
QualType getTypedefType(const TypedefNameDecl *Decl,
QualType Canon = QualType()) const;
QualType Underlying = QualType()) const;
QualType getRecordType(const RecordDecl *Decl) const;
@ -1981,9 +2013,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
unsigned char getFixedPointScale(QualType Ty) const;
unsigned char getFixedPointIBits(QualType Ty) const;
FixedPointSemantics getFixedPointSemantics(QualType Ty) const;
APFixedPoint getFixedPointMax(QualType Ty) const;
APFixedPoint getFixedPointMin(QualType Ty) const;
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const;
llvm::APFixedPoint getFixedPointMax(QualType Ty) const;
llvm::APFixedPoint getFixedPointMin(QualType Ty) const;
DeclarationNameInfo getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const;
@ -2022,6 +2054,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
GE_Missing_ucontext
};
QualType DecodeTypeStr(const char *&Str, const ASTContext &Context,
ASTContext::GetBuiltinTypeError &Error,
bool &RequireICE, bool AllowTypeModifiers) const;
/// Return the type for the specified builtin.
///
/// If \p IntegerConstantArgs is non-null, it is filled in with a bitmask of
@ -2054,6 +2090,15 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// types.
bool areCompatibleVectorTypes(QualType FirstVec, QualType SecondVec);
/// Return true if the given types are an SVE builtin and a VectorType that
/// is a fixed-length representation of the SVE builtin for a specific
/// vector-length.
bool areCompatibleSveTypes(QualType FirstType, QualType SecondType);
/// Return true if the given vector types are lax-compatible SVE vector types,
/// false otherwise.
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType);
/// Return true if the type has been explicitly qualified with ObjC ownership.
/// A type may be implicitly qualified with ownership under ObjC ARC, and in
/// some cases the compiler treats these differently.
@ -2125,16 +2170,25 @@ class ASTContext : public RefCountedBase<ASTContext> {
}
unsigned getTypeUnadjustedAlign(const Type *T) const;
/// Return the ABI-specified alignment of a type, in bits, or 0 if
/// Return the alignment of a type, in bits, or 0 if
/// the type is incomplete and we cannot determine the alignment (for
/// example, from alignment attributes).
unsigned getTypeAlignIfKnown(QualType T) const;
/// example, from alignment attributes). The returned alignment is the
/// Preferred alignment if NeedsPreferredAlignment is true, otherwise is the
/// ABI alignment.
unsigned getTypeAlignIfKnown(QualType T,
bool NeedsPreferredAlignment = false) const;
/// Return the ABI-specified alignment of a (complete) type \p T, in
/// characters.
CharUnits getTypeAlignInChars(QualType T) const;
CharUnits getTypeAlignInChars(const Type *T) const;
/// Return the PreferredAlignment of a (complete) type \p T, in
/// characters.
CharUnits getPreferredTypeAlignInChars(QualType T) const {
return toCharUnitsFromBits(getPreferredTypeAlign(T));
}
/// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a type,
/// in characters, before alignment adjustments. This method does not work on
/// incomplete types.
@ -2143,10 +2197,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
// getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
// type is a record, its data size is returned.
std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const;
std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
TypeInfoChars getTypeInfoInChars(const Type *T) const;
TypeInfoChars getTypeInfoInChars(QualType T) const;
/// Determine if the alignment the type has was required using an
/// alignment attribute.
@ -2157,7 +2211,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// the current target, in bits.
///
/// This can be different than the ABI alignment in cases where it is
/// beneficial for performance to overalign a data type.
/// beneficial for performance or backwards compatibility preserving to
/// overalign a data type. (Note: despite the name, the preferred alignment
/// is ABI-impacting, and not an optimization.)
unsigned getPreferredTypeAlign(QualType T) const {
return getPreferredTypeAlign(T.getTypePtr());
}
unsigned getPreferredTypeAlign(const Type *T) const;
/// Return the default alignment for __attribute__((aligned)) on
@ -2250,6 +2309,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
const ObjCImplementationDecl *ID,
const ObjCIvarDecl *Ivar) const;
/// Find the 'this' offset for the member path in a pointer-to-member
/// APValue.
CharUnits getMemberPointerPathAdjustment(const APValue &MP) const;
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
VTableContextBase *getVTableContext();
@ -2345,12 +2408,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
return (*SuperTnullability == NullabilityKind::NonNull &&
*SubTnullability == NullabilityKind::Nullable);
}
else {
// For the return type, it's okay for the superclass method to specify
// "nullable" and the subclass method specify "nonnull"
return (*SuperTnullability == NullabilityKind::Nullable &&
*SubTnullability == NullabilityKind::NonNull);
}
// For the return type, it's okay for the superclass method to specify
// "nullable" and the subclass method specify "nonnull"
return (*SuperTnullability == NullabilityKind::Nullable &&
*SubTnullability == NullabilityKind::NonNull);
}
return true;
}
@ -2830,6 +2891,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// GUID value.
MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const;
/// Return the template parameter object of the given type with the given
/// value.
TemplateParamObjectDecl *getTemplateParamObjectDecl(QualType T,
const APValue &V) const;
/// Parses the target attributes passed in, and returns only the ones that are
/// valid feature names.
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const;
@ -3025,13 +3091,12 @@ OPT_LIST(V)
};
struct SectionInfo {
DeclaratorDecl *Decl;
NamedDecl *Decl;
SourceLocation PragmaSectionLocation;
int SectionFlags;
SectionInfo() = default;
SectionInfo(DeclaratorDecl *Decl,
SourceLocation PragmaSectionLocation,
SectionInfo(NamedDecl *Decl, SourceLocation PragmaSectionLocation,
int SectionFlags)
: Decl(Decl), PragmaSectionLocation(PragmaSectionLocation),
SectionFlags(SectionFlags) {}
@ -3042,6 +3107,12 @@ OPT_LIST(V)
/// Return a new OMPTraitInfo object owned by this context.
OMPTraitInfo &getNewOMPTraitInfo();
/// Whether a C++ static variable may be externalized.
bool mayExternalizeStaticVar(const Decl *D) const;
/// Whether a C++ static variable should be externalized.
bool shouldExternalizeStaticVar(const Decl *D) const;
private:
/// All OMPTraitInfo objects live in this collection, one per
/// `pragma omp [begin] declare variant` directive.
@ -3049,8 +3120,8 @@ OPT_LIST(V)
};
/// Insertion operator for diagnostics.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const ASTContext::SectionInfo &Section);
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const ASTContext::SectionInfo &Section);
/// Utility function for constructing a nullary selector.
inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {

View File

@ -27,9 +27,9 @@ class Type;
#include "clang/AST/TypeNodes.inc"
class CXXCtorInitializer;
class OMPClause;
#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) class Class;
#include "llvm/Frontend/OpenMP/OMP.inc"
} // end namespace clang

View File

@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
#define LLVM_CLANG_AST_ASTIMPORTER_H
#include "clang/AST/APValue.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExprCXX.h"
@ -503,6 +504,13 @@ class TypeSourceInfo;
/// "to" context, or the import error.
llvm::Expected<CXXBaseSpecifier *> Import(const CXXBaseSpecifier *FromSpec);
/// Import the given APValue from the "from" context into
/// the "to" context.
///
/// \return the equivalent APValue in the "to" context or the import
/// error.
llvm::Expected<APValue> Import(const APValue &FromValue);
/// Import the definition of the given declaration, including all of
/// the declarations it contains.
LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From);

View File

@ -82,8 +82,12 @@ class ASTNodeTraverser
bool getDeserialize() const { return Deserialize; }
void SetTraversalKind(TraversalKind TK) { Traversal = TK; }
TraversalKind GetTraversalKind() const { return Traversal; }
void Visit(const Decl *D) {
if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isImplicit())
return;
getNodeDelegate().AddChild([=] {
getNodeDelegate().Visit(D);
if (!D)
@ -100,6 +104,14 @@ class ASTNodeTraverser
// Decls within functions are visited by the body.
if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
if (Traversal != TK_AsIs) {
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
auto SK = CTSD->getSpecializationKind();
if (SK == TSK_ExplicitInstantiationDeclaration ||
SK == TSK_ExplicitInstantiationDefinition)
return;
}
}
if (const auto *DC = dyn_cast<DeclContext>(D))
dumpDeclContext(DC);
}
@ -114,9 +126,6 @@ class ASTNodeTraverser
switch (Traversal) {
case TK_AsIs:
break;
case TK_IgnoreImplicitCastsAndParentheses:
S = E->IgnoreParenImpCasts();
break;
case TK_IgnoreUnlessSpelledInSource:
S = E->IgnoreUnlessSpelledInSource();
break;
@ -135,7 +144,9 @@ class ASTNodeTraverser
if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S))
return;
if (isa<LambdaExpr>(S) && Traversal == TK_IgnoreUnlessSpelledInSource)
if (Traversal == TK_IgnoreUnlessSpelledInSource &&
isa<LambdaExpr, CXXForRangeStmt, CallExpr,
CXXRewrittenBinaryOperator>(S))
return;
for (const Stmt *SubStmt : S->children())
@ -176,6 +187,8 @@ class ASTNodeTraverser
}
void Visit(const CXXCtorInitializer *Init) {
if (Traversal == TK_IgnoreUnlessSpelledInSource && !Init->isWritten())
return;
getNodeDelegate().AddChild([=] {
getNodeDelegate().Visit(Init);
Visit(Init->getInit());
@ -392,6 +405,9 @@ class ASTNodeTraverser
if (const Expr *TRC = D->getTrailingRequiresClause())
Visit(TRC);
if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted())
return;
if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
for (const auto *I : C->inits())
Visit(I);
@ -408,6 +424,9 @@ class ASTNodeTraverser
}
void VisitVarDecl(const VarDecl *D) {
if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isCXXForRangeDecl())
return;
if (D->hasInit())
Visit(D->getInit());
}
@ -481,8 +500,10 @@ class ASTNodeTraverser
Visit(D->getTemplatedDecl());
for (const auto *Child : D->specializations())
dumpTemplateDeclSpecialization(Child);
if (Traversal == TK_AsIs) {
for (const auto *Child : D->specializations())
dumpTemplateDeclSpecialization(Child);
}
}
void VisitTypeAliasDecl(const TypeAliasDecl *D) {
@ -543,9 +564,7 @@ class ASTNodeTraverser
void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
if (const auto *TC = D->getTypeConstraint())
if (TC->hasExplicitTemplateArgs())
for (const auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
dumpTemplateArgumentLoc(ArgLoc);
Visit(TC->getImmediatelyDeclaredConstraint());
if (D->hasDefaultArgument())
Visit(D->getDefaultArgument(), SourceRange(),
D->getDefaultArgStorage().getInheritedFrom(),
@ -574,6 +593,12 @@ class ASTNodeTraverser
Visit(D->getConstraintExpr());
}
void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
if (CSE->hasExplicitTemplateArgs())
for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
dumpTemplateArgumentLoc(ArgLoc);
}
void VisitUsingShadowDecl(const UsingShadowDecl *D) {
if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
Visit(TD->getTypeForDecl());
@ -702,6 +727,35 @@ class ASTNodeTraverser
Visit(CatchParam);
}
void VisitCXXForRangeStmt(const CXXForRangeStmt *Node) {
if (Traversal == TK_IgnoreUnlessSpelledInSource) {
Visit(Node->getInit());
Visit(Node->getLoopVariable());
Visit(Node->getRangeInit());
Visit(Node->getBody());
}
}
void VisitCallExpr(const CallExpr *Node) {
for (const auto *Child :
make_filter_range(Node->children(), [this](const Stmt *Child) {
if (Traversal != TK_IgnoreUnlessSpelledInSource)
return false;
return !isa<CXXDefaultArgExpr>(Child);
})) {
Visit(Child);
}
}
void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *Node) {
if (Traversal == TK_IgnoreUnlessSpelledInSource) {
Visit(Node->getLHS());
Visit(Node->getRHS());
} else {
ConstStmtVisitor<Derived>::VisitCXXRewrittenBinaryOperator(Node);
}
}
void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
Visit(TA.getAsExpr());
}

View File

@ -97,6 +97,13 @@ struct StructuralEquivalenceContext {
/// \c VisitedDecls members) and can cause faulty equivalent results.
bool IsEquivalent(QualType T1, QualType T2);
/// Determine whether the two statements are structurally equivalent.
/// Implementation functions (all static functions in
/// ASTStructuralEquivalence.cpp) must never call this function because that
/// will wreak havoc the internal state (\c DeclsToCheck and
/// \c VisitedDecls members) and can cause faulty equivalent results.
bool IsEquivalent(Stmt *S1, Stmt *S2);
/// Find the index of the given anonymous struct/union within its
/// context.
///

View File

@ -40,10 +40,6 @@ enum TraversalKind {
/// Will traverse all child nodes.
TK_AsIs,
/// Will not traverse implicit casts and parentheses.
/// Corresponds to Expr::IgnoreParenImpCasts()
TK_IgnoreImplicitCastsAndParentheses,
/// Ignore AST nodes not written in the source
TK_IgnoreUnlessSpelledInSource
};
@ -104,6 +100,8 @@ class ASTNodeKind {
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
ASTNodeKind Kind2);
ASTNodeKind getCladeKind() const;
/// Hooks for using ASTNodeKind as a key in a DenseMap.
struct DenseMapInfo {
// ASTNodeKind() is a good empty key because it is represented as a 0.
@ -132,6 +130,7 @@ class ASTNodeKind {
enum NodeKindId {
NKI_None,
NKI_TemplateArgument,
NKI_TemplateArgumentLoc,
NKI_TemplateName,
NKI_NestedNameSpecifierLoc,
NKI_QualType,
@ -150,8 +149,9 @@ class ASTNodeKind {
#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
#include "clang/AST/TypeNodes.inc"
NKI_OMPClause,
#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
#include "llvm/Frontend/OpenMP/OMPKinds.def"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
#include "llvm/Frontend/OpenMP/OMP.inc"
NKI_NumberOfKinds
};
@ -191,6 +191,7 @@ class ASTNodeKind {
};
KIND_TO_KIND_ID(CXXCtorInitializer)
KIND_TO_KIND_ID(TemplateArgument)
KIND_TO_KIND_ID(TemplateArgumentLoc)
KIND_TO_KIND_ID(TemplateName)
KIND_TO_KIND_ID(NestedNameSpecifier)
KIND_TO_KIND_ID(NestedNameSpecifierLoc)
@ -207,8 +208,9 @@ KIND_TO_KIND_ID(CXXBaseSpecifier)
#include "clang/AST/StmtNodes.inc"
#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
#include "clang/AST/TypeNodes.inc"
#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
#include "llvm/Frontend/OpenMP/OMPKinds.def"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
#include "llvm/Frontend/OpenMP/OMP.inc"
#undef KIND_TO_KIND_ID
inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
@ -248,9 +250,8 @@ class DynTypedNode {
/// in the \c DynTypedNode, and the returned pointer points at
/// the storage inside DynTypedNode. For those nodes, do not
/// use the pointer outside the scope of the DynTypedNode.
template <typename T>
const T *get() const {
return BaseConverter<T>::get(NodeKind, Storage.buffer);
template <typename T> const T *get() const {
return BaseConverter<T>::get(NodeKind, &Storage);
}
/// Retrieve the stored node as type \c T.
@ -258,7 +259,7 @@ class DynTypedNode {
/// Similar to \c get(), but asserts that the type is what we are expecting.
template <typename T>
const T &getUnchecked() const {
return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
return BaseConverter<T>::getUnchecked(NodeKind, &Storage);
}
ASTNodeKind getNodeKind() const { return NodeKind; }
@ -270,7 +271,7 @@ class DynTypedNode {
/// method returns NULL.
const void *getMemoizationData() const {
return NodeKind.hasPointerIdentity()
? *reinterpret_cast<void *const *>(Storage.buffer)
? *reinterpret_cast<void *const *>(&Storage)
: nullptr;
}
@ -392,12 +393,12 @@ class DynTypedNode {
/// Converter that uses dyn_cast<T> from a stored BaseT*.
template <typename T, typename BaseT> struct DynCastPtrConverter {
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
static const T *get(ASTNodeKind NodeKind, const void *Storage) {
if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
return &getUnchecked(NodeKind, Storage);
return nullptr;
}
static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
return *cast<T>(static_cast<const BaseT *>(
*reinterpret_cast<const void *const *>(Storage)));
@ -405,19 +406,19 @@ class DynTypedNode {
static DynTypedNode create(const BaseT &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNode(Node);
new (Result.Storage.buffer) const void *(&Node);
new (&Result.Storage) const void *(&Node);
return Result;
}
};
/// Converter that stores T* (by pointer).
template <typename T> struct PtrConverter {
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
static const T *get(ASTNodeKind NodeKind, const void *Storage) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
return &getUnchecked(NodeKind, Storage);
return nullptr;
}
static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
return *static_cast<const T *>(
*reinterpret_cast<const void *const *>(Storage));
@ -425,26 +426,26 @@ class DynTypedNode {
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
new (Result.Storage.buffer) const void *(&Node);
new (&Result.Storage) const void *(&Node);
return Result;
}
};
/// Converter that stores T (by value).
template <typename T> struct ValueConverter {
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
static const T *get(ASTNodeKind NodeKind, const void *Storage) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
return reinterpret_cast<const T *>(Storage);
return nullptr;
}
static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) {
static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
return *reinterpret_cast<const T *>(Storage);
}
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
new (Result.Storage.buffer) T(Node);
new (&Result.Storage) T(Node);
return Result;
}
};
@ -456,12 +457,13 @@ class DynTypedNode {
/// Note that we can store \c Decls, \c Stmts, \c Types,
/// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
/// guaranteed to be unique pointers pointing to dedicated storage in the AST.
/// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and
/// \c TemplateArguments on the other hand do not have storage or unique
/// pointers and thus need to be stored by value.
/// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs,
/// \c TemplateArguments and \c TemplateArgumentLocs on the other hand do not
/// have storage or unique pointers and thus need to be stored by value.
llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
NestedNameSpecifierLoc, QualType,
TypeLoc> Storage;
TemplateArgumentLoc, NestedNameSpecifierLoc,
QualType, TypeLoc>
Storage;
};
template <typename T>
@ -496,6 +498,10 @@ template <>
struct DynTypedNode::BaseConverter<
TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
template <>
struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
: public ValueConverter<TemplateArgumentLoc> {};
template <>
struct DynTypedNode::BaseConverter<
TemplateName, void> : public ValueConverter<TemplateName> {};
@ -527,20 +533,6 @@ template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
}
};
// Previously these types were defined in the clang::ast_type_traits namespace.
// Provide typedefs so that legacy code can be fixed asynchronously.
namespace ast_type_traits {
using DynTypedNode = ::clang::DynTypedNode;
using ASTNodeKind = ::clang::ASTNodeKind;
using TraversalKind = ::clang::TraversalKind;
constexpr TraversalKind TK_AsIs = ::clang::TK_AsIs;
constexpr TraversalKind TK_IgnoreImplicitCastsAndParentheses =
::clang::TK_IgnoreImplicitCastsAndParentheses;
constexpr TraversalKind TK_IgnoreUnlessSpelledInSource =
::clang::TK_IgnoreUnlessSpelledInSource;
} // namespace ast_type_traits
} // end namespace clang
namespace llvm {

View File

@ -177,6 +177,40 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
return llvm::APInt(bitWidth, numWords, &data[0]);
}
llvm::FixedPointSemantics readFixedPointSemantics() {
unsigned width = asImpl().readUInt32();
unsigned scale = asImpl().readUInt32();
unsigned tmp = asImpl().readUInt32();
bool isSigned = tmp & 0x1;
bool isSaturated = tmp & 0x2;
bool hasUnsignedPadding = tmp & 0x4;
return llvm::FixedPointSemantics(width, scale, isSigned, isSaturated,
hasUnsignedPadding);
}
APValue::LValuePathSerializationHelper readLValuePathSerializationHelper(
SmallVectorImpl<APValue::LValuePathEntry> &path) {
auto elemTy = asImpl().readQualType();
unsigned pathLength = asImpl().readUInt32();
for (unsigned i = 0; i < pathLength; ++i) {
if (elemTy->template getAs<RecordType>()) {
unsigned int_ = asImpl().readUInt32();
Decl *decl = asImpl().template readDeclAs<Decl>();
if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
elemTy = getASTContext().getRecordType(recordDecl);
else
elemTy = cast<ValueDecl>(decl)->getType();
path.push_back(
APValue::LValuePathEntry(APValue::BaseOrMemberType(decl, int_)));
} else {
elemTy = getASTContext().getAsArrayType(elemTy)->getElementType();
path.push_back(
APValue::LValuePathEntry::ArrayIndex(asImpl().readUInt32()));
}
}
return APValue::LValuePathSerializationHelper(path, elemTy);
}
Qualifiers readQualifiers() {
static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t),
"update this if the value size changes");

View File

@ -9,6 +9,7 @@
#ifndef CLANG_AST_ABSTRACTBASICWRITER_H
#define CLANG_AST_ABSTRACTBASICWRITER_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
namespace clang {
@ -121,6 +122,7 @@ template <class Impl>
class DataStreamBasicWriter : public BasicWriterBase<Impl> {
protected:
using BasicWriterBase<Impl>::asImpl;
DataStreamBasicWriter(ASTContext &ctx) : BasicWriterBase<Impl>(ctx) {}
public:
/// Implement property-find by ignoring it. We rely on properties being
@ -163,6 +165,39 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
asImpl().writeUInt64(words[i]);
}
void writeFixedPointSemantics(const llvm::FixedPointSemantics &sema) {
asImpl().writeUInt32(sema.getWidth());
asImpl().writeUInt32(sema.getScale());
asImpl().writeUInt32(sema.isSigned() | sema.isSaturated() << 1 |
sema.hasUnsignedPadding() << 2);
}
void writeLValuePathSerializationHelper(
APValue::LValuePathSerializationHelper lvaluePath) {
ArrayRef<APValue::LValuePathEntry> path = lvaluePath.Path;
QualType elemTy = lvaluePath.getType();
asImpl().writeQualType(elemTy);
asImpl().writeUInt32(path.size());
auto &ctx = ((BasicWriterBase<Impl> *)this)->getASTContext();
for (auto elem : path) {
if (elemTy->getAs<RecordType>()) {
asImpl().writeUInt32(elem.getAsBaseOrMember().getInt());
const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
asImpl().writeDeclRef(recordDecl);
elemTy = ctx.getRecordType(recordDecl);
} else {
const auto *valueDecl = cast<ValueDecl>(baseOrMember);
asImpl().writeDeclRef(valueDecl);
elemTy = valueDecl->getType();
}
} else {
asImpl().writeUInt32(elem.getAsArrayIndex());
elemTy = ctx.getAsArrayType(elemTy)->getElementType();
}
}
}
void writeQualifiers(Qualifiers value) {
static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t),
"update this if the value size changes");

View File

@ -162,6 +162,21 @@ class InheritableAttr : public Attr {
}
};
class DeclOrStmtAttr : public InheritableAttr {
protected:
DeclOrStmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
attr::Kind AK, bool IsLateParsed,
bool InheritEvenIfAlreadyPresent)
: InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
InheritEvenIfAlreadyPresent) {}
public:
static bool classof(const Attr *A) {
return A->getKind() >= attr::FirstDeclOrStmtAttr &&
A->getKind() <= attr::LastDeclOrStmtAttr;
}
};
class InheritableParamAttr : public InheritableAttr {
protected:
InheritableParamAttr(ASTContext &Context,
@ -259,7 +274,10 @@ class ParamIdx {
/// Construct from a result from \c serialize.
static ParamIdx deserialize(SerialType S) {
ParamIdx P(*reinterpret_cast<ParamIdx *>(&S));
// Using this two-step static_cast via void * instead of reinterpret_cast
// silences a -Wstrict-aliasing false positive from GCC7 and earlier.
void *ParamIdxPtr = static_cast<void *>(&S);
ParamIdx P(*static_cast<ParamIdx *>(ParamIdxPtr));
assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
return P;
}
@ -334,29 +352,28 @@ static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
struct ParsedTargetAttr {
std::vector<std::string> Features;
StringRef Architecture;
StringRef Tune;
StringRef BranchProtection;
bool DuplicateArchitecture = false;
bool DuplicateTune = false;
bool operator ==(const ParsedTargetAttr &Other) const {
return DuplicateArchitecture == Other.DuplicateArchitecture &&
Architecture == Other.Architecture && Features == Other.Features;
DuplicateTune == Other.DuplicateTune &&
Architecture == Other.Architecture &&
Tune == Other.Tune &&
BranchProtection == Other.BranchProtection &&
Features == Other.Features;
}
};
#include "clang/AST/Attrs.inc"
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const Attr *At) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const Attr *At) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
DiagnosticsEngine::ak_attr);
return DB;
}
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
const Attr *At) {
PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
DiagnosticsEngine::ak_attr);
return PD;
}
} // end namespace clang
#endif

View File

@ -149,12 +149,6 @@ class CXXBasePaths {
/// to help build the set of paths.
CXXBasePath ScratchPath;
/// Array of the declarations that have been found. This
/// array is constructed only if needed, e.g., to iterate over the
/// results within LookupResult.
std::unique_ptr<NamedDecl *[]> DeclsFound;
unsigned NumDeclsFound = 0;
/// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
/// ambiguous paths while it is looking for a path from a derived
/// type to a base type.
@ -170,8 +164,6 @@ class CXXBasePaths {
/// is also recorded.
bool DetectVirtual;
void ComputeDeclsFound();
bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
CXXRecordDecl::BaseMatchesCallback BaseMatches,
bool LookupInDependent = false);
@ -198,8 +190,6 @@ class CXXBasePaths {
using decl_range = llvm::iterator_range<decl_iterator>;
decl_range found_decls();
/// Determine whether the path from the most-derived type to the
/// given base type is ambiguous (i.e., it refers to multiple subobjects of
/// the same base type).

View File

@ -131,6 +131,10 @@ FIELD(HasUninitializedFields, 1, NO_MERGE)
/// constructors from a base class.
FIELD(HasInheritedConstructor, 1, NO_MERGE)
/// True if there are any member using-declarations that inherit
/// default constructors from a base class.
FIELD(HasInheritedDefaultConstructor, 1, NO_MERGE)
/// True if there are any member using-declarations named
/// 'operator='.
FIELD(HasInheritedAssignment, 1, NO_MERGE)
@ -210,6 +214,9 @@ FIELD(DefaultedDestructorIsConstexpr, 1, NO_MERGE)
/// member or base class of non-literal or volatile type.
FIELD(HasNonLiteralTypeFieldsOrBases, 1, NO_MERGE)
/// True if this class is a structural type, assuming it is a literal type.
FIELD(StructuralIfLiteral, 1, NO_MERGE)
/// Whether we have a C++11 user-provided default constructor (not
/// explicitly deleted or defaulted).
FIELD(UserProvidedDefaultConstructor, 1, NO_MERGE)

View File

@ -215,8 +215,8 @@ inline CanQualType Type::getCanonicalTypeUnqualified() const {
return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
CanQualType T) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
CanQualType T) {
DB << static_cast<QualType>(T);
return DB;
}

View File

@ -62,13 +62,6 @@ class Token {
/// The actual kind of the token.
tok::TokenKind Kind;
/// Length of the token spelling in comment. Can be 0 for synthenized
/// tokens.
unsigned Length;
/// Contains text value associated with a token.
const char *TextPtr;
/// Integer value associated with a token.
///
/// If the token is a known command, contains command ID and TextPtr is
@ -76,6 +69,13 @@ class Token {
/// contains the length of the string that starts at TextPtr.
unsigned IntVal;
/// Length of the token spelling in comment. Can be 0 for synthenized
/// tokens.
unsigned Length;
/// Contains text value associated with a token.
const char *TextPtr;
public:
SourceLocation getLocation() const LLVM_READONLY { return Loc; }
void setLocation(SourceLocation SL) { Loc = SL; }
@ -232,7 +232,6 @@ class Lexer {
const char *const BufferStart;
const char *const BufferEnd;
SourceLocation FileLoc;
const char *BufferPtr;
@ -240,7 +239,14 @@ class Lexer {
/// to newline or BufferEnd, for C comments points to star in '*/'.
const char *CommentEnd;
enum LexerCommentState {
SourceLocation FileLoc;
/// If true, the commands, html tags, etc will be parsed and reported as
/// separate tokens inside the comment body. If false, the comment text will
/// be parsed into text and newline tokens.
bool ParseCommands;
enum LexerCommentState : uint8_t {
LCS_BeforeComment,
LCS_InsideBCPLComment,
LCS_InsideCComment,
@ -250,7 +256,7 @@ class Lexer {
/// Low-level lexer state, track if we are inside or outside of comment.
LexerCommentState CommentState;
enum LexerState {
enum LexerState : uint8_t {
/// Lexing normal comment text
LS_Normal,
@ -280,11 +286,6 @@ class Lexer {
/// command, including command marker.
SmallString<16> VerbatimBlockEndCommandName;
/// If true, the commands, html tags, etc will be parsed and reported as
/// separate tokens inside the comment body. If false, the comment text will
/// be parsed into text and newline tokens.
bool ParseCommands;
/// Given a character reference name (e.g., "lt"), return the character that
/// it stands for (e.g., "<").
StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;

View File

@ -70,6 +70,7 @@ class CXXPseudoDestructorExpr;
class OverloadExpr;
class DependentScopeDeclRefExpr;
class CXXConstructExpr;
class CXXDefaultInitExpr;
class LambdaExpr;
class CXXUnresolvedConstructExpr;
class CXXDependentScopeMemberExpr;
@ -106,7 +107,7 @@ class ObjCMessageExpr;
ExprDependence computeDependence(FullExpr *E);
ExprDependence computeDependence(OpaqueValueExpr *E);
ExprDependence computeDependence(ParenExpr *E);
ExprDependence computeDependence(UnaryOperator *E);
ExprDependence computeDependence(UnaryOperator *E, const ASTContext &Ctx);
ExprDependence computeDependence(UnaryExprOrTypeTraitExpr *E);
ExprDependence computeDependence(ArraySubscriptExpr *E);
ExprDependence computeDependence(MatrixSubscriptExpr *E);
@ -153,6 +154,7 @@ ExprDependence computeDependence(OverloadExpr *E, bool KnownDependent,
bool KnownContainsUnexpandedParameterPack);
ExprDependence computeDependence(DependentScopeDeclRefExpr *E);
ExprDependence computeDependence(CXXConstructExpr *E);
ExprDependence computeDependence(CXXDefaultInitExpr *E);
ExprDependence computeDependence(LambdaExpr *E,
bool ContainsUnexpandedParameterPack);
ExprDependence computeDependence(CXXUnresolvedConstructExpr *E);

View File

@ -265,10 +265,25 @@ class NamedDecl : public Decl {
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
/// Pretty-print the unqualified name of this declaration. Can be overloaded
/// by derived classes to provide a more user-friendly name when appropriate.
virtual void printName(raw_ostream &os) const;
/// Get the actual, stored name of the declaration, which may be a special
/// name.
///
/// Note that generally in diagnostics, the non-null \p NamedDecl* itself
/// should be sent into the diagnostic instead of using the result of
/// \p getDeclName().
///
/// A \p DeclarationName in a diagnostic will just be streamed to the output,
/// which will directly result in a call to \p DeclarationName::print.
///
/// A \p NamedDecl* in a diagnostic will also ultimately result in a call to
/// \p DeclarationName::print, but with two customisation points along the
/// way (\p getNameForDiagnostic and \p printName). These are used to print
/// the template arguments if any, and to provide a user-friendly name for
/// some entities (such as unnamed variables and anonymous records).
DeclarationName getDeclName() const { return Name; }
/// Set the name of this declaration.
@ -788,18 +803,11 @@ struct EvaluatedStmt {
/// Whether this statement is being evaluated.
bool IsEvaluating : 1;
/// Whether we already checked whether this statement was an
/// integral constant expression.
bool CheckedICE : 1;
/// Whether we are checking whether this statement is an
/// integral constant expression.
bool CheckingICE : 1;
/// Whether this statement is an integral constant expression,
/// or in C++11, whether the statement is a constant expression. Only
/// valid if CheckedICE is true.
bool IsICE : 1;
/// Whether this variable is known to have constant initialization. This is
/// currently only computed in C++, for static / thread storage duration
/// variables that might have constant initialization and for variables that
/// are usable in constant expressions.
bool HasConstantInitialization : 1;
/// Whether this variable is known to have constant destruction. That is,
/// whether running the destructor on the initial value is a side-effect
@ -808,12 +816,18 @@ struct EvaluatedStmt {
/// non-trivial.
bool HasConstantDestruction : 1;
/// In C++98, whether the initializer is an ICE. This affects whether the
/// variable is usable in constant expressions.
bool HasICEInit : 1;
bool CheckedForICEInit : 1;
Stmt *Value;
APValue Evaluated;
EvaluatedStmt()
: WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
CheckingICE(false), IsICE(false), HasConstantDestruction(false) {}
: WasEvaluated(false), IsEvaluating(false),
HasConstantInitialization(false), HasConstantDestruction(false),
HasICEInit(false), CheckedForICEInit(false) {}
};
/// Represents a variable declaration or definition.
@ -1248,22 +1262,29 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// constant expression, according to the relevant language standard.
/// This only checks properties of the declaration, and does not check
/// whether the initializer is in fact a constant expression.
bool mightBeUsableInConstantExpressions(ASTContext &C) const;
///
/// This corresponds to C++20 [expr.const]p3's notion of a
/// "potentially-constant" variable.
bool mightBeUsableInConstantExpressions(const ASTContext &C) const;
/// Determine whether this variable's value can be used in a
/// constant expression, according to the relevant language standard,
/// including checking whether it was initialized by a constant expression.
bool isUsableInConstantExpressions(ASTContext &C) const;
bool isUsableInConstantExpressions(const ASTContext &C) const;
EvaluatedStmt *ensureEvaluatedStmt() const;
EvaluatedStmt *getEvaluatedStmt() const;
/// Attempt to evaluate the value of the initializer attached to this
/// declaration, and produce notes explaining why it cannot be evaluated or is
/// not a constant expression. Returns a pointer to the value if evaluation
/// succeeded, 0 otherwise.
/// declaration, and produce notes explaining why it cannot be evaluated.
/// Returns a pointer to the value if evaluation succeeded, 0 otherwise.
APValue *evaluateValue() const;
APValue *evaluateValue(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
private:
APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
bool IsConstantInitialization) const;
public:
/// Return the already-evaluated value of this variable's
/// initializer, or NULL if the value is not yet known. Returns pointer
/// to untyped APValue if the value could not be evaluated.
@ -1272,25 +1293,29 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
/// Evaluate the destruction of this variable to determine if it constitutes
/// constant destruction.
///
/// \pre isInitICE()
/// \pre hasConstantInitialization()
/// \return \c true if this variable has constant destruction, \c false if
/// not.
bool evaluateDestruction(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
/// Determines whether it is already known whether the
/// initializer is an integral constant expression or not.
bool isInitKnownICE() const;
/// Determines whether the initializer is an integral constant
/// expression, or in C++11, whether the initializer is a constant
/// expression.
/// Determine whether this variable has constant initialization.
///
/// \pre isInitKnownICE()
bool isInitICE() const;
/// This is only set in two cases: when the language semantics require
/// constant initialization (globals in C and some globals in C++), and when
/// the variable is usable in constant expressions (constexpr, const int, and
/// reference variables in C++).
bool hasConstantInitialization() const;
/// Determine whether the value of the initializer attached to this
/// declaration is an integral constant expression.
bool checkInitIsICE() const;
/// Determine whether the initializer of this variable is an integer constant
/// expression. For use in C++98, where this affects whether the variable is
/// usable in constant expressions.
bool hasICEInitializer(const ASTContext &Context) const;
/// Evaluate the initializer of this variable to determine whether it's a
/// constant initializer. Should only be called once, after completing the
/// definition of the variable.
bool checkForConstantInitialization(
SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
void setInitStyle(InitializationStyle Style) {
VarDeclBits.InitStyle = Style;
@ -1639,6 +1664,9 @@ class ParmVarDecl : public VarDecl {
return ParmVarDeclBits.IsObjCMethodParam;
}
/// Determines whether this parameter is destroyed in the callee function.
bool isDestroyedInCallee() const;
unsigned getFunctionScopeDepth() const {
if (ParmVarDeclBits.IsObjCMethodParam) return 0;
return ParmVarDeclBits.ScopeDepthOrObjCQuals;
@ -1956,7 +1984,7 @@ class FunctionDecl : public DeclaratorDecl,
SourceLocation NLoc, DeclarationName N, QualType T,
TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false,
bool hasWrittenPrototype = true,
ConstexprSpecKind ConstexprKind = CSK_unspecified,
ConstexprSpecKind ConstexprKind = ConstexprSpecKind::Unspecified,
Expr *TrailingRequiresClause = nullptr) {
DeclarationNameInfo NameInfo(N, NLoc);
return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo, SC,
@ -2028,7 +2056,14 @@ class FunctionDecl : public DeclaratorDecl,
///
/// The variant that accepts a FunctionDecl pointer will set that function
/// declaration to the declaration that is a definition (if there is one).
bool isDefined(const FunctionDecl *&Definition) const;
///
/// \param CheckForPendingFriendDefinition If \c true, also check for friend
/// declarations that were instantiataed from function definitions.
/// Such a declaration behaves as if it is a definition for the
/// purpose of redefinition checking, but isn't actually a "real"
/// definition until its body is instantiated.
bool isDefined(const FunctionDecl *&Definition,
bool CheckForPendingFriendDefinition = false) const;
bool isDefined() const {
const FunctionDecl* Definition;
@ -2074,6 +2109,11 @@ class FunctionDecl : public DeclaratorDecl,
willHaveBody() || hasDefiningAttr();
}
/// Determine whether this specific declaration of the function is a friend
/// declaration that was instantiated from a function definition. Such
/// declarations behave like definitions in some contexts.
bool isThisDeclarationInstantiatedFromAFriendDefinition() const;
/// Returns whether this specific declaration of the function has a body.
bool doesThisDeclarationHaveABody() const {
return (!FunctionDeclBits.HasDefaultedFunctionInfo && Body) ||
@ -2196,19 +2236,19 @@ class FunctionDecl : public DeclaratorDecl,
/// Whether this is a (C++11) constexpr function or constexpr constructor.
bool isConstexpr() const {
return FunctionDeclBits.ConstexprKind != CSK_unspecified;
return getConstexprKind() != ConstexprSpecKind::Unspecified;
}
void setConstexprKind(ConstexprSpecKind CSK) {
FunctionDeclBits.ConstexprKind = CSK;
FunctionDeclBits.ConstexprKind = static_cast<uint64_t>(CSK);
}
ConstexprSpecKind getConstexprKind() const {
return static_cast<ConstexprSpecKind>(FunctionDeclBits.ConstexprKind);
}
bool isConstexprSpecified() const {
return FunctionDeclBits.ConstexprKind == CSK_constexpr;
return getConstexprKind() == ConstexprSpecKind::Constexpr;
}
bool isConsteval() const {
return FunctionDeclBits.ConstexprKind == CSK_consteval;
return getConstexprKind() == ConstexprSpecKind::Consteval;
}
/// Whether the instantiation of this function is pending.
@ -2231,10 +2271,6 @@ class FunctionDecl : public DeclaratorDecl,
bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; }
void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; }
/// Indicates the function uses Floating Point constrained intrinsics
bool usesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; }
void setUsesFPIntrin(bool Val) { FunctionDeclBits.UsesFPIntrin = Val; }
/// Whether this function has been deleted.
///
/// A function that is "deleted" (via the C++0x "= delete" syntax)
@ -4498,14 +4534,8 @@ class EmptyDecl : public Decl {
/// Insertion operator for diagnostics. This allows sending NamedDecl's
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const NamedDecl* ND) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
DiagnosticsEngine::ak_nameddecl);
return DB;
}
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
const NamedDecl* ND) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
const NamedDecl *ND) {
PD.AddTaggedVal(reinterpret_cast<intptr_t>(ND),
DiagnosticsEngine::ak_nameddecl);
return PD;

View File

@ -1246,8 +1246,7 @@ class DeclContextLookupResult {
using IteratorBase =
llvm::iterator_adaptor_base<iterator, ResultTy::iterator,
std::random_access_iterator_tag,
NamedDecl *const>;
std::random_access_iterator_tag, NamedDecl *>;
class iterator : public IteratorBase {
value_type SingleElement;

View File

@ -744,9 +744,14 @@ class CXXRecordDecl : public RecordDecl {
///
/// This value is used for lazy creation of default constructors.
bool needsImplicitDefaultConstructor() const {
return !data().UserDeclaredConstructor &&
!(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
(!isLambda() || lambdaIsDefaultConstructibleAndAssignable());
return (!data().UserDeclaredConstructor &&
!(data().DeclaredSpecialMembers & SMF_DefaultConstructor) &&
(!isLambda() || lambdaIsDefaultConstructibleAndAssignable())) ||
// FIXME: Proposed fix to core wording issue: if a class inherits
// a default constructor and doesn't explicitly declare one, one
// is declared implicitly.
(data().HasInheritedDefaultConstructor &&
!(data().DeclaredSpecialMembers & SMF_DefaultConstructor));
}
/// Determine whether this class has any user-declared constructors.
@ -1008,8 +1013,13 @@ class CXXRecordDecl : public RecordDecl {
/// Retrieve the lambda static invoker, the address of which
/// is returned by the conversion operator, and the body of which
/// is forwarded to the lambda call operator.
/// is forwarded to the lambda call operator. The version that does not
/// take a calling convention uses the 'default' calling convention for free
/// functions if the Lambda's calling convention was not modified via
/// attribute. Otherwise, it will return the calling convention specified for
/// the lambda.
CXXMethodDecl *getLambdaStaticInvoker() const;
CXXMethodDecl *getLambdaStaticInvoker(CallingConv CC) const;
/// Retrieve the generic lambda's template parameter list.
/// Returns null if the class does not represent a lambda or a generic
@ -1025,7 +1035,7 @@ class CXXRecordDecl : public RecordDecl {
}
/// Set the captures for this lambda closure type.
void setCaptures(ArrayRef<LambdaCapture> Captures);
void setCaptures(ASTContext &Context, ArrayRef<LambdaCapture> Captures);
/// For a closure type, retrieve the mapping from captured
/// variables and \c this to the non-static data members that store the
@ -1396,6 +1406,11 @@ class CXXRecordDecl : public RecordDecl {
hasTrivialDefaultConstructor());
}
/// Determine whether this is a structural type.
bool isStructural() const {
return isLiteral() && data().StructuralIfLiteral;
}
/// If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
@ -1612,58 +1627,6 @@ class CXXRecordDecl : public RecordDecl {
CXXBasePath &Path,
const CXXRecordDecl *BaseRecord);
/// Base-class lookup callback that determines whether there exists
/// a tag with the given name.
///
/// This callback can be used with \c lookupInBases() to find tag members
/// of the given name within a C++ class hierarchy.
static bool FindTagMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
/// Base-class lookup callback that determines whether there exists
/// a member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
/// of the given name within a C++ class hierarchy.
static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
/// Base-class lookup callback that determines whether there exists
/// a member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
/// of the given name within a C++ class hierarchy, including dependent
/// classes.
static bool
FindOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
/// Base-class lookup callback that determines whether there exists
/// an OpenMP declare reduction member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
/// of the given name within a C++ class hierarchy.
static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
/// Base-class lookup callback that determines whether there exists
/// an OpenMP declare mapper member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
/// of the given name within a C++ class hierarchy.
static bool FindOMPMapperMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path, DeclarationName Name);
/// Base-class lookup callback that determines whether there exists
/// a member with the given name that can be used in a nested-name-specifier.
///
/// This callback can be used with \c lookupInBases() to find members of
/// the given name within a C++ class hierarchy that can occur within
/// nested-name-specifiers.
static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
DeclarationName Name);
/// Retrieve the final overriders for each virtual member
/// function in the class hierarchy where this class is the
/// most-derived class in the class hierarchy.
@ -1672,12 +1635,20 @@ class CXXRecordDecl : public RecordDecl {
/// Get the indirect primary bases for this class.
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
/// Determine whether this class has a member with the given name, possibly
/// in a non-dependent base class.
///
/// No check for ambiguity is performed, so this should never be used when
/// implementing language semantics, but it may be appropriate for warnings,
/// static analysis, or similar.
bool hasMemberName(DeclarationName N) const;
/// Performs an imprecise lookup of a dependent name in this class.
///
/// This function does not follow strict semantic rules and should be used
/// only when lookup rules can be relaxed, e.g. indexing.
std::vector<const NamedDecl *>
lookupDependentName(const DeclarationName &Name,
lookupDependentName(DeclarationName Name,
llvm::function_ref<bool(const NamedDecl *ND)> Filter);
/// Renders and displays an inheritance diagram
@ -1877,7 +1848,7 @@ class CXXDeductionGuideDecl : public FunctionDecl {
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, SourceLocation EndLocation)
: FunctionDecl(CXXDeductionGuide, C, DC, StartLoc, NameInfo, T, TInfo,
SC_None, false, CSK_unspecified),
SC_None, false, ConstexprSpecKind::Unspecified),
ExplicitSpec(ES) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
@ -4070,11 +4041,8 @@ class MSGuidDecl : public ValueDecl,
/// Insertion operator for diagnostics. This allows sending an AccessSpecifier
/// into a diagnostic with <<.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
AccessSpecifier AS);
const PartialDiagnostic &operator<<(const PartialDiagnostic &DB,
AccessSpecifier AS);
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
AccessSpecifier AS);
} // namespace clang

View File

@ -320,6 +320,13 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
}
/// If this method is declared or implemented in a category, return
/// that category.
ObjCCategoryDecl *getCategory();
const ObjCCategoryDecl *getCategory() const {
return const_cast<ObjCMethodDecl*>(this)->getCategory();
}
Selector getSelector() const { return getDeclName().getObjCSelector(); }
QualType getReturnType() const { return MethodDeclType; }
@ -649,20 +656,8 @@ class ObjCTypeParamDecl : public TypedefNameDecl {
/// \endcode
class ObjCTypeParamList final
: private llvm::TrailingObjects<ObjCTypeParamList, ObjCTypeParamDecl *> {
/// Stores the components of a SourceRange as a POD.
struct PODSourceRange {
unsigned Begin;
unsigned End;
};
union {
/// Location of the left and right angle brackets.
PODSourceRange Brackets;
// Used only for alignment.
ObjCTypeParamDecl *AlignmentHack;
};
/// Location of the left and right angle brackets.
SourceRange Brackets;
/// The number of parameters in the list, which are tail-allocated.
unsigned NumParams;
@ -710,17 +705,9 @@ class ObjCTypeParamList final
return *(end() - 1);
}
SourceLocation getLAngleLoc() const {
return SourceLocation::getFromRawEncoding(Brackets.Begin);
}
SourceLocation getRAngleLoc() const {
return SourceLocation::getFromRawEncoding(Brackets.End);
}
SourceRange getSourceRange() const {
return SourceRange(getLAngleLoc(), getRAngleLoc());
}
SourceLocation getLAngleLoc() const { return Brackets.getBegin(); }
SourceLocation getRAngleLoc() const { return Brackets.getEnd(); }
SourceRange getSourceRange() const { return Brackets; }
/// Gather the default set of type arguments to be substituted for
/// these type parameters when dealing with an unspecialized type.
@ -2171,6 +2158,14 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
data().ReferencedProtocols.set(List, Num, Locs, C);
}
/// This is true iff the protocol is tagged with the
/// `objc_non_runtime_protocol` attribute.
bool isNonRuntimeProtocol() const;
/// Get the set of all protocols implied by this protocols inheritance
/// hierarchy.
void getImpliedProtocols(llvm::DenseSet<const ObjCProtocolDecl *> &IPs) const;
ObjCProtocolDecl *lookupProtocolNamed(IdentifierInfo *PName);
// Lookup a method. First, we search locally. If a method isn't

View File

@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_DECLOPENMP_H
#define LLVM_CLANG_AST_DECLOPENMP_H
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
@ -24,6 +25,76 @@
namespace clang {
/// This is a basic class for representing single OpenMP declarative directive.
///
template <typename U> class OMPDeclarativeDirective : public U {
friend class ASTDeclReader;
friend class ASTDeclWriter;
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
if (!Data)
return llvm::None;
return Data->getClauses();
}
protected:
/// Data, associated with the directive.
OMPChildren *Data = nullptr;
/// Build instance of directive.
template <typename... Params>
OMPDeclarativeDirective(Params &&... P) : U(std::forward<Params>(P)...) {}
template <typename T, typename... Params>
static T *createDirective(const ASTContext &C, DeclContext *DC,
ArrayRef<OMPClause *> Clauses, unsigned NumChildren,
Params &&... P) {
auto *Inst = new (C, DC, size(Clauses.size(), NumChildren))
T(DC, std::forward<Params>(P)...);
Inst->Data = OMPChildren::Create(Inst + 1, Clauses,
/*AssociatedStmt=*/nullptr, NumChildren);
Inst->Data->setClauses(Clauses);
return Inst;
}
template <typename T, typename... Params>
static T *createEmptyDirective(const ASTContext &C, unsigned ID,
unsigned NumClauses, unsigned NumChildren,
Params &&... P) {
auto *Inst = new (C, ID, size(NumClauses, NumChildren))
T(nullptr, std::forward<Params>(P)...);
Inst->Data = OMPChildren::CreateEmpty(
Inst + 1, NumClauses, /*HasAssociatedStmt=*/false, NumChildren);
return Inst;
}
static size_t size(unsigned NumClauses, unsigned NumChildren) {
return OMPChildren::size(NumClauses, /*HasAssociatedStmt=*/false,
NumChildren);
}
public:
/// Get number of clauses.
unsigned getNumClauses() const {
if (!Data)
return 0;
return Data->getNumClauses();
}
/// Returns specified clause.
///
/// \param I Number of clause.
///
OMPClause *getClause(unsigned I) const { return clauses()[I]; }
ArrayRef<OMPClause *> clauses() const {
if (!Data)
return llvm::None;
return Data->getClauses();
}
};
/// This represents '#pragma omp threadprivate ...' directive.
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
///
@ -36,25 +107,23 @@ namespace clang {
/// };
/// \endcode
///
class OMPThreadPrivateDecl final
: public Decl,
private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> {
friend class ASTDeclReader;
friend TrailingObjects;
unsigned NumVars;
class OMPThreadPrivateDecl final : public OMPDeclarativeDirective<Decl> {
friend class OMPDeclarativeDirective<Decl>;
virtual void anchor();
OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) :
Decl(DK, DC, L), NumVars(0) { }
OMPThreadPrivateDecl(DeclContext *DC = nullptr,
SourceLocation L = SourceLocation())
: OMPDeclarativeDirective<Decl>(OMPThreadPrivate, DC, L) {}
ArrayRef<const Expr *> getVars() const {
return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
return llvm::makeArrayRef(Storage, Data->getNumChildren());
}
MutableArrayRef<Expr *> getVars() {
return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
}
void setVars(ArrayRef<Expr *> VL);
@ -71,8 +140,8 @@ class OMPThreadPrivateDecl final
typedef llvm::iterator_range<varlist_iterator> varlist_range;
typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
unsigned varlist_size() const { return NumVars; }
bool varlist_empty() const { return NumVars == 0; }
unsigned varlist_size() const { return Data->getNumChildren(); }
bool varlist_empty() const { return Data->getChildren().empty(); }
varlist_range varlists() {
return varlist_range(varlist_begin(), varlist_end());
@ -94,7 +163,7 @@ class OMPThreadPrivateDecl final
/// 'float':
///
/// \code
/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \
/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in)
/// initializer (omp_priv = 0)
/// \endcode
///
@ -214,11 +283,11 @@ class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
/// \code
/// #pragma omp declare mapper(mid: struct vec v) map(v.len, v.data[0:N])
/// \endcode
class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext {
class OMPDeclareMapperDecl final : public OMPDeclarativeDirective<ValueDecl>,
public DeclContext {
friend class OMPDeclarativeDirective<ValueDecl>;
friend class ASTDeclReader;
/// Clauses associated with this mapper declaration
MutableArrayRef<OMPClause *> Clauses;
friend class ASTDeclWriter;
/// Mapper variable, which is 'v' in the example above
Expr *MapperVarRef = nullptr;
@ -230,42 +299,36 @@ class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext {
void anchor() override;
OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, QualType Ty,
DeclarationName VarName,
OMPDeclareMapperDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
QualType Ty, DeclarationName VarName,
OMPDeclareMapperDecl *PrevDeclInScope)
: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), VarName(VarName),
: OMPDeclarativeDirective<ValueDecl>(OMPDeclareMapper, DC, L, Name, Ty),
DeclContext(OMPDeclareMapper), VarName(VarName),
PrevDeclInScope(PrevDeclInScope) {}
void setPrevDeclInScope(OMPDeclareMapperDecl *Prev) {
PrevDeclInScope = Prev;
}
/// Sets an array of clauses to this mapper declaration
void setClauses(ArrayRef<OMPClause *> CL);
public:
/// Creates declare mapper node.
static OMPDeclareMapperDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
QualType T, DeclarationName VarName,
ArrayRef<OMPClause *> Clauses,
OMPDeclareMapperDecl *PrevDeclInScope);
/// Creates deserialized declare mapper node.
static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned N);
/// Creates an array of clauses to this mapper declaration and intializes
/// them.
void CreateClauses(ASTContext &C, ArrayRef<OMPClause *> CL);
using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
using clauselist_range = llvm::iterator_range<clauselist_iterator>;
using clauselist_const_range =
llvm::iterator_range<clauselist_const_iterator>;
unsigned clauselist_size() const { return Clauses.size(); }
bool clauselist_empty() const { return Clauses.empty(); }
unsigned clauselist_size() const { return Data->getNumClauses(); }
bool clauselist_empty() const { return Data->getClauses().empty(); }
clauselist_range clauselists() {
return clauselist_range(clauselist_begin(), clauselist_end());
@ -273,16 +336,24 @@ class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext {
clauselist_const_range clauselists() const {
return clauselist_const_range(clauselist_begin(), clauselist_end());
}
clauselist_iterator clauselist_begin() { return Clauses.begin(); }
clauselist_iterator clauselist_end() { return Clauses.end(); }
clauselist_const_iterator clauselist_begin() const { return Clauses.begin(); }
clauselist_const_iterator clauselist_end() const { return Clauses.end(); }
clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
clauselist_const_iterator clauselist_begin() const {
return Data->getClauses().begin();
}
clauselist_const_iterator clauselist_end() const {
return Data->getClauses().end();
}
/// Get the variable declared in the mapper
Expr *getMapperVarRef() { return MapperVarRef; }
const Expr *getMapperVarRef() const { return MapperVarRef; }
Expr *getMapperVarRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
const Expr *getMapperVarRef() const {
return cast_or_null<Expr>(Data->getChildren()[0]);
}
/// Set the variable declared in the mapper
void setMapperVarRef(Expr *MapperVarRefE) { MapperVarRef = MapperVarRefE; }
void setMapperVarRef(Expr *MapperVarRefE) {
Data->getChildren()[0] = MapperVarRefE;
}
/// Get the name of the variable declared in the mapper
DeclarationName getVarName() { return VarName; }
@ -342,34 +413,14 @@ class OMPCapturedExprDecl final : public VarDecl {
/// #pragma omp requires unified_address
/// \endcode
///
class OMPRequiresDecl final
: public Decl,
private llvm::TrailingObjects<OMPRequiresDecl, OMPClause *> {
class OMPRequiresDecl final : public OMPDeclarativeDirective<Decl> {
friend class OMPDeclarativeDirective<Decl>;
friend class ASTDeclReader;
friend TrailingObjects;
// Number of clauses associated with this requires declaration
unsigned NumClauses = 0;
virtual void anchor();
OMPRequiresDecl(Kind DK, DeclContext *DC, SourceLocation L)
: Decl(DK, DC, L), NumClauses(0) {}
/// Returns an array of immutable clauses associated with this requires
/// declaration
ArrayRef<const OMPClause *> getClauses() const {
return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
}
/// Returns an array of clauses associated with this requires declaration
MutableArrayRef<OMPClause *> getClauses() {
return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
NumClauses);
}
/// Sets an array of clauses to this requires declaration
void setClauses(ArrayRef<OMPClause *> CL);
OMPRequiresDecl(DeclContext *DC, SourceLocation L)
: OMPDeclarativeDirective<Decl>(OMPRequires, DC, L) {}
public:
/// Create requires node.
@ -384,8 +435,8 @@ class OMPRequiresDecl final
using clauselist_range = llvm::iterator_range<clauselist_iterator>;
using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
unsigned clauselist_size() const { return NumClauses; }
bool clauselist_empty() const { return NumClauses == 0; }
unsigned clauselist_size() const { return Data->getNumClauses(); }
bool clauselist_empty() const { return Data->getClauses().empty(); }
clauselist_range clauselists() {
return clauselist_range(clauselist_begin(), clauselist_end());
@ -393,13 +444,13 @@ class OMPRequiresDecl final
clauselist_const_range clauselists() const {
return clauselist_const_range(clauselist_begin(), clauselist_end());
}
clauselist_iterator clauselist_begin() { return getClauses().begin(); }
clauselist_iterator clauselist_end() { return getClauses().end(); }
clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
clauselist_const_iterator clauselist_begin() const {
return getClauses().begin();
return Data->getClauses().begin();
}
clauselist_const_iterator clauselist_end() const {
return getClauses().end();
return Data->getClauses().end();
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@ -419,53 +470,27 @@ class OMPRequiresDecl final
/// };
/// \endcode
///
class OMPAllocateDecl final
: public Decl,
private llvm::TrailingObjects<OMPAllocateDecl, Expr *, OMPClause *> {
class OMPAllocateDecl final : public OMPDeclarativeDirective<Decl> {
friend class OMPDeclarativeDirective<Decl>;
friend class ASTDeclReader;
friend TrailingObjects;
/// Number of variable within the allocate directive.
unsigned NumVars = 0;
/// Number of clauses associated with the allocate directive.
unsigned NumClauses = 0;
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return NumVars;
}
size_t numTrailingObjects(OverloadToken<OMPClause *>) const {
return NumClauses;
}
virtual void anchor();
OMPAllocateDecl(Kind DK, DeclContext *DC, SourceLocation L)
: Decl(DK, DC, L) {}
OMPAllocateDecl(DeclContext *DC, SourceLocation L)
: OMPDeclarativeDirective<Decl>(OMPAllocate, DC, L) {}
ArrayRef<const Expr *> getVars() const {
return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars);
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
return llvm::makeArrayRef(Storage, Data->getNumChildren());
}
MutableArrayRef<Expr *> getVars() {
return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars);
auto **Storage = reinterpret_cast<Expr **>(Data->getChildren().data());
return llvm::makeMutableArrayRef(Storage, Data->getNumChildren());
}
void setVars(ArrayRef<Expr *> VL);
/// Returns an array of immutable clauses associated with this directive.
ArrayRef<OMPClause *> getClauses() const {
return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
}
/// Returns an array of clauses associated with this directive.
MutableArrayRef<OMPClause *> getClauses() {
return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
NumClauses);
}
/// Sets an array of clauses to this requires declaration
void setClauses(ArrayRef<OMPClause *> CL);
public:
static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, ArrayRef<Expr *> VL,
@ -482,11 +507,10 @@ class OMPAllocateDecl final
using clauselist_range = llvm::iterator_range<clauselist_iterator>;
using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
unsigned varlist_size() const { return NumVars; }
bool varlist_empty() const { return NumVars == 0; }
unsigned clauselist_size() const { return NumClauses; }
bool clauselist_empty() const { return NumClauses == 0; }
unsigned varlist_size() const { return Data->getNumChildren(); }
bool varlist_empty() const { return Data->getChildren().empty(); }
unsigned clauselist_size() const { return Data->getNumClauses(); }
bool clauselist_empty() const { return Data->getClauses().empty(); }
varlist_range varlists() {
return varlist_range(varlist_begin(), varlist_end());
@ -505,13 +529,13 @@ class OMPAllocateDecl final
clauselist_const_range clauselists() const {
return clauselist_const_range(clauselist_begin(), clauselist_end());
}
clauselist_iterator clauselist_begin() { return getClauses().begin(); }
clauselist_iterator clauselist_end() { return getClauses().end(); }
clauselist_iterator clauselist_begin() { return Data->getClauses().begin(); }
clauselist_iterator clauselist_end() { return Data->getClauses().end(); }
clauselist_const_iterator clauselist_begin() const {
return getClauses().begin();
return Data->getClauses().begin();
}
clauselist_const_iterator clauselist_end() const {
return getClauses().end();
return Data->getClauses().end();
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }

View File

@ -77,7 +77,7 @@ class TemplateParameterList final
/// The number of template parameters in this template
/// parameter list.
unsigned NumParams : 30;
unsigned NumParams : 29;
/// Whether this template parameter list contains an unexpanded parameter
/// pack.
@ -204,10 +204,6 @@ class TemplateParameterList final
bool OmitTemplateKW = false) const;
void print(raw_ostream &Out, const ASTContext &Context,
const PrintingPolicy &Policy, bool OmitTemplateKW = false) const;
public:
// FIXME: workaround for MSVC 2013; remove when no longer needed
using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner;
};
/// Stores a list of template parameters and the associated
@ -2270,7 +2266,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
/// Retrieve the set of partial specializations of this class
/// template.
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations();
getPartialSpecializations() const;
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
@ -2367,7 +2363,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
/// Retrieve the partial specializations as an ordered list.
void getPartialSpecializations(
SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const;
/// Find a class template partial specialization with the given
/// type T.
@ -3099,7 +3095,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
/// Retrieve the set of partial specializations of this class
/// template.
llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations();
getPartialSpecializations() const;
VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
@ -3195,7 +3191,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
/// Retrieve the partial specializations as an ordered list.
void getPartialSpecializations(
SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const;
/// Find a variable template partial specialization which was
/// instantiated
@ -3230,7 +3226,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
static bool classofKind(Kind K) { return K == VarTemplate; }
};
// \brief Declaration of a C++2a concept.
/// Declaration of a C++2a concept.
class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
protected:
Expr *ConstraintExpr;
@ -3259,6 +3255,9 @@ class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0));
}
ConceptDecl *getCanonicalDecl() override { return getFirstDecl(); }
const ConceptDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Concept; }
@ -3268,6 +3267,74 @@ class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
friend class ASTDeclWriter;
};
/// A template parameter object.
///
/// Template parameter objects represent values of class type used as template
/// arguments. There is one template parameter object for each such distinct
/// value used as a template argument across the program.
///
/// \code
/// struct A { int x, y; };
/// template<A> struct S;
/// S<A{1, 2}> s1;
/// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl.
/// \endcode
class TemplateParamObjectDecl : public ValueDecl,
public Mergeable<TemplateParamObjectDecl>,
public llvm::FoldingSetNode {
private:
/// The value of this template parameter object.
APValue Value;
TemplateParamObjectDecl(DeclContext *DC, QualType T, const APValue &V)
: ValueDecl(TemplateParamObject, DC, SourceLocation(), DeclarationName(),
T),
Value(V) {}
static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T,
const APValue &V);
static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C,
unsigned ID);
/// Only ASTContext::getTemplateParamObjectDecl and deserialization
/// create these.
friend class ASTContext;
friend class ASTReader;
friend class ASTDeclReader;
public:
/// Print this template parameter object in a human-readable format.
void printName(llvm::raw_ostream &OS) const override;
/// Print this object as an equivalent expression.
void printAsExpr(llvm::raw_ostream &OS) const;
/// Print this object as an initializer suitable for a variable of the
/// object's type.
void printAsInit(llvm::raw_ostream &OS) const;
const APValue &getValue() const { return Value; }
static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
const APValue &V) {
ID.AddPointer(T.getCanonicalType().getAsOpaquePtr());
V.Profile(ID);
}
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getType(), getValue());
}
TemplateParamObjectDecl *getCanonicalDecl() override {
return getFirstDecl();
}
const TemplateParamObjectDecl *getCanonicalDecl() const {
return getFirstDecl();
}
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == TemplateParamObject; }
};
inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
if (auto *PD = P.dyn_cast<TemplateTypeParmDecl *>())
return PD;
@ -3286,6 +3353,36 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
: nullptr;
}
/// Check whether the template parameter is a pack expansion, and if so,
/// determine the number of parameters produced by that expansion. For instance:
///
/// \code
/// template<typename ...Ts> struct A {
/// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B;
/// };
/// \endcode
///
/// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us
/// is not a pack expansion, so returns an empty Optional.
inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) {
if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionParameters();
}
if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
if (NTTP->isExpandedParameterPack())
return NTTP->getNumExpansionTypes();
}
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
if (TTP->isExpandedParameterPack())
return TTP->getNumExpansionTemplateParameters();
}
return None;
}
} // namespace clang
#endif // LLVM_CLANG_AST_DECLTEMPLATE_H

View File

@ -811,19 +811,10 @@ struct DeclarationNameInfo {
SourceLocation getEndLocPrivate() const;
};
/// Insertion operator for diagnostics. This allows sending DeclarationName's
/// into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
DeclarationName N) {
DB.AddTaggedVal(N.getAsOpaqueInteger(),
DiagnosticsEngine::ak_declarationname);
return DB;
}
/// Insertion operator for partial diagnostics. This allows binding
/// DeclarationName's into a partial diagnostic with <<.
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
DeclarationName N) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
DeclarationName N) {
PD.AddTaggedVal(N.getAsOpaqueInteger(),
DiagnosticsEngine::ak_declarationname);
return PD;
@ -857,6 +848,16 @@ struct DenseMapInfo<clang::DeclarationName> {
}
};
template <> struct PointerLikeTypeTraits<clang::DeclarationName> {
static inline void *getAsVoidPointer(clang::DeclarationName P) {
return P.getAsOpaquePtr();
}
static inline clang::DeclarationName getFromVoidPointer(void *P) {
return clang::DeclarationName::getFromOpaquePtr(P);
}
static constexpr int NumLowBitsAvailable = 0;
};
} // namespace llvm
// The definition of AssumedTemplateStorage is factored out of TemplateName to

View File

@ -41,6 +41,7 @@ struct ExprDependenceScope {
TypeInstantiation = Type | Instantiation,
ValueInstantiation = Value | Instantiation,
TypeValueInstantiation = Type | Value | Instantiation,
ErrorDependent = Error | ValueInstantiation,
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
};

View File

@ -48,7 +48,7 @@ class DependentDiagnostic {
QualType BaseObjectType,
const PartialDiagnostic &PDiag) {
DependentDiagnostic *DD = Create(Context, Parent, PDiag);
DD->AccessData.Loc = Loc.getRawEncoding();
DD->AccessData.Loc = Loc;
DD->AccessData.IsMember = IsMemberAccess;
DD->AccessData.Access = AS;
DD->AccessData.TargetDecl = TargetDecl;
@ -73,7 +73,7 @@ class DependentDiagnostic {
SourceLocation getAccessLoc() const {
assert(getKind() == Access);
return SourceLocation::getFromRawEncoding(AccessData.Loc);
return AccessData.Loc;
}
NamedDecl *getAccessTarget() const {
@ -100,8 +100,8 @@ class DependentDiagnostic {
friend class DependentStoredDeclsMap;
DependentDiagnostic(const PartialDiagnostic &PDiag,
PartialDiagnostic::Storage *Storage)
: Diag(PDiag, Storage) {}
DiagnosticStorage *Storage)
: Diag(PDiag, Storage) {}
static DependentDiagnostic *Create(ASTContext &Context,
DeclContext *Parent,
@ -112,7 +112,7 @@ class DependentDiagnostic {
PartialDiagnostic Diag;
struct {
unsigned Loc;
SourceLocation Loc;
unsigned Access : 2;
unsigned IsMember : 1;
NamedDecl *TargetDecl;

View File

@ -24,7 +24,6 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SyncScope.h"
#include "clang/Basic/TypeTraits.h"
@ -414,6 +413,10 @@ class Expr : public ValueStmt {
return ClassifyImpl(Ctx, &Loc);
}
/// Returns the set of floating point options that apply to this expression.
/// Only meaningful for operations on floating point values.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const;
/// getValueKindForType - Given a formal return or parameter type,
/// give its value kind.
static ExprValueKind getValueKindForType(QualType T) {
@ -522,16 +525,15 @@ class Expr : public ValueStmt {
/// semantically correspond to a bool.
bool isKnownToHaveBooleanValue(bool Semantic = true) const;
/// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a
/// valid i-c-e, return false and fill in Loc (if specified) with the location
/// of the invalid expression.
/// isIntegerConstantExpr - Return the value if this expression is a valid
/// integer constant expression. If not a valid i-c-e, return None and fill
/// in Loc (if specified) with the location of the invalid expression.
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
SourceLocation *Loc = nullptr,
bool isEvaluated = true) const;
Optional<llvm::APSInt> getIntegerConstantExpr(const ASTContext &Ctx,
SourceLocation *Loc = nullptr,
bool isEvaluated = true) const;
bool isIntegerConstantExpr(const ASTContext &Ctx,
SourceLocation *Loc = nullptr) const;
@ -697,7 +699,8 @@ class Expr : public ValueStmt {
/// notes will be produced if the expression is not a constant expression.
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
const VarDecl *VD,
SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
SmallVectorImpl<PartialDiagnosticAt> &Notes,
bool IsConstantInitializer) const;
/// EvaluateWithSubstitution - Evaluate an expression as if from the context
/// of a call to the given function with the given arguments, inside an
@ -708,13 +711,26 @@ class Expr : public ValueStmt {
ArrayRef<const Expr*> Args,
const Expr *This = nullptr) const;
/// Indicates how the constant expression will be used.
enum ConstExprUsage { EvaluateForCodeGen, EvaluateForMangling };
enum class ConstantExprKind {
/// An integer constant expression (an array bound, enumerator, case value,
/// bit-field width, or similar) or similar.
Normal,
/// A non-class template argument. Such a value is only used for mangling,
/// not for code generation, so can refer to dllimported functions.
NonClassTemplateArgument,
/// A class template argument. Such a value is used for code generation.
ClassTemplateArgument,
/// An immediate invocation. The destruction of the end result of this
/// evaluation is not part of the evaluation, but all other temporaries
/// are destroyed.
ImmediateInvocation,
};
/// Evaluate an expression that is required to be a constant expression.
bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage,
const ASTContext &Ctx,
bool InPlace = false) const;
/// Evaluate an expression that is required to be a constant expression. Does
/// not check the syntactic constraints for C and C++98 constant expressions.
bool EvaluateAsConstantExpr(
EvalResult &Result, const ASTContext &Ctx,
ConstantExprKind Kind = ConstantExprKind::Normal) const;
/// If the current Expr is a pointer, this will try to statically
/// determine the number of bytes available where the pointer is pointing.
@ -869,9 +885,9 @@ class Expr : public ValueStmt {
/// Skip conversion operators. If this Expr is a call to a conversion
/// operator, return the argument.
Expr *IgnoreConversionOperator() LLVM_READONLY;
const Expr *IgnoreConversionOperator() const {
return const_cast<Expr *>(this)->IgnoreConversionOperator();
Expr *IgnoreConversionOperatorSingleStep() LLVM_READONLY;
const Expr *IgnoreConversionOperatorSingleStep() const {
return const_cast<Expr *>(this)->IgnoreConversionOperatorSingleStep();
}
/// Skip past any parentheses and lvalue casts which might surround this
@ -903,9 +919,9 @@ class Expr : public ValueStmt {
/// * What IgnoreParens() skips
/// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase,
/// CK_UncheckedDerivedToBase and CK_NoOp)
Expr *ignoreParenBaseCasts() LLVM_READONLY;
const Expr *ignoreParenBaseCasts() const {
return const_cast<Expr *>(this)->ignoreParenBaseCasts();
Expr *IgnoreParenBaseCasts() LLVM_READONLY;
const Expr *IgnoreParenBaseCasts() const {
return const_cast<Expr *>(this)->IgnoreParenBaseCasts();
}
/// Determine whether this expression is a default function argument.
@ -962,6 +978,13 @@ class Expr : public ValueStmt {
T->getStmtClass() <= lastExprConstant;
}
};
// PointerLikeTypeTraits is specialized so it can be used with a forward-decl of
// Expr. Verify that we got it right.
static_assert(llvm::PointerLikeTypeTraits<Expr *>::NumLowBitsAvailable <=
llvm::detail::ConstantLog2<alignof(Expr)>::value,
"PointerLikeTypeTraits<Expr*> assumes too much alignment.");
using ConstantExprKind = Expr::ConstantExprKind;
//===----------------------------------------------------------------------===//
// Wrapper Expressions.
@ -1261,7 +1284,7 @@ class DeclRefExpr final
ValueDecl *getDecl() { return D; }
const ValueDecl *getDecl() const { return D; }
void setDecl(ValueDecl *NewD) { D = NewD; }
void setDecl(ValueDecl *NewD);
DeclarationNameInfo getNameInfo() const {
return DeclarationNameInfo(getDecl()->getDeclName(), getLocation(), DNLoc);
@ -1923,17 +1946,13 @@ class StringLiteral final
/// [C99 6.4.2.2] - A predefined identifier such as __func__.
class PredefinedExpr final
: public Expr,
private llvm::TrailingObjects<PredefinedExpr, Stmt *, Expr *,
TypeSourceInfo *> {
private llvm::TrailingObjects<PredefinedExpr, Stmt *> {
friend class ASTStmtReader;
friend TrailingObjects;
// PredefinedExpr is optionally followed by a single trailing
// "Stmt *" for the predefined identifier. It is present if and only if
// hasFunctionName() is true and is always a "StringLiteral *".
// It can also be followed by a Expr* in the case of a
// __builtin_unique_stable_name with an expression, or TypeSourceInfo * if
// __builtin_unique_stable_name with a type.
public:
enum IdentKind {
@ -1946,18 +1965,12 @@ class PredefinedExpr final
PrettyFunction,
/// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual,
UniqueStableNameType,
UniqueStableNameExpr,
PrettyFunctionNoVirtual
};
private:
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
StringLiteral *SL);
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
TypeSourceInfo *Info);
PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK,
Expr *E);
explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName);
@ -1970,39 +1983,10 @@ class PredefinedExpr final
*getTrailingObjects<Stmt *>() = SL;
}
void setTypeSourceInfo(TypeSourceInfo *Info) {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
"TypeSourceInfo only valid for UniqueStableName of a Type");
*getTrailingObjects<TypeSourceInfo *>() = Info;
}
void setExpr(Expr *E) {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
"TypeSourceInfo only valid for UniqueStableName of n Expression.");
*getTrailingObjects<Expr *>() = E;
}
size_t numTrailingObjects(OverloadToken<Stmt *>) const {
return hasFunctionName();
}
size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const {
return getIdentKind() == UniqueStableNameType && !hasFunctionName();
}
size_t numTrailingObjects(OverloadToken<Expr *>) const {
return getIdentKind() == UniqueStableNameExpr && !hasFunctionName();
}
public:
/// Create a PredefinedExpr.
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, StringLiteral *SL);
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, StringLiteral *SL,
TypeSourceInfo *Info);
static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L,
QualType FNTy, IdentKind IK, StringLiteral *SL,
Expr *E);
/// Create an empty PredefinedExpr.
static PredefinedExpr *CreateEmpty(const ASTContext &Ctx,
@ -2027,34 +2011,12 @@ class PredefinedExpr final
: nullptr;
}
TypeSourceInfo *getTypeSourceInfo() {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
"TypeSourceInfo only valid for UniqueStableName of a Type");
return *getTrailingObjects<TypeSourceInfo *>();
}
const TypeSourceInfo *getTypeSourceInfo() const {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType &&
"TypeSourceInfo only valid for UniqueStableName of a Type");
return *getTrailingObjects<TypeSourceInfo *>();
}
Expr *getExpr() {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
"TypeSourceInfo only valid for UniqueStableName of n Expression.");
return *getTrailingObjects<Expr *>();
}
const Expr *getExpr() const {
assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr &&
"TypeSourceInfo only valid for UniqueStableName of n Expression.");
return *getTrailingObjects<Expr *>();
}
static StringRef getIdentKindName(IdentKind IK);
StringRef getIdentKindName() const {
return getIdentKindName(getIdentKind());
}
static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl);
static std::string ComputeName(ASTContext &Context, IdentKind IK,
const QualType Ty);
SourceLocation getBeginLoc() const { return getLocation(); }
SourceLocation getEndLoc() const { return getLocation(); }
@ -2273,12 +2235,12 @@ class UnaryOperator final
/// Is FPFeatures in Trailing Storage?
bool hasStoredFPFeatures() const { return UnaryOperatorBits.HasFPFeatures; }
protected:
/// Get FPFeatures from trailing storage
/// Get FPFeatures from trailing storage.
FPOptionsOverride getStoredFPFeatures() const {
return getTrailingFPFeatures();
}
protected:
/// Set FPFeatures in trailing storage, used only by Serialization
void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
@ -2788,6 +2750,8 @@ class CallExpr : public Expr {
//
// * An array of getNumArgs() "Stmt *" for the argument expressions.
//
// * An optional of type FPOptionsOverride.
//
// Note that we store the offset in bytes from the this pointer to the start
// of the trailing objects. It would be perfectly possible to compute it
// based on the dynamic kind of the CallExpr. However 1.) we have plenty of
@ -2809,6 +2773,15 @@ class CallExpr : public Expr {
/// this pointer to the trailing objects.
static unsigned offsetToTrailingObjects(StmtClass SC);
unsigned getSizeOfTrailingStmts() const {
return (1 + getNumPreArgs() + getNumArgs()) * sizeof(Stmt *);
}
size_t getOffsetOfTrailingFPFeatures() const {
assert(hasStoredFPFeatures());
return CallExprBits.OffsetToTrailingObjects + getSizeOfTrailingStmts();
}
public:
enum class ADLCallKind : bool { NotADL, UsesADL };
static constexpr ADLCallKind NotADL = ADLCallKind::NotADL;
@ -2819,16 +2792,19 @@ class CallExpr : public Expr {
/// allocated for the trailing objects.
CallExpr(StmtClass SC, Expr *Fn, ArrayRef<Expr *> PreArgs,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
SourceLocation RParenLoc, unsigned MinNumArgs, ADLCallKind UsesADL);
SourceLocation RParenLoc, FPOptionsOverride FPFeatures,
unsigned MinNumArgs, ADLCallKind UsesADL);
/// Build an empty call expression, for deserialization.
CallExpr(StmtClass SC, unsigned NumPreArgs, unsigned NumArgs,
EmptyShell Empty);
bool hasFPFeatures, EmptyShell Empty);
/// Return the size in bytes needed for the trailing objects.
/// Used by the derived classes to allocate the right amount of storage.
static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs) {
return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *);
static unsigned sizeOfTrailingObjects(unsigned NumPreArgs, unsigned NumArgs,
bool HasFPFeatures) {
return (1 + NumPreArgs + NumArgs) * sizeof(Stmt *) +
HasFPFeatures * sizeof(FPOptionsOverride);
}
Stmt *getPreArg(unsigned I) {
@ -2846,22 +2822,43 @@ class CallExpr : public Expr {
unsigned getNumPreArgs() const { return CallExprBits.NumPreArgs; }
/// Return a pointer to the trailing FPOptions
FPOptionsOverride *getTrailingFPFeatures() {
assert(hasStoredFPFeatures());
return reinterpret_cast<FPOptionsOverride *>(
reinterpret_cast<char *>(this) + CallExprBits.OffsetToTrailingObjects +
getSizeOfTrailingStmts());
}
const FPOptionsOverride *getTrailingFPFeatures() const {
assert(hasStoredFPFeatures());
return reinterpret_cast<const FPOptionsOverride *>(
reinterpret_cast<const char *>(this) +
CallExprBits.OffsetToTrailingObjects + getSizeOfTrailingStmts());
}
public:
/// Create a call expression. Fn is the callee expression, Args is the
/// argument array, Ty is the type of the call expression (which is *not*
/// the return type in general), VK is the value kind of the call expression
/// (lvalue, rvalue, ...), and RParenLoc is the location of the right
/// parenthese in the call expression. MinNumArgs specifies the minimum
/// number of arguments. The actual number of arguments will be the greater
/// of Args.size() and MinNumArgs. This is used in a few places to allocate
/// enough storage for the default arguments. UsesADL specifies whether the
/// callee was found through argument-dependent lookup.
/// Create a call expression.
/// \param Fn The callee expression,
/// \param Args The argument array,
/// \param Ty The type of the call expression (which is *not* the return
/// type in general),
/// \param VK The value kind of the call expression (lvalue, rvalue, ...),
/// \param RParenLoc The location of the right parenthesis in the call
/// expression.
/// \param FPFeatures Floating-point features associated with the call,
/// \param MinNumArgs Specifies the minimum number of arguments. The actual
/// number of arguments will be the greater of Args.size()
/// and MinNumArgs. This is used in a few places to allocate
/// enough storage for the default arguments.
/// \param UsesADL Specifies whether the callee was found through
/// argument-dependent lookup.
///
/// Note that you can use CreateTemporary if you need a temporary call
/// expression on the stack.
static CallExpr *Create(const ASTContext &Ctx, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK,
SourceLocation RParenLoc, unsigned MinNumArgs = 0,
SourceLocation RParenLoc,
FPOptionsOverride FPFeatures, unsigned MinNumArgs = 0,
ADLCallKind UsesADL = NotADL);
/// Create a temporary call expression with no arguments in the memory
@ -2878,7 +2875,7 @@ class CallExpr : public Expr {
/// Create an empty call expression, for deserialization.
static CallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
EmptyShell Empty);
bool HasFPFeatures, EmptyShell Empty);
Expr *getCallee() { return cast<Expr>(getTrailingStmts()[FN]); }
const Expr *getCallee() const { return cast<Expr>(getTrailingStmts()[FN]); }
@ -2892,6 +2889,8 @@ class CallExpr : public Expr {
}
bool usesADL() const { return getADLCallKind() == UsesADL; }
bool hasStoredFPFeatures() const { return CallExprBits.HasFPFeatures; }
Decl *getCalleeDecl() { return getCallee()->getReferencedDeclOfCallee(); }
const Decl *getCalleeDecl() const {
return getCallee()->getReferencedDeclOfCallee();
@ -2984,6 +2983,31 @@ class CallExpr : public Expr {
/// this function call.
unsigned getNumCommas() const { return getNumArgs() ? getNumArgs() - 1 : 0; }
/// Get FPOptionsOverride from trailing storage.
FPOptionsOverride getStoredFPFeatures() const {
assert(hasStoredFPFeatures());
return *getTrailingFPFeatures();
}
/// Set FPOptionsOverride in trailing storage. Used only by Serialization.
void setStoredFPFeatures(FPOptionsOverride F) {
assert(hasStoredFPFeatures());
*getTrailingFPFeatures() = F;
}
// Get the FP features status of this operator. Only meaningful for
// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (hasStoredFPFeatures())
return getStoredFPFeatures().applyOverrides(LO);
return FPOptions::defaultWithoutTrailingStorage(LO);
}
FPOptionsOverride getFPFeatures() const {
if (hasStoredFPFeatures())
return getStoredFPFeatures();
return FPOptionsOverride();
}
/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
/// of the callee. If not, return 0.
unsigned getBuiltinCallee() const;
@ -3143,7 +3167,7 @@ class MemberExpr final
/// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
/// static data members), a CXXMethodDecl, or an EnumConstantDecl.
ValueDecl *getMemberDecl() const { return MemberDecl; }
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
void setMemberDecl(ValueDecl *D);
/// Retrieves the declaration found by lookup.
DeclAccessPair getFoundDecl() const {
@ -3380,9 +3404,11 @@ class CastExpr : public Expr {
}
CXXBaseSpecifier **path_buffer();
friend class ASTStmtReader;
protected:
CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind,
Expr *op, unsigned BasePathSize)
Expr *op, unsigned BasePathSize, bool HasFPFeatures)
: Expr(SC, ty, VK, OK_Ordinary), Op(op) {
CastExprBits.Kind = kind;
CastExprBits.PartOfExplicitCast = false;
@ -3391,17 +3417,27 @@ class CastExpr : public Expr {
"BasePathSize overflow!");
setDependence(computeDependence(this));
assert(CastConsistency());
CastExprBits.HasFPFeatures = HasFPFeatures;
}
/// Construct an empty cast.
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize)
: Expr(SC, Empty) {
CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize,
bool HasFPFeatures)
: Expr(SC, Empty) {
CastExprBits.PartOfExplicitCast = false;
CastExprBits.BasePathSize = BasePathSize;
CastExprBits.HasFPFeatures = HasFPFeatures;
assert((CastExprBits.BasePathSize == BasePathSize) &&
"BasePathSize overflow!");
}
/// Return a pointer to the trailing FPOptions.
/// \pre hasStoredFPFeatures() == true
FPOptionsOverride *getTrailingFPFeatures();
const FPOptionsOverride *getTrailingFPFeatures() const {
return const_cast<CastExpr *>(this)->getTrailingFPFeatures();
}
public:
CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; }
void setCastKind(CastKind K) { CastExprBits.Kind = K; }
@ -3446,6 +3482,28 @@ class CastExpr : public Expr {
return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType());
}
bool hasStoredFPFeatures() const { return CastExprBits.HasFPFeatures; }
/// Get FPOptionsOverride from trailing storage.
FPOptionsOverride getStoredFPFeatures() const {
assert(hasStoredFPFeatures());
return *getTrailingFPFeatures();
}
// Get the FP features status of this operation. Only meaningful for
// operations on floating point types.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
if (hasStoredFPFeatures())
return getStoredFPFeatures().applyOverrides(LO);
return FPOptions::defaultWithoutTrailingStorage(LO);
}
FPOptionsOverride getFPFeatures() const {
if (hasStoredFPFeatures())
return getStoredFPFeatures();
return FPOptionsOverride();
}
static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
QualType opType);
static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
@ -3483,21 +3541,35 @@ class CastExpr : public Expr {
/// @endcode
class ImplicitCastExpr final
: public CastExpr,
private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> {
private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *,
FPOptionsOverride> {
ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
unsigned BasePathLength, ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength) { }
unsigned BasePathLength, FPOptionsOverride FPO,
ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, BasePathLength,
FPO.requiresTrailingStorage()) {
if (hasStoredFPFeatures())
*getTrailingFPFeatures() = FPO;
}
/// Construct an empty implicit cast.
explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize)
: CastExpr(ImplicitCastExprClass, Shell, PathSize) { }
explicit ImplicitCastExpr(EmptyShell Shell, unsigned PathSize,
bool HasFPFeatures)
: CastExpr(ImplicitCastExprClass, Shell, PathSize, HasFPFeatures) {}
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
return path_size();
}
public:
enum OnStack_t { OnStack };
ImplicitCastExpr(OnStack_t _, QualType ty, CastKind kind, Expr *op,
ExprValueKind VK)
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) {
ExprValueKind VK, FPOptionsOverride FPO)
: CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0,
FPO.requiresTrailingStorage()) {
if (hasStoredFPFeatures())
*getTrailingFPFeatures() = FPO;
}
bool isPartOfExplicitCast() const { return CastExprBits.PartOfExplicitCast; }
@ -3508,10 +3580,10 @@ class ImplicitCastExpr final
static ImplicitCastExpr *Create(const ASTContext &Context, QualType T,
CastKind Kind, Expr *Operand,
const CXXCastPath *BasePath,
ExprValueKind Cat);
ExprValueKind Cat, FPOptionsOverride FPO);
static ImplicitCastExpr *CreateEmpty(const ASTContext &Context,
unsigned PathSize);
unsigned PathSize, bool HasFPFeatures);
SourceLocation getBeginLoc() const LLVM_READONLY {
return getSubExpr()->getBeginLoc();
@ -3552,12 +3624,14 @@ class ExplicitCastExpr : public CastExpr {
protected:
ExplicitCastExpr(StmtClass SC, QualType exprTy, ExprValueKind VK,
CastKind kind, Expr *op, unsigned PathSize,
TypeSourceInfo *writtenTy)
: CastExpr(SC, exprTy, VK, kind, op, PathSize), TInfo(writtenTy) {}
bool HasFPFeatures, TypeSourceInfo *writtenTy)
: CastExpr(SC, exprTy, VK, kind, op, PathSize, HasFPFeatures),
TInfo(writtenTy) {}
/// Construct an empty explicit cast.
ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
: CastExpr(SC, Shell, PathSize) { }
ExplicitCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
bool HasFPFeatures)
: CastExpr(SC, Shell, PathSize, HasFPFeatures) {}
public:
/// getTypeInfoAsWritten - Returns the type source info for the type
@ -3580,29 +3654,38 @@ class ExplicitCastExpr : public CastExpr {
/// (Type)expr. For example: @c (int)f.
class CStyleCastExpr final
: public ExplicitCastExpr,
private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> {
private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *,
FPOptionsOverride> {
SourceLocation LPLoc; // the location of the left paren
SourceLocation RPLoc; // the location of the right paren
CStyleCastExpr(QualType exprTy, ExprValueKind vk, CastKind kind, Expr *op,
unsigned PathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation r)
: ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
writtenTy), LPLoc(l), RPLoc(r) {}
unsigned PathSize, FPOptionsOverride FPO,
TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation r)
: ExplicitCastExpr(CStyleCastExprClass, exprTy, vk, kind, op, PathSize,
FPO.requiresTrailingStorage(), writtenTy),
LPLoc(l), RPLoc(r) {
if (hasStoredFPFeatures())
*getTrailingFPFeatures() = FPO;
}
/// Construct an empty C-style explicit cast.
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize) { }
explicit CStyleCastExpr(EmptyShell Shell, unsigned PathSize,
bool HasFPFeatures)
: ExplicitCastExpr(CStyleCastExprClass, Shell, PathSize, HasFPFeatures) {}
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
return path_size();
}
public:
static CStyleCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K,
Expr *Op, const CXXCastPath *BasePath,
TypeSourceInfo *WrittenTy, SourceLocation L,
SourceLocation R);
static CStyleCastExpr *
Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K,
Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO,
TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R);
static CStyleCastExpr *CreateEmpty(const ASTContext &Context,
unsigned PathSize);
unsigned PathSize, bool HasFPFeatures);
SourceLocation getLParenLoc() const { return LPLoc; }
void setLParenLoc(SourceLocation L) { LPLoc = L; }
@ -4690,6 +4773,13 @@ class InitListExpr : public Expr {
setDependence(getDependence() | expr->getDependence());
}
/// Mark the semantic form of the InitListExpr as error when the semantic
/// analysis fails.
void markError() {
assert(isSemanticForm());
setDependence(getDependence() | ExprDependence::ErrorDependent);
}
/// Reserve space for some number of initializers.
void reserveInits(const ASTContext &C, unsigned NumInits);
@ -4904,10 +4994,10 @@ class DesignatedInitExpr final
uintptr_t NameOrField;
/// The location of the '.' in the designated initializer.
unsigned DotLoc;
SourceLocation DotLoc;
/// The location of the field name in the designated initializer.
unsigned FieldLoc;
SourceLocation FieldLoc;
};
/// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
@ -4916,12 +5006,12 @@ class DesignatedInitExpr final
/// initializer expression's list of subexpressions.
unsigned Index;
/// The location of the '[' starting the array range designator.
unsigned LBracketLoc;
SourceLocation LBracketLoc;
/// The location of the ellipsis separating the start and end
/// indices. Only valid for GNU array-range designators.
unsigned EllipsisLoc;
SourceLocation EllipsisLoc;
/// The location of the ']' terminating the array range designator.
unsigned RBracketLoc;
SourceLocation RBracketLoc;
};
/// Represents a single C99 designator.
@ -4953,29 +5043,32 @@ class DesignatedInitExpr final
Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
SourceLocation FieldLoc)
: Kind(FieldDesignator) {
new (&Field) DesignatedInitExpr::FieldDesignator;
Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
Field.DotLoc = DotLoc.getRawEncoding();
Field.FieldLoc = FieldLoc.getRawEncoding();
Field.DotLoc = DotLoc;
Field.FieldLoc = FieldLoc;
}
/// Initializes an array designator.
Designator(unsigned Index, SourceLocation LBracketLoc,
SourceLocation RBracketLoc)
: Kind(ArrayDesignator) {
new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
ArrayOrRange.Index = Index;
ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
ArrayOrRange.EllipsisLoc = SourceLocation().getRawEncoding();
ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
ArrayOrRange.LBracketLoc = LBracketLoc;
ArrayOrRange.EllipsisLoc = SourceLocation();
ArrayOrRange.RBracketLoc = RBracketLoc;
}
/// Initializes a GNU array-range designator.
Designator(unsigned Index, SourceLocation LBracketLoc,
SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
: Kind(ArrayRangeDesignator) {
new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
ArrayOrRange.Index = Index;
ArrayOrRange.LBracketLoc = LBracketLoc.getRawEncoding();
ArrayOrRange.EllipsisLoc = EllipsisLoc.getRawEncoding();
ArrayOrRange.RBracketLoc = RBracketLoc.getRawEncoding();
ArrayOrRange.LBracketLoc = LBracketLoc;
ArrayOrRange.EllipsisLoc = EllipsisLoc;
ArrayOrRange.RBracketLoc = RBracketLoc;
}
bool isFieldDesignator() const { return Kind == FieldDesignator; }
@ -4999,30 +5092,30 @@ class DesignatedInitExpr final
SourceLocation getDotLoc() const {
assert(Kind == FieldDesignator && "Only valid on a field designator");
return SourceLocation::getFromRawEncoding(Field.DotLoc);
return Field.DotLoc;
}
SourceLocation getFieldLoc() const {
assert(Kind == FieldDesignator && "Only valid on a field designator");
return SourceLocation::getFromRawEncoding(Field.FieldLoc);
return Field.FieldLoc;
}
SourceLocation getLBracketLoc() const {
assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
"Only valid on an array or array-range designator");
return SourceLocation::getFromRawEncoding(ArrayOrRange.LBracketLoc);
return ArrayOrRange.LBracketLoc;
}
SourceLocation getRBracketLoc() const {
assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
"Only valid on an array or array-range designator");
return SourceLocation::getFromRawEncoding(ArrayOrRange.RBracketLoc);
return ArrayOrRange.RBracketLoc;
}
SourceLocation getEllipsisLoc() const {
assert(Kind == ArrayRangeDesignator &&
"Only valid on an array-range designator");
return SourceLocation::getFromRawEncoding(ArrayOrRange.EllipsisLoc);
return ArrayOrRange.EllipsisLoc;
}
unsigned getFirstExprIndex() const {
@ -6240,9 +6333,6 @@ class TypoExpr : public Expr {
///
/// One can also reliably suppress all bogus errors on expressions containing
/// recovery expressions by examining results of Expr::containsErrors().
///
/// FIXME: RecoveryExpr is currently generated by default in C++ mode only, as
/// dependence isn't handled properly on several C-only codepaths.
class RecoveryExpr final : public Expr,
private llvm::TrailingObjects<RecoveryExpr, Expr *> {
public:

View File

@ -84,7 +84,6 @@ class CXXOperatorCallExpr final : public CallExpr {
friend class ASTStmtWriter;
SourceRange Range;
FPOptionsOverride Overrides;
// CXXOperatorCallExpr has some trailing objects belonging
// to CallExpr. See CallExpr for the details.
@ -96,7 +95,7 @@ class CXXOperatorCallExpr final : public CallExpr {
SourceLocation OperatorLoc, FPOptionsOverride FPFeatures,
ADLCallKind UsesADL);
CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty);
CXXOperatorCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
public:
static CXXOperatorCallExpr *
@ -106,7 +105,8 @@ class CXXOperatorCallExpr final : public CallExpr {
ADLCallKind UsesADL = NotADL);
static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx,
unsigned NumArgs, EmptyShell Empty);
unsigned NumArgs, bool HasFPFeatures,
EmptyShell Empty);
/// Returns the kind of overloaded operator that this expression refers to.
OverloadedOperatorKind getOperator() const {
@ -164,11 +164,6 @@ class CXXOperatorCallExpr final : public CallExpr {
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXOperatorCallExprClass;
}
// Set the FPFeatures status of this operator. Only meaningful for
// operations on floating point types.
void setFPFeatures(FPOptionsOverride F) { Overrides = F; }
FPOptionsOverride getFPFeatures() const { return Overrides; }
};
/// Represents a call to a member function that
@ -184,18 +179,20 @@ class CXXMemberCallExpr final : public CallExpr {
// to CallExpr. See CallExpr for the details.
CXXMemberCallExpr(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
ExprValueKind VK, SourceLocation RP, unsigned MinNumArgs);
ExprValueKind VK, SourceLocation RP,
FPOptionsOverride FPOptions, unsigned MinNumArgs);
CXXMemberCallExpr(unsigned NumArgs, EmptyShell Empty);
CXXMemberCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
public:
static CXXMemberCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty,
ExprValueKind VK, SourceLocation RP,
FPOptionsOverride FPFeatures,
unsigned MinNumArgs = 0);
static CXXMemberCallExpr *CreateEmpty(const ASTContext &Ctx, unsigned NumArgs,
EmptyShell Empty);
bool HasFPFeatures, EmptyShell Empty);
/// Retrieve the implicit object argument for the member call.
///
@ -242,18 +239,21 @@ class CUDAKernelCallExpr final : public CallExpr {
CUDAKernelCallExpr(Expr *Fn, CallExpr *Config, ArrayRef<Expr *> Args,
QualType Ty, ExprValueKind VK, SourceLocation RP,
unsigned MinNumArgs);
FPOptionsOverride FPFeatures, unsigned MinNumArgs);
CUDAKernelCallExpr(unsigned NumArgs, EmptyShell Empty);
CUDAKernelCallExpr(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
public:
static CUDAKernelCallExpr *Create(const ASTContext &Ctx, Expr *Fn,
CallExpr *Config, ArrayRef<Expr *> Args,
QualType Ty, ExprValueKind VK,
SourceLocation RP, unsigned MinNumArgs = 0);
SourceLocation RP,
FPOptionsOverride FPFeatures,
unsigned MinNumArgs = 0);
static CUDAKernelCallExpr *CreateEmpty(const ASTContext &Ctx,
unsigned NumArgs, EmptyShell Empty);
unsigned NumArgs, bool HasFPFeatures,
EmptyShell Empty);
const CallExpr *getConfig() const {
return cast_or_null<CallExpr>(getPreArg(CONFIG));
@ -320,6 +320,16 @@ class CXXRewrittenBinaryOperator : public Expr {
bool isReversed() const { return CXXRewrittenBinaryOperatorBits.IsReversed; }
BinaryOperatorKind getOperator() const { return getDecomposedForm().Opcode; }
BinaryOperatorKind getOpcode() const { return getOperator(); }
static StringRef getOpcodeStr(BinaryOperatorKind Op) {
return BinaryOperator::getOpcodeStr(Op);
}
StringRef getOpcodeStr() const {
return BinaryOperator::getOpcodeStr(getOpcode());
}
bool isComparisonOp() const { return true; }
bool isAssignmentOp() const { return false; }
const Expr *getLHS() const { return getDecomposedForm().LHS; }
const Expr *getRHS() const { return getDecomposedForm().RHS; }
@ -374,16 +384,17 @@ class CXXNamedCastExpr : public ExplicitCastExpr {
protected:
friend class ASTStmtReader;
CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK,
CastKind kind, Expr *op, unsigned PathSize,
CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind,
Expr *op, unsigned PathSize, bool HasFPFeatures,
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc,
SourceRange AngleBrackets)
: ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l),
RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
SourceLocation RParenLoc, SourceRange AngleBrackets)
: ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, HasFPFeatures,
writtenTy),
Loc(l), RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {}
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(SC, Shell, PathSize) {}
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize,
bool HasFPFeatures)
: ExplicitCastExpr(SC, Shell, PathSize, HasFPFeatures) {}
public:
const char *getCastName() const;
@ -419,29 +430,39 @@ class CXXNamedCastExpr : public ExplicitCastExpr {
/// \c static_cast<int>(1.0).
class CXXStaticCastExpr final
: public CXXNamedCastExpr,
private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> {
private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *,
FPOptionsOverride> {
CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
SourceRange AngleBrackets)
FPOptionsOverride FPO, SourceLocation l,
SourceLocation RParenLoc, SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize,
writtenTy, l, RParenLoc, AngleBrackets) {}
FPO.requiresTrailingStorage(), writtenTy, l, RParenLoc,
AngleBrackets) {
if (hasStoredFPFeatures())
*getTrailingFPFeatures() = FPO;
}
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize)
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {}
explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize,
bool HasFPFeatures)
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize,
HasFPFeatures) {}
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
return path_size();
}
public:
friend class CastExpr;
friend TrailingObjects;
static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK, CastKind K, Expr *Op,
const CXXCastPath *Path,
TypeSourceInfo *Written, SourceLocation L,
SourceLocation RParenLoc,
SourceRange AngleBrackets);
static CXXStaticCastExpr *
Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K,
Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written,
FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc,
SourceRange AngleBrackets);
static CXXStaticCastExpr *CreateEmpty(const ASTContext &Context,
unsigned PathSize);
unsigned PathSize, bool hasFPFeatures);
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXStaticCastExprClass;
@ -456,15 +477,17 @@ class CXXStaticCastExpr final
class CXXDynamicCastExpr final
: public CXXNamedCastExpr,
private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> {
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind,
Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy,
CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op,
unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize,
writtenTy, l, RParenLoc, AngleBrackets) {}
/*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
AngleBrackets) {}
explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {}
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize,
/*HasFPFeatures*/ false) {}
public:
friend class CastExpr;
@ -499,16 +522,17 @@ class CXXReinterpretCastExpr final
: public CXXNamedCastExpr,
private llvm::TrailingObjects<CXXReinterpretCastExpr,
CXXBaseSpecifier *> {
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind,
Expr *op, unsigned pathSize,
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc,
CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op,
unsigned pathSize, TypeSourceInfo *writtenTy,
SourceLocation l, SourceLocation RParenLoc,
SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op,
pathSize, writtenTy, l, RParenLoc, AngleBrackets) {}
pathSize, /*HasFPFeatures*/ false, writtenTy, l,
RParenLoc, AngleBrackets) {}
CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize)
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {}
: CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize,
/*HasFPFeatures*/ false) {}
public:
friend class CastExpr;
@ -541,11 +565,13 @@ class CXXConstCastExpr final
CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op,
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc, SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op,
0, writtenTy, l, RParenLoc, AngleBrackets) {}
: CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, 0,
/*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
AngleBrackets) {}
explicit CXXConstCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {}
: CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0,
/*HasFPFeatures*/ false) {}
public:
friend class CastExpr;
@ -578,10 +604,12 @@ class CXXAddrspaceCastExpr final
TypeSourceInfo *writtenTy, SourceLocation l,
SourceLocation RParenLoc, SourceRange AngleBrackets)
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0,
writtenTy, l, RParenLoc, AngleBrackets) {}
/*HasFPFeatures*/ false, writtenTy, l, RParenLoc,
AngleBrackets) {}
explicit CXXAddrspaceCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0) {}
: CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0,
/*HasFPFeatures*/ false) {}
public:
friend class CastExpr;
@ -619,18 +647,20 @@ class UserDefinedLiteral final : public CallExpr {
UserDefinedLiteral(Expr *Fn, ArrayRef<Expr *> Args, QualType Ty,
ExprValueKind VK, SourceLocation LitEndLoc,
SourceLocation SuffixLoc);
SourceLocation SuffixLoc, FPOptionsOverride FPFeatures);
UserDefinedLiteral(unsigned NumArgs, EmptyShell Empty);
UserDefinedLiteral(unsigned NumArgs, bool HasFPFeatures, EmptyShell Empty);
public:
static UserDefinedLiteral *Create(const ASTContext &Ctx, Expr *Fn,
ArrayRef<Expr *> Args, QualType Ty,
ExprValueKind VK, SourceLocation LitEndLoc,
SourceLocation SuffixLoc);
SourceLocation SuffixLoc,
FPOptionsOverride FPFeatures);
static UserDefinedLiteral *CreateEmpty(const ASTContext &Ctx,
unsigned NumArgs, EmptyShell Empty);
unsigned NumArgs, bool HasFPOptions,
EmptyShell Empty);
/// The kind of literal operator which is invoked.
enum LiteralOperatorKind {
@ -838,6 +868,10 @@ class CXXTypeidExpr : public Expr {
/// evaluated, per C++11 [expr.typeid]p3.
bool isPotentiallyEvaluated() const;
/// Best-effort check if the expression operand refers to a most derived
/// object. This is not a strong guarantee.
bool isMostDerived(ASTContext &Context) const;
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
/// Retrieves the type operand of this typeid() expression after
@ -1691,34 +1725,43 @@ class CXXInheritedCtorInitExpr : public Expr {
/// \endcode
class CXXFunctionalCastExpr final
: public ExplicitCastExpr,
private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> {
private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *,
FPOptionsOverride> {
SourceLocation LParenLoc;
SourceLocation RParenLoc;
CXXFunctionalCastExpr(QualType ty, ExprValueKind VK,
TypeSourceInfo *writtenTy,
CastKind kind, Expr *castExpr, unsigned pathSize,
SourceLocation lParenLoc, SourceLocation rParenLoc)
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind,
castExpr, pathSize, writtenTy),
LParenLoc(lParenLoc), RParenLoc(rParenLoc) {}
TypeSourceInfo *writtenTy, CastKind kind,
Expr *castExpr, unsigned pathSize,
FPOptionsOverride FPO, SourceLocation lParenLoc,
SourceLocation rParenLoc)
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, castExpr,
pathSize, FPO.requiresTrailingStorage(), writtenTy),
LParenLoc(lParenLoc), RParenLoc(rParenLoc) {
if (hasStoredFPFeatures())
*getTrailingFPFeatures() = FPO;
}
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize)
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {}
explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize,
bool HasFPFeatures)
: ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize,
HasFPFeatures) {}
unsigned numTrailingObjects(OverloadToken<CXXBaseSpecifier *>) const {
return path_size();
}
public:
friend class CastExpr;
friend TrailingObjects;
static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T,
ExprValueKind VK,
TypeSourceInfo *Written,
CastKind Kind, Expr *Op,
const CXXCastPath *Path,
SourceLocation LPLoc,
SourceLocation RPLoc);
static CXXFunctionalCastExpr *CreateEmpty(const ASTContext &Context,
unsigned PathSize);
static CXXFunctionalCastExpr *
Create(const ASTContext &Context, QualType T, ExprValueKind VK,
TypeSourceInfo *Written, CastKind Kind, Expr *Op,
const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc,
SourceLocation RPLoc);
static CXXFunctionalCastExpr *
CreateEmpty(const ASTContext &Context, unsigned PathSize, bool HasFPFeatures);
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation L) { LParenLoc = L; }
@ -1996,6 +2039,9 @@ class LambdaExpr final : public Expr,
/// invented by use of an auto parameter).
ArrayRef<NamedDecl *> getExplicitTemplateParameters() const;
/// Get the trailing requires clause, if any.
Expr *getTrailingRequiresClause() const;
/// Whether this is a generic lambda.
bool isGenericLambda() const { return getTemplateParameterList(); }
@ -3394,17 +3440,18 @@ class CXXUnresolvedConstructExpr final
/// The location of the right parentheses (')').
SourceLocation RParenLoc;
CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, SourceLocation LParenLoc,
ArrayRef<Expr *> Args, SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI,
SourceLocation LParenLoc, ArrayRef<Expr *> Args,
SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
: Expr(CXXUnresolvedConstructExprClass, Empty) {
: Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) {
CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
}
public:
static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
TypeSourceInfo *Type,
QualType T, TypeSourceInfo *TSI,
SourceLocation LParenLoc,
ArrayRef<Expr *> Args,
SourceLocation RParenLoc);
@ -3436,43 +3483,43 @@ class CXXUnresolvedConstructExpr final
bool isListInitialization() const { return LParenLoc.isInvalid(); }
/// Retrieve the number of arguments.
unsigned arg_size() const { return CXXUnresolvedConstructExprBits.NumArgs; }
unsigned getNumArgs() const { return CXXUnresolvedConstructExprBits.NumArgs; }
using arg_iterator = Expr **;
using arg_range = llvm::iterator_range<arg_iterator>;
arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); }
arg_iterator arg_end() { return arg_begin() + arg_size(); }
arg_iterator arg_end() { return arg_begin() + getNumArgs(); }
arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
using const_arg_iterator = const Expr* const *;
using const_arg_range = llvm::iterator_range<const_arg_iterator>;
const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); }
const_arg_iterator arg_end() const { return arg_begin() + arg_size(); }
const_arg_iterator arg_end() const { return arg_begin() + getNumArgs(); }
const_arg_range arguments() const {
return const_arg_range(arg_begin(), arg_end());
}
Expr *getArg(unsigned I) {
assert(I < arg_size() && "Argument index out-of-range");
assert(I < getNumArgs() && "Argument index out-of-range");
return arg_begin()[I];
}
const Expr *getArg(unsigned I) const {
assert(I < arg_size() && "Argument index out-of-range");
assert(I < getNumArgs() && "Argument index out-of-range");
return arg_begin()[I];
}
void setArg(unsigned I, Expr *E) {
assert(I < arg_size() && "Argument index out-of-range");
assert(I < getNumArgs() && "Argument index out-of-range");
arg_begin()[I] = E;
}
SourceLocation getBeginLoc() const LLVM_READONLY;
SourceLocation getEndLoc() const LLVM_READONLY {
if (!RParenLoc.isValid() && arg_size() > 0)
return getArg(arg_size() - 1)->getEndLoc();
if (!RParenLoc.isValid() && getNumArgs() > 0)
return getArg(getNumArgs() - 1)->getEndLoc();
return RParenLoc;
}
@ -3483,13 +3530,13 @@ class CXXUnresolvedConstructExpr final
// Iterators
child_range children() {
auto **begin = reinterpret_cast<Stmt **>(arg_begin());
return child_range(begin, begin + arg_size());
return child_range(begin, begin + getNumArgs());
}
const_child_range children() const {
auto **begin = reinterpret_cast<Stmt **>(
const_cast<CXXUnresolvedConstructExpr *>(this)->arg_begin());
return const_child_range(begin, begin + arg_size());
return const_child_range(begin, begin + getNumArgs());
}
};
@ -4199,8 +4246,10 @@ class SubstNonTypeTemplateParmExpr : public Expr {
friend class ASTReader;
friend class ASTStmtReader;
/// The replaced parameter.
NonTypeTemplateParmDecl *Param;
/// The replaced parameter and a flag indicating if it was a reference
/// parameter. For class NTTPs, we can't determine that based on the value
/// category alone.
llvm::PointerIntPair<NonTypeTemplateParmDecl*, 1, bool> ParamAndRef;
/// The replacement expression.
Stmt *Replacement;
@ -4211,10 +4260,10 @@ class SubstNonTypeTemplateParmExpr : public Expr {
public:
SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
SourceLocation Loc,
NonTypeTemplateParmDecl *Param,
NonTypeTemplateParmDecl *Param, bool RefParam,
Expr *Replacement)
: Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
Param(Param), Replacement(Replacement) {
ParamAndRef(Param, RefParam), Replacement(Replacement) {
SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
setDependence(computeDependence(this));
}
@ -4227,7 +4276,14 @@ class SubstNonTypeTemplateParmExpr : public Expr {
Expr *getReplacement() const { return cast<Expr>(Replacement); }
NonTypeTemplateParmDecl *getParameter() const { return Param; }
NonTypeTemplateParmDecl *getParameter() const {
return ParamAndRef.getPointer();
}
bool isReferenceParameter() const { return ParamAndRef.getInt(); }
/// Determine the substituted type of the template parameter.
QualType getParameterType(const ASTContext &Ctx) const;
static bool classof(const Stmt *s) {
return s->getStmtClass() == SubstNonTypeTemplateParmExprClass;
@ -4476,6 +4532,10 @@ class MaterializeTemporaryExpr : public Expr {
return getValueKind() == VK_LValue;
}
/// Determine whether this temporary object is usable in constant
/// expressions, as specified in C++20 [expr.const]p4.
bool isUsableInConstantExpressions(const ASTContext &Context) const;
SourceLocation getBeginLoc() const LLVM_READONLY {
return getSubExpr()->getBeginLoc();
}
@ -4517,31 +4577,38 @@ class CXXFoldExpr : public Expr {
friend class ASTStmtReader;
friend class ASTStmtWriter;
enum SubExpr { Callee, LHS, RHS, Count };
SourceLocation LParenLoc;
SourceLocation EllipsisLoc;
SourceLocation RParenLoc;
// When 0, the number of expansions is not known. Otherwise, this is one more
// than the number of expansions.
unsigned NumExpansions;
Stmt *SubExprs[2];
Stmt *SubExprs[SubExpr::Count];
BinaryOperatorKind Opcode;
public:
CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS,
BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS,
SourceLocation RParenLoc, Optional<unsigned> NumExpansions)
CXXFoldExpr(QualType T, UnresolvedLookupExpr *Callee,
SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode,
SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc,
Optional<unsigned> NumExpansions)
: Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary), LParenLoc(LParenLoc),
EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc),
NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) {
SubExprs[0] = LHS;
SubExprs[1] = RHS;
SubExprs[SubExpr::Callee] = Callee;
SubExprs[SubExpr::LHS] = LHS;
SubExprs[SubExpr::RHS] = RHS;
setDependence(computeDependence(this));
}
CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {}
Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); }
Expr *getRHS() const { return static_cast<Expr*>(SubExprs[1]); }
UnresolvedLookupExpr *getCallee() const {
return static_cast<UnresolvedLookupExpr *>(SubExprs[SubExpr::Callee]);
}
Expr *getLHS() const { return static_cast<Expr*>(SubExprs[SubExpr::LHS]); }
Expr *getRHS() const { return static_cast<Expr*>(SubExprs[SubExpr::RHS]); }
/// Does this produce a right-associated sequence of operators?
bool isRightFold() const {
@ -4557,6 +4624,8 @@ class CXXFoldExpr : public Expr {
/// Get the operand that doesn't contain a pack, for a binary fold.
Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); }
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
BinaryOperatorKind getOperator() const { return Opcode; }
@ -4566,19 +4635,33 @@ class CXXFoldExpr : public Expr {
return None;
}
SourceLocation getBeginLoc() const LLVM_READONLY { return LParenLoc; }
SourceLocation getBeginLoc() const LLVM_READONLY {
if (LParenLoc.isValid())
return LParenLoc;
if (isLeftFold())
return getEllipsisLoc();
return getLHS()->getBeginLoc();
}
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
SourceLocation getEndLoc() const LLVM_READONLY {
if (RParenLoc.isValid())
return RParenLoc;
if (isRightFold())
return getEllipsisLoc();
return getRHS()->getEndLoc();
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXFoldExprClass;
}
// Iterators
child_range children() { return child_range(SubExprs, SubExprs + 2); }
child_range children() {
return child_range(SubExprs, SubExprs + SubExpr::Count);
}
const_child_range children() const {
return const_child_range(SubExprs, SubExprs + 2);
return const_child_range(SubExprs, SubExprs + SubExpr::Count);
}
};
@ -4796,7 +4879,7 @@ class BuiltinBitCastExpr final
private llvm::TrailingObjects<BuiltinBitCastExpr, CXXBaseSpecifier *> {
friend class ASTStmtReader;
friend class CastExpr;
friend class TrailingObjects;
friend TrailingObjects;
SourceLocation KWLoc;
SourceLocation RParenLoc;
@ -4805,11 +4888,11 @@ class BuiltinBitCastExpr final
BuiltinBitCastExpr(QualType T, ExprValueKind VK, CastKind CK, Expr *SrcExpr,
TypeSourceInfo *DstType, SourceLocation KWLoc,
SourceLocation RParenLoc)
: ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0,
: ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, false,
DstType),
KWLoc(KWLoc), RParenLoc(RParenLoc) {}
BuiltinBitCastExpr(EmptyShell Empty)
: ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0) {}
: ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0, false) {}
SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; }
SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }

View File

@ -126,7 +126,11 @@ class ConceptSpecializationExpr final : public Expr, public ConceptReference,
}
SourceLocation getEndLoc() const LLVM_READONLY {
return ArgsAsWritten->RAngleLoc;
// If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint
// of a TypeConstraint written syntactically as a constrained-parameter,
// there may not be a template argument list.
return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
: ConceptName.getEndLoc();
}
// Iterators

View File

@ -1639,12 +1639,12 @@ class ObjCBridgedCastExpr final
CastKind CK, SourceLocation BridgeKeywordLoc,
TypeSourceInfo *TSInfo, Expr *Operand)
: ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue,
CK, Operand, 0, TSInfo),
CK, Operand, 0, false, TSInfo),
LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {}
/// Construct an empty Objective-C bridged cast.
explicit ObjCBridgedCastExpr(EmptyShell Shell)
: ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {}
: ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0, false) {}
SourceLocation getLParenLoc() const { return LParenLoc; }

View File

@ -161,10 +161,6 @@ class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
/// Retrieve the module that corresponds to the given module ID.
virtual Module *getModule(unsigned ID) { return nullptr; }
/// Determine whether D comes from a PCH which was built with a corresponding
/// object file.
virtual bool DeclIsFromPCHWithObjectFile(const Decl *D) { return false; }
/// Return a descriptor for the corresponding module, if one exists.
virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID);

View File

@ -32,6 +32,7 @@ enum class DynamicInitKind : unsigned {
NoStub = 0,
Initializer,
AtExit,
GlobalArrayDestructor
};
enum class KernelReferenceKind : unsigned {

View File

@ -0,0 +1,161 @@
//===--- IgnoreExpr.h - Ignore intermediate Expressions -----------------===//
//
// 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 common functions to ignore intermediate expression nodes
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_IGNOREEXPR_H
#define LLVM_CLANG_AST_IGNOREEXPR_H
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
namespace clang {
namespace detail {
/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
/// Return Fn_n(...(Fn_1(E)))
inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; }
template <typename FnTy, typename... FnTys>
Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) {
return IgnoreExprNodesImpl(Fn(E), std::forward<FnTys>(Fns)...);
}
} // namespace detail
/// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
/// Recursively apply each of the functions to E until reaching a fixed point.
/// Note that a null E is valid; in this case nothing is done.
template <typename... FnTys> Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) {
Expr *LastE = nullptr;
while (E != LastE) {
LastE = E;
E = detail::IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...);
}
return E;
}
template <typename... FnTys>
const Expr *IgnoreExprNodes(const Expr *E, FnTys &&...Fns) {
return const_cast<Expr *>(IgnoreExprNodes(E, std::forward<FnTys>(Fns)...));
}
inline Expr *IgnoreImplicitCastsSingleStep(Expr *E) {
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
return ICE->getSubExpr();
if (auto *FE = dyn_cast<FullExpr>(E))
return FE->getSubExpr();
return E;
}
inline Expr *IgnoreImplicitCastsExtraSingleStep(Expr *E) {
// FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in
// addition to what IgnoreImpCasts() skips to account for the current
// behaviour of IgnoreParenImpCasts().
Expr *SubE = IgnoreImplicitCastsSingleStep(E);
if (SubE != E)
return SubE;
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
return MTE->getSubExpr();
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
return NTTP->getReplacement();
return E;
}
inline Expr *IgnoreCastsSingleStep(Expr *E) {
if (auto *CE = dyn_cast<CastExpr>(E))
return CE->getSubExpr();
if (auto *FE = dyn_cast<FullExpr>(E))
return FE->getSubExpr();
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
return MTE->getSubExpr();
if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
return NTTP->getReplacement();
return E;
}
inline Expr *IgnoreLValueCastsSingleStep(Expr *E) {
// Skip what IgnoreCastsSingleStep skips, except that only
// lvalue-to-rvalue casts are skipped.
if (auto *CE = dyn_cast<CastExpr>(E))
if (CE->getCastKind() != CK_LValueToRValue)
return E;
return IgnoreCastsSingleStep(E);
}
inline Expr *IgnoreBaseCastsSingleStep(Expr *E) {
if (auto *CE = dyn_cast<CastExpr>(E))
if (CE->getCastKind() == CK_DerivedToBase ||
CE->getCastKind() == CK_UncheckedDerivedToBase ||
CE->getCastKind() == CK_NoOp)
return CE->getSubExpr();
return E;
}
inline Expr *IgnoreImplicitSingleStep(Expr *E) {
Expr *SubE = IgnoreImplicitCastsSingleStep(E);
if (SubE != E)
return SubE;
if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
return MTE->getSubExpr();
if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
return BTE->getSubExpr();
return E;
}
inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
return ICE->getSubExprAsWritten();
return IgnoreImplicitSingleStep(E);
}
inline Expr *IgnoreParensOnlySingleStep(Expr *E) {
if (auto *PE = dyn_cast<ParenExpr>(E))
return PE->getSubExpr();
return E;
}
inline Expr *IgnoreParensSingleStep(Expr *E) {
if (auto *PE = dyn_cast<ParenExpr>(E))
return PE->getSubExpr();
if (auto *UO = dyn_cast<UnaryOperator>(E)) {
if (UO->getOpcode() == UO_Extension)
return UO->getSubExpr();
}
else if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
if (!GSE->isResultDependent())
return GSE->getResultExpr();
}
else if (auto *CE = dyn_cast<ChooseExpr>(E)) {
if (!CE->isConditionDependent())
return CE->getChosenSubExpr();
}
return E;
}
} // namespace clang
#endif // LLVM_CLANG_AST_IGNOREEXPR_H

View File

@ -123,8 +123,11 @@ class MangleContext {
void mangleBlock(const DeclContext *DC, const BlockDecl *BD,
raw_ostream &Out);
void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &);
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &);
void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &OS,
bool includePrefixByte = true,
bool includeCategoryNamespace = true);
void mangleObjCMethodNameAsSourceName(const ObjCMethodDecl *MD,
raw_ostream &);
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0;
@ -149,14 +152,9 @@ class MangleContext {
};
class ItaniumMangleContext : public MangleContext {
bool IsUniqueNameMangler = false;
public:
explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D)
: MangleContext(C, D, MK_Itanium) {}
explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D,
bool IsUniqueNameMangler)
: MangleContext(C, D, MK_Itanium),
IsUniqueNameMangler(IsUniqueNameMangler) {}
virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0;
virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0;
@ -177,15 +175,12 @@ class ItaniumMangleContext : public MangleContext {
virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0;
bool isUniqueNameMangler() { return IsUniqueNameMangler; }
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Itanium;
}
static ItaniumMangleContext *create(ASTContext &Context,
DiagnosticsEngine &Diags,
bool IsUniqueNameMangler = false);
DiagnosticsEngine &Diags);
};
class MicrosoftMangleContext : public MangleContext {

View File

@ -17,6 +17,7 @@
#include "clang/AST/DependenceFlags.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h"
@ -518,8 +519,8 @@ class NestedNameSpecifierLocBuilder {
/// Insertion operator for diagnostics. This allows sending
/// NestedNameSpecifiers into a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
NestedNameSpecifier *NNS) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
NestedNameSpecifier *NNS) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(NNS),
DiagnosticsEngine::ak_nestednamespec);
return DB;
@ -527,4 +528,33 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
} // namespace clang
namespace llvm {
template <> struct DenseMapInfo<clang::NestedNameSpecifierLoc> {
using FirstInfo = DenseMapInfo<clang::NestedNameSpecifier *>;
using SecondInfo = DenseMapInfo<void *>;
static clang::NestedNameSpecifierLoc getEmptyKey() {
return clang::NestedNameSpecifierLoc(FirstInfo::getEmptyKey(),
SecondInfo::getEmptyKey());
}
static clang::NestedNameSpecifierLoc getTombstoneKey() {
return clang::NestedNameSpecifierLoc(FirstInfo::getTombstoneKey(),
SecondInfo::getTombstoneKey());
}
static unsigned getHashValue(const clang::NestedNameSpecifierLoc &PairVal) {
return hash_combine(
FirstInfo::getHashValue(PairVal.getNestedNameSpecifier()),
SecondInfo::getHashValue(PairVal.getOpaqueData()));
}
static bool isEqual(const clang::NestedNameSpecifierLoc &LHS,
const clang::NestedNameSpecifierLoc &RHS) {
return LHS == RHS;
}
};
} // namespace llvm
#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H

View File

@ -16,6 +16,7 @@
#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
#define LLVM_CLANG_AST_OPENMPCLAUSE_H
#include "clang/AST/ASTFwd.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
@ -27,6 +28,7 @@
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
@ -4737,8 +4739,9 @@ class OMPClauseMappableExprCommon {
/// subscript it may not have any associated declaration. In that case the
/// associated declaration is set to nullptr.
class MappableComponent {
/// Expression associated with the component.
Expr *AssociatedExpression = nullptr;
/// Pair of Expression and Non-contiguous pair associated with the
/// component.
llvm::PointerIntPair<Expr *, 1, bool> AssociatedExpressionNonContiguousPr;
/// Declaration associated with the declaration. If the component does
/// not have a declaration (e.g. array subscripts or section), this is set
@ -4748,14 +4751,22 @@ class OMPClauseMappableExprCommon {
public:
explicit MappableComponent() = default;
explicit MappableComponent(Expr *AssociatedExpression,
ValueDecl *AssociatedDeclaration)
: AssociatedExpression(AssociatedExpression),
ValueDecl *AssociatedDeclaration,
bool IsNonContiguous)
: AssociatedExpressionNonContiguousPr(AssociatedExpression,
IsNonContiguous),
AssociatedDeclaration(
AssociatedDeclaration
? cast<ValueDecl>(AssociatedDeclaration->getCanonicalDecl())
: nullptr) {}
Expr *getAssociatedExpression() const { return AssociatedExpression; }
Expr *getAssociatedExpression() const {
return AssociatedExpressionNonContiguousPr.getPointer();
}
bool isNonContiguous() const {
return AssociatedExpressionNonContiguousPr.getInt();
}
ValueDecl *getAssociatedDeclaration() const {
return AssociatedDeclaration;
@ -4820,6 +4831,11 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
/// Total number of components in this clause.
unsigned NumComponents;
/// Whether this clause is possible to have user-defined mappers associated.
/// It should be true for map, to, and from clauses, and false for
/// use_device_ptr and is_device_ptr.
const bool SupportsMapper;
/// C++ nested name specifier for the associated user-defined mapper.
NestedNameSpecifierLoc MapperQualifierLoc;
@ -4840,19 +4856,21 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
/// NumUniqueDeclarations: number of unique base declarations in this clause;
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
/// \param SupportsMapper Indicates whether this clause is possible to have
/// user-defined mappers associated.
/// \param MapperQualifierLocPtr C++ nested name specifier for the associated
/// user-defined mapper.
/// \param MapperIdInfoPtr The identifier of associated user-defined mapper.
OMPMappableExprListClause(
OpenMPClauseKind K, const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes,
const OMPMappableExprListSizeTy &Sizes, bool SupportsMapper = false,
NestedNameSpecifierLoc *MapperQualifierLocPtr = nullptr,
DeclarationNameInfo *MapperIdInfoPtr = nullptr)
: OMPVarListClause<T>(K, Locs.StartLoc, Locs.LParenLoc, Locs.EndLoc,
Sizes.NumVars),
NumUniqueDeclarations(Sizes.NumUniqueDeclarations),
NumComponentLists(Sizes.NumComponentLists),
NumComponents(Sizes.NumComponents) {
NumComponents(Sizes.NumComponents), SupportsMapper(SupportsMapper) {
if (MapperQualifierLocPtr)
MapperQualifierLoc = *MapperQualifierLocPtr;
if (MapperIdInfoPtr)
@ -5051,6 +5069,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
/// Get the user-defined mapper references that are in the trailing objects of
/// the class.
MutableArrayRef<Expr *> getUDMapperRefs() {
assert(SupportsMapper &&
"Must be a clause that is possible to have user-defined mappers");
return llvm::makeMutableArrayRef<Expr *>(
static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
OMPVarListClause<T>::varlist_size(),
@ -5060,8 +5080,10 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
/// Get the user-defined mappers references that are in the trailing objects
/// of the class.
ArrayRef<Expr *> getUDMapperRefs() const {
assert(SupportsMapper &&
"Must be a clause that is possible to have user-defined mappers");
return llvm::makeArrayRef<Expr *>(
static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
static_cast<const T *>(this)->template getTrailingObjects<Expr *>() +
OMPVarListClause<T>::varlist_size(),
OMPVarListClause<T>::varlist_size());
}
@ -5071,6 +5093,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
void setUDMapperRefs(ArrayRef<Expr *> DMDs) {
assert(DMDs.size() == OMPVarListClause<T>::varlist_size() &&
"Unexpected number of user-defined mappers.");
assert(SupportsMapper &&
"Must be a clause that is possible to have user-defined mappers");
std::copy(DMDs.begin(), DMDs.end(), getUDMapperRefs().begin());
}
@ -5107,6 +5131,12 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
// The list number associated with the current declaration.
ArrayRef<unsigned>::iterator NumListsCur;
// Whether this clause is possible to have user-defined mappers associated.
const bool SupportsMapper;
// The user-defined mapper associated with the current declaration.
ArrayRef<Expr *>::iterator MapperCur;
// Remaining lists for the current declaration.
unsigned RemainingLists = 0;
@ -5127,16 +5157,20 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
explicit const_component_lists_iterator(
ArrayRef<ValueDecl *> UniqueDecls, ArrayRef<unsigned> DeclsListNum,
ArrayRef<unsigned> CumulativeListSizes,
MappableExprComponentListRef Components)
MappableExprComponentListRef Components, bool SupportsMapper,
ArrayRef<Expr *> Mappers)
: const_component_lists_iterator::iterator_adaptor_base(
Components.begin()),
DeclCur(UniqueDecls.begin()), NumListsCur(DeclsListNum.begin()),
SupportsMapper(SupportsMapper),
ListSizeCur(CumulativeListSizes.begin()),
ListSizeEnd(CumulativeListSizes.end()), End(Components.end()) {
assert(UniqueDecls.size() == DeclsListNum.size() &&
"Inconsistent number of declarations and list sizes!");
if (!DeclsListNum.empty())
RemainingLists = *NumListsCur;
if (SupportsMapper)
MapperCur = Mappers.begin();
}
/// Construct an iterator that scan lists for a given declaration \a
@ -5144,9 +5178,11 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
explicit const_component_lists_iterator(
const ValueDecl *Declaration, ArrayRef<ValueDecl *> UniqueDecls,
ArrayRef<unsigned> DeclsListNum, ArrayRef<unsigned> CumulativeListSizes,
MappableExprComponentListRef Components)
MappableExprComponentListRef Components, bool SupportsMapper,
ArrayRef<Expr *> Mappers)
: const_component_lists_iterator(UniqueDecls, DeclsListNum,
CumulativeListSizes, Components) {
CumulativeListSizes, Components,
SupportsMapper, Mappers) {
// Look for the desired declaration. While we are looking for it, we
// update the state so that we know the component where a given list
// starts.
@ -5161,6 +5197,9 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
std::advance(ListSizeCur, *NumListsCur - 1);
PrevListSize = *ListSizeCur;
++ListSizeCur;
if (SupportsMapper)
++MapperCur;
}
// If we didn't find any declaration, advance the iterator to after the
@ -5186,14 +5225,20 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
// Return the array with the current list. The sizes are cumulative, so the
// array size is the difference between the current size and previous one.
std::pair<const ValueDecl *, MappableExprComponentListRef>
std::tuple<const ValueDecl *, MappableExprComponentListRef,
const ValueDecl *>
operator*() const {
assert(ListSizeCur != ListSizeEnd && "Invalid iterator!");
return std::make_pair(
const ValueDecl *Mapper = nullptr;
if (SupportsMapper && *MapperCur)
Mapper = cast<ValueDecl>(cast<DeclRefExpr>(*MapperCur)->getDecl());
return std::make_tuple(
*DeclCur,
MappableExprComponentListRef(&*this->I, *ListSizeCur - PrevListSize));
MappableExprComponentListRef(&*this->I, *ListSizeCur - PrevListSize),
Mapper);
}
std::pair<const ValueDecl *, MappableExprComponentListRef>
std::tuple<const ValueDecl *, MappableExprComponentListRef,
const ValueDecl *>
operator->() const {
return **this;
}
@ -5216,6 +5261,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
if (!(--RemainingLists)) {
++DeclCur;
++NumListsCur;
if (SupportsMapper)
++MapperCur;
RemainingLists = *NumListsCur;
assert(RemainingLists && "No lists in the following declaration??");
}
@ -5233,13 +5280,15 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
const_component_lists_iterator component_lists_begin() const {
return const_component_lists_iterator(
getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(),
getComponentsRef());
getComponentsRef(), SupportsMapper,
SupportsMapper ? getUDMapperRefs() : llvm::None);
}
const_component_lists_iterator component_lists_end() const {
return const_component_lists_iterator(
ArrayRef<ValueDecl *>(), ArrayRef<unsigned>(), ArrayRef<unsigned>(),
MappableExprComponentListRef(getComponentsRef().end(),
getComponentsRef().end()));
getComponentsRef().end()),
SupportsMapper, llvm::None);
}
const_component_lists_range component_lists() const {
return {component_lists_begin(), component_lists_end()};
@ -5251,7 +5300,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
decl_component_lists_begin(const ValueDecl *VD) const {
return const_component_lists_iterator(
VD, getUniqueDeclsRef(), getDeclNumListsRef(),
getComponentListSizesRef(), getComponentsRef());
getComponentListSizesRef(), getComponentsRef(), SupportsMapper,
SupportsMapper ? getUDMapperRefs() : llvm::None);
}
const_component_lists_iterator decl_component_lists_end() const {
return component_lists_end();
@ -5354,7 +5404,7 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// Map-type-modifiers for the 'map' clause.
OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = {
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
OMPC_MAP_MODIFIER_unknown};
OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
/// Location of map-type-modifiers for the 'map' clause.
SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers];
@ -5399,7 +5449,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
SourceLocation MapLoc, const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
: OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes,
&MapperQualifierLoc, &MapperIdInfo),
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo),
MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {
assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() &&
"Unexpected number of map type modifiers.");
@ -5419,8 +5470,8 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes)
: OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(),
Sizes) {}
: OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), Sizes,
/*SupportsMapper=*/true) {}
/// Set map-type-modifier for the clause.
///
@ -6289,8 +6340,20 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
friend OMPVarListClause;
friend TrailingObjects;
/// Motion-modifiers for the 'to' clause.
OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = {
OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown};
/// Location of motion-modifiers for the 'to' clause.
SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers];
/// Colon location.
SourceLocation ColonLoc;
/// Build clause with number of variables \a NumVars.
///
/// \param TheMotionModifiers Motion-modifiers.
/// \param TheMotionModifiersLoc Locations of motion-modifiers.
/// \param MapperQualifierLoc C++ nested name specifier for the associated
/// user-defined mapper.
/// \param MapperIdInfo The identifier of associated user-defined mapper.
@ -6302,12 +6365,24 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
/// NumUniqueDeclarations: number of unique base declarations in this clause;
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPToClause(NestedNameSpecifierLoc MapperQualifierLoc,
explicit OMPToClause(ArrayRef<OpenMPMotionModifierKind> TheMotionModifiers,
ArrayRef<SourceLocation> TheMotionModifiersLoc,
NestedNameSpecifierLoc MapperQualifierLoc,
DeclarationNameInfo MapperIdInfo,
const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
: OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes,
&MapperQualifierLoc, &MapperIdInfo) {}
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo) {
assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() &&
"Unexpected number of motion modifiers.");
llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));
assert(llvm::array_lengthof(MotionModifiersLoc) ==
TheMotionModifiersLoc.size() &&
"Unexpected number of motion modifier locations.");
llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
}
/// Build an empty clause.
///
@ -6317,8 +6392,31 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes)
: OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(),
Sizes) {}
: OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), Sizes,
/*SupportsMapper=*/true) {}
/// Set motion-modifier for the clause.
///
/// \param I index for motion-modifier.
/// \param T motion-modifier for the clause.
void setMotionModifier(unsigned I, OpenMPMotionModifierKind T) {
assert(I < NumberOfOMPMotionModifiers &&
"Unexpected index to store motion modifier, exceeds array size.");
MotionModifiers[I] = T;
}
/// Set location for the motion-modifier.
///
/// \param I index for motion-modifier location.
/// \param TLoc motion-modifier location.
void setMotionModifierLoc(unsigned I, SourceLocation TLoc) {
assert(I < NumberOfOMPMotionModifiers &&
"Index to store motion modifier location exceeds array size.");
MotionModifiersLoc[I] = TLoc;
}
/// Set colon location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@ -6344,6 +6442,8 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
/// \param Vars The original expression used in the clause.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
/// \param MotionModifiers Motion-modifiers.
/// \param MotionModifiersLoc Location of motion-modifiers.
/// \param UDMapperRefs References to user-defined mappers associated with
/// expressions used in the clause.
/// \param UDMQualifierLoc C++ nested name specifier for the associated
@ -6354,6 +6454,8 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists,
ArrayRef<Expr *> UDMapperRefs,
ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
ArrayRef<SourceLocation> MotionModifiersLoc,
NestedNameSpecifierLoc UDMQualifierLoc,
DeclarationNameInfo MapperId);
@ -6368,6 +6470,38 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
static OMPToClause *CreateEmpty(const ASTContext &C,
const OMPMappableExprListSizeTy &Sizes);
/// Fetches the motion-modifier at 'Cnt' index of array of modifiers.
///
/// \param Cnt index for motion-modifier.
OpenMPMotionModifierKind getMotionModifier(unsigned Cnt) const LLVM_READONLY {
assert(Cnt < NumberOfOMPMotionModifiers &&
"Requested modifier exceeds the total number of modifiers.");
return MotionModifiers[Cnt];
}
/// Fetches the motion-modifier location at 'Cnt' index of array of modifiers'
/// locations.
///
/// \param Cnt index for motion-modifier location.
SourceLocation getMotionModifierLoc(unsigned Cnt) const LLVM_READONLY {
assert(Cnt < NumberOfOMPMotionModifiers &&
"Requested modifier location exceeds total number of modifiers.");
return MotionModifiersLoc[Cnt];
}
/// Fetches ArrayRef of motion-modifiers.
ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
return llvm::makeArrayRef(MotionModifiers);
}
/// Fetches ArrayRef of location of motion-modifiers.
ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
return llvm::makeArrayRef(MotionModifiersLoc);
}
/// Get colon location.
SourceLocation getColonLoc() const { return ColonLoc; }
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@ -6408,8 +6542,20 @@ class OMPFromClause final
friend OMPVarListClause;
friend TrailingObjects;
/// Motion-modifiers for the 'from' clause.
OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = {
OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown};
/// Location of motion-modifiers for the 'from' clause.
SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers];
/// Colon location.
SourceLocation ColonLoc;
/// Build clause with number of variables \a NumVars.
///
/// \param TheMotionModifiers Motion-modifiers.
/// \param TheMotionModifiersLoc Locations of motion-modifiers.
/// \param MapperQualifierLoc C++ nested name specifier for the associated
/// user-defined mapper.
/// \param MapperIdInfo The identifier of associated user-defined mapper.
@ -6421,12 +6567,24 @@ class OMPFromClause final
/// NumUniqueDeclarations: number of unique base declarations in this clause;
/// 3) NumComponentLists: number of component lists in this clause; and 4)
/// NumComponents: total number of expression components in the clause.
explicit OMPFromClause(NestedNameSpecifierLoc MapperQualifierLoc,
explicit OMPFromClause(ArrayRef<OpenMPMotionModifierKind> TheMotionModifiers,
ArrayRef<SourceLocation> TheMotionModifiersLoc,
NestedNameSpecifierLoc MapperQualifierLoc,
DeclarationNameInfo MapperIdInfo,
const OMPVarListLocTy &Locs,
const OMPMappableExprListSizeTy &Sizes)
: OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes,
&MapperQualifierLoc, &MapperIdInfo) {}
/*SupportsMapper=*/true, &MapperQualifierLoc,
&MapperIdInfo) {
assert(llvm::array_lengthof(MotionModifiers) == TheMotionModifiers.size() &&
"Unexpected number of motion modifiers.");
llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));
assert(llvm::array_lengthof(MotionModifiersLoc) ==
TheMotionModifiersLoc.size() &&
"Unexpected number of motion modifier locations.");
llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
}
/// Build an empty clause.
///
@ -6437,7 +6595,30 @@ class OMPFromClause final
/// NumComponents: total number of expression components in the clause.
explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes)
: OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(),
Sizes) {}
Sizes, /*SupportsMapper=*/true) {}
/// Set motion-modifier for the clause.
///
/// \param I index for motion-modifier.
/// \param T motion-modifier for the clause.
void setMotionModifier(unsigned I, OpenMPMotionModifierKind T) {
assert(I < NumberOfOMPMotionModifiers &&
"Unexpected index to store motion modifier, exceeds array size.");
MotionModifiers[I] = T;
}
/// Set location for the motion-modifier.
///
/// \param I index for motion-modifier location.
/// \param TLoc motion-modifier location.
void setMotionModifierLoc(unsigned I, SourceLocation TLoc) {
assert(I < NumberOfOMPMotionModifiers &&
"Index to store motion modifier location exceeds array size.");
MotionModifiersLoc[I] = TLoc;
}
/// Set colon location.
void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
@ -6463,18 +6644,21 @@ class OMPFromClause final
/// \param Vars The original expression used in the clause.
/// \param Declarations Declarations used in the clause.
/// \param ComponentLists Component lists used in the clause.
/// \param MotionModifiers Motion-modifiers.
/// \param MotionModifiersLoc Location of motion-modifiers.
/// \param UDMapperRefs References to user-defined mappers associated with
/// expressions used in the clause.
/// \param UDMQualifierLoc C++ nested name specifier for the associated
/// user-defined mapper.
/// \param MapperId The identifier of associated user-defined mapper.
static OMPFromClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars,
ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists,
ArrayRef<Expr *> UDMapperRefs,
NestedNameSpecifierLoc UDMQualifierLoc,
DeclarationNameInfo MapperId);
static OMPFromClause *
Create(const ASTContext &C, const OMPVarListLocTy &Locs,
ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
MappableExprComponentListsRef ComponentLists,
ArrayRef<Expr *> UDMapperRefs,
ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
ArrayRef<SourceLocation> MotionModifiersLoc,
NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId);
/// Creates an empty clause with the place for \a NumVars variables.
///
@ -6487,6 +6671,38 @@ class OMPFromClause final
static OMPFromClause *CreateEmpty(const ASTContext &C,
const OMPMappableExprListSizeTy &Sizes);
/// Fetches the motion-modifier at 'Cnt' index of array of modifiers.
///
/// \param Cnt index for motion-modifier.
OpenMPMotionModifierKind getMotionModifier(unsigned Cnt) const LLVM_READONLY {
assert(Cnt < NumberOfOMPMotionModifiers &&
"Requested modifier exceeds the total number of modifiers.");
return MotionModifiers[Cnt];
}
/// Fetches the motion-modifier location at 'Cnt' index of array of modifiers'
/// locations.
///
/// \param Cnt index for motion-modifier location.
SourceLocation getMotionModifierLoc(unsigned Cnt) const LLVM_READONLY {
assert(Cnt < NumberOfOMPMotionModifiers &&
"Requested modifier location exceeds total number of modifiers.");
return MotionModifiersLoc[Cnt];
}
/// Fetches ArrayRef of motion-modifiers.
ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
return llvm::makeArrayRef(MotionModifiers);
}
/// Fetches ArrayRef of location of motion-modifiers.
ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
return llvm::makeArrayRef(MotionModifiersLoc);
}
/// Get colon location.
SourceLocation getColonLoc() const { return ColonLoc; }
child_range children() {
return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
reinterpret_cast<Stmt **>(varlist_end()));
@ -7542,22 +7758,22 @@ class OMPClauseVisitorBase {
#define DISPATCH(CLASS) \
return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))
#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); }
#include "llvm/Frontend/OpenMP/OMPKinds.def"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) \
RetTy Visit##Class(PTR(Class) S) { DISPATCH(Class); }
#include "llvm/Frontend/OpenMP/OMP.inc"
RetTy Visit(PTR(OMPClause) S) {
// Top switch clause: visit each OMPClause.
switch (S->getClauseKind()) {
#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) \
case llvm::omp::Clause::Enum: \
return Visit##Class(static_cast<PTR(Class)>(S));
#define OMP_CLAUSE_NO_CLASS(Enum, Str) \
#define CLAUSE_NO_CLASS(Enum, Str) \
case llvm::omp::Clause::Enum: \
break;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
default:
break;
#include "llvm/Frontend/OpenMP/OMP.inc"
}
}
// Base case, ignore it. :)
@ -7581,18 +7797,24 @@ class OMPClausePrinter final : public OMPClauseVisitor<OMPClausePrinter> {
/// Process clauses with list of variables.
template <typename T> void VisitOMPClauseList(T *Node, char StartSym);
/// Process motion clauses.
template <typename T> void VisitOMPMotionClause(T *Node);
public:
OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
: OS(OS), Policy(Policy) {}
#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
void Visit##Class(Class *S);
#include "llvm/Frontend/OpenMP/OMPKinds.def"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S);
#include "llvm/Frontend/OpenMP/OMP.inc"
};
struct OMPTraitProperty {
llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid;
/// The raw string as we parsed it. This is needed for the `isa` trait set
/// (which accepts anything) and (later) extensions.
StringRef RawString;
};
struct OMPTraitSelector {
Expr *ScoreOrCondition = nullptr;
@ -7644,12 +7866,190 @@ class OMPTraitInfo {
/// Return a string representation identifying this context selector.
std::string getMangledName() const;
/// Check the extension trait \p TP is active.
bool isExtensionActive(llvm::omp::TraitProperty TP) {
for (const OMPTraitSet &Set : Sets) {
if (Set.Kind != llvm::omp::TraitSet::implementation)
continue;
for (const OMPTraitSelector &Selector : Set.Selectors) {
if (Selector.Kind != llvm::omp::TraitSelector::implementation_extension)
continue;
for (const OMPTraitProperty &Property : Selector.Properties) {
if (Property.Kind == TP)
return true;
}
}
}
return false;
}
/// Print a human readable representation into \p OS.
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);
/// Clang specific specialization of the OMPContext to lookup target features.
struct TargetOMPContext final : public llvm::omp::OMPContext {
TargetOMPContext(ASTContext &ASTCtx,
std::function<void(StringRef)> &&DiagUnknownTrait,
const FunctionDecl *CurrentFunctionDecl);
virtual ~TargetOMPContext() = default;
/// See llvm::omp::OMPContext::matchesISATrait
bool matchesISATrait(StringRef RawString) const override;
private:
std::function<bool(StringRef)> FeatureValidityCheck;
std::function<void(StringRef)> DiagUnknownTrait;
llvm::StringMap<bool> FeatureMap;
};
/// Contains data for OpenMP directives: clauses, children
/// expressions/statements (helpers for codegen) and associated statement, if
/// any.
class OMPChildren final
: private llvm::TrailingObjects<OMPChildren, OMPClause *, Stmt *> {
friend TrailingObjects;
friend class OMPClauseReader;
friend class OMPExecutableDirective;
template <typename T> friend class OMPDeclarativeDirective;
/// Numbers of clauses.
unsigned NumClauses = 0;
/// Number of child expressions/stmts.
unsigned NumChildren = 0;
/// true if the directive has associated statement.
bool HasAssociatedStmt = false;
/// Define the sizes of each trailing object array except the last one. This
/// is required for TrailingObjects to work properly.
size_t numTrailingObjects(OverloadToken<OMPClause *>) const {
return NumClauses;
}
OMPChildren() = delete;
OMPChildren(unsigned NumClauses, unsigned NumChildren, bool HasAssociatedStmt)
: NumClauses(NumClauses), NumChildren(NumChildren),
HasAssociatedStmt(HasAssociatedStmt) {}
static size_t size(unsigned NumClauses, bool HasAssociatedStmt,
unsigned NumChildren);
static OMPChildren *Create(void *Mem, ArrayRef<OMPClause *> Clauses);
static OMPChildren *Create(void *Mem, ArrayRef<OMPClause *> Clauses, Stmt *S,
unsigned NumChildren = 0);
static OMPChildren *CreateEmpty(void *Mem, unsigned NumClauses,
bool HasAssociatedStmt = false,
unsigned NumChildren = 0);
public:
unsigned getNumClauses() const { return NumClauses; }
unsigned getNumChildren() const { return NumChildren; }
bool hasAssociatedStmt() const { return HasAssociatedStmt; }
/// Set associated statement.
void setAssociatedStmt(Stmt *S) {
getTrailingObjects<Stmt *>()[NumChildren] = S;
}
void setChildren(ArrayRef<Stmt *> Children);
/// Sets the list of variables for this clause.
///
/// \param Clauses The list of clauses for the directive.
///
void setClauses(ArrayRef<OMPClause *> Clauses);
/// Returns statement associated with the directive.
const Stmt *getAssociatedStmt() const {
return const_cast<OMPChildren *>(this)->getAssociatedStmt();
}
Stmt *getAssociatedStmt() {
assert(HasAssociatedStmt &&
"Expected directive with the associated statement.");
return getTrailingObjects<Stmt *>()[NumChildren];
}
/// Get the clauses storage.
MutableArrayRef<OMPClause *> getClauses() {
return llvm::makeMutableArrayRef(getTrailingObjects<OMPClause *>(),
NumClauses);
}
ArrayRef<OMPClause *> getClauses() const {
return const_cast<OMPChildren *>(this)->getClauses();
}
/// Returns the captured statement associated with the
/// component region within the (combined) directive.
///
/// \param RegionKind Component region kind.
const CapturedStmt *
getCapturedStmt(OpenMPDirectiveKind RegionKind,
ArrayRef<OpenMPDirectiveKind> CaptureRegions) const {
assert(llvm::any_of(
CaptureRegions,
[=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
"RegionKind not found in OpenMP CaptureRegions.");
auto *CS = cast<CapturedStmt>(getAssociatedStmt());
for (auto ThisCaptureRegion : CaptureRegions) {
if (ThisCaptureRegion == RegionKind)
return CS;
CS = cast<CapturedStmt>(CS->getCapturedStmt());
}
llvm_unreachable("Incorrect RegionKind specified for directive.");
}
/// Get innermost captured statement for the construct.
CapturedStmt *
getInnermostCapturedStmt(ArrayRef<OpenMPDirectiveKind> CaptureRegions) {
assert(hasAssociatedStmt() && "Must have associated captured statement.");
assert(!CaptureRegions.empty() &&
"At least one captured statement must be provided.");
auto *CS = cast<CapturedStmt>(getAssociatedStmt());
for (unsigned Level = CaptureRegions.size(); Level > 1; --Level)
CS = cast<CapturedStmt>(CS->getCapturedStmt());
return CS;
}
const CapturedStmt *
getInnermostCapturedStmt(ArrayRef<OpenMPDirectiveKind> CaptureRegions) const {
return const_cast<OMPChildren *>(this)->getInnermostCapturedStmt(
CaptureRegions);
}
MutableArrayRef<Stmt *> getChildren();
ArrayRef<Stmt *> getChildren() const {
return const_cast<OMPChildren *>(this)->getChildren();
}
Stmt *getRawStmt() {
assert(HasAssociatedStmt &&
"Expected directive with the associated statement.");
if (auto *CS = dyn_cast<CapturedStmt>(getAssociatedStmt())) {
Stmt *S = nullptr;
do {
S = CS->getCapturedStmt();
CS = dyn_cast<CapturedStmt>(S);
} while (CS);
return S;
}
return getAssociatedStmt();
}
const Stmt *getRawStmt() const {
return const_cast<OMPChildren *>(this)->getRawStmt();
}
Stmt::child_range getAssociatedStmtAsRange() {
if (!HasAssociatedStmt)
return Stmt::child_range(Stmt::child_iterator(), Stmt::child_iterator());
return Stmt::child_range(&getTrailingObjects<Stmt *>()[NumChildren],
&getTrailingObjects<Stmt *>()[NumChildren + 1]);
}
};
} // namespace clang
#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H

View File

@ -77,9 +77,10 @@ CAST_OPERATION(LValueToRValueBitCast)
CAST_OPERATION(LValueToRValue)
/// CK_NoOp - A conversion which does not affect the type other than
/// (possibly) adding qualifiers.
/// (possibly) adding qualifiers or removing noexcept.
/// int -> int
/// char** -> const char * const *
/// void () noexcept -> void ()
CAST_OPERATION(NoOp)
/// CK_BaseToDerived - A conversion from a C++ class pointer/reference
@ -201,6 +202,14 @@ CAST_OPERATION(IntegralToBoolean)
/// float f = i;
CAST_OPERATION(IntegralToFloating)
/// CK_FloatingToFixedPoint - Floating to fixed point.
/// _Accum a = f;
CAST_OPERATION(FloatingToFixedPoint)
/// CK_FixedPointToFloating - Fixed point to floating.
/// (float) 2.5k
CAST_OPERATION(FixedPointToFloating)
/// CK_FixedPointCast - Fixed point to fixed point.
/// (_Accum) 0.5r
CAST_OPERATION(FixedPointCast)

View File

@ -63,7 +63,7 @@ class OptionalDiagnostic {
return *this;
}
OptionalDiagnostic &operator<<(const APFixedPoint &FX) {
OptionalDiagnostic &operator<<(const llvm::APFixedPoint &FX) {
if (Diag) {
SmallVector<char, 32> Buffer;
FX.toString(Buffer);

View File

@ -51,9 +51,7 @@ class ParentMap {
return getParentIgnoreParenCasts(const_cast<Stmt*>(S));
}
bool hasParent(Stmt* S) const {
return getParent(S) != nullptr;
}
bool hasParent(const Stmt *S) const { return getParent(S) != nullptr; }
bool isConsumedExpr(Expr *E) const;

View File

@ -94,25 +94,24 @@ class DynTypedNodeList {
public:
DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
new (Storage.buffer) DynTypedNode(N);
new (&Storage) DynTypedNode(N);
}
DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
new (Storage.buffer) ArrayRef<DynTypedNode>(A);
new (&Storage) ArrayRef<DynTypedNode>(A);
}
const DynTypedNode *begin() const {
if (!IsSingleNode)
return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)
->begin();
return reinterpret_cast<const DynTypedNode *>(Storage.buffer);
return reinterpret_cast<const DynTypedNode *>(&Storage);
}
const DynTypedNode *end() const {
if (!IsSingleNode)
return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
->end();
return reinterpret_cast<const DynTypedNode *>(Storage.buffer) + 1;
return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage)->end();
return reinterpret_cast<const DynTypedNode *>(&Storage) + 1;
}
size_t size() const { return end() - begin(); }

View File

@ -18,6 +18,7 @@
namespace clang {
class DeclContext;
class LangOptions;
class SourceManager;
class Stmt;
@ -39,6 +40,15 @@ class PrintingCallbacks {
virtual std::string remapPath(StringRef Path) const {
return std::string(Path);
}
/// When printing type to be inserted into code in specific context, this
/// callback can be used to avoid printing the redundant part of the
/// qualifier. For example, when inserting code inside namespace foo, we
/// should print bar::SomeType instead of foo::bar::SomeType.
/// To do this, shouldPrintScope should return true on "foo" NamespaceDecl.
/// The printing stops at the first isScopeVisible() == true, so there will
/// be no calls with outer scopes.
virtual bool isScopeVisible(const DeclContext *DC) const { return false; }
};
/// Describes how types, statements, expressions, and declarations should be
@ -52,12 +62,13 @@ struct PrintingPolicy {
: Indentation(2), SuppressSpecifiers(false),
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
SuppressScope(false), SuppressUnwrittenScope(false),
SuppressInitializers(false), ConstantArraySizeAsWritten(false),
AnonymousTagLocations(true), SuppressStrongLifetime(false),
SuppressLifetimeQualifiers(false),
SuppressTemplateArgsInCXXConstructors(false), Bool(LO.Bool),
Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),
UseVoidForZeroParams(!LO.CPlusPlus),
SuppressInlineNamespace(true), SuppressInitializers(false),
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
SuppressTemplateArgsInCXXConstructors(false),
SuppressDefaultTemplateArgs(true), Bool(LO.Bool),
Nullptr(LO.CPlusPlus11), Restrict(LO.C99), Alignof(LO.CPlusPlus11),
UnderscoreAlignof(LO.C11), UseVoidForZeroParams(!LO.CPlusPlus),
SplitTemplateClosers(!LO.CPlusPlus11), TerseOutput(false),
PolishForDeclaration(false), Half(LO.Half),
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
@ -117,10 +128,15 @@ struct PrintingPolicy {
/// Suppresses printing of scope specifiers.
unsigned SuppressScope : 1;
/// Suppress printing parts of scope specifiers that don't need
/// to be written, e.g., for inline or anonymous namespaces.
/// Suppress printing parts of scope specifiers that are never
/// written, e.g., for anonymous namespaces.
unsigned SuppressUnwrittenScope : 1;
/// Suppress printing parts of scope specifiers that correspond
/// to inline namespaces, where the name is unambiguous with the specifier
/// removed.
unsigned SuppressInlineNamespace : 1;
/// Suppress printing of variable initializers.
///
/// This flag is used when printing the loop variable in a for-range
@ -167,10 +183,18 @@ struct PrintingPolicy {
/// constructors.
unsigned SuppressTemplateArgsInCXXConstructors : 1;
/// When true, attempt to suppress template arguments that match the default
/// argument for the parameter.
unsigned SuppressDefaultTemplateArgs : 1;
/// Whether we can use 'bool' rather than '_Bool' (even if the language
/// doesn't actually have 'bool', because, e.g., it is defined as a macro).
unsigned Bool : 1;
/// Whether we should use 'nullptr' rather than '0' as a null pointer
/// constant.
unsigned Nullptr : 1;
/// Whether we can use 'restrict' rather than '__restrict'.
unsigned Restrict : 1;

View File

@ -72,6 +72,8 @@ class CountPropertyType<string typeName = ""> : PropertyType<typeName> {
def APInt : PropertyType<"llvm::APInt"> { let PassByReference = 1; }
def APSInt : PropertyType<"llvm::APSInt"> { let PassByReference = 1; }
def APValue : PropertyType { let PassByReference = 1; }
def APValueKind : EnumPropertyType<"APValue::ValueKind">;
def ArraySizeModifier : EnumPropertyType<"ArrayType::ArraySizeModifier">;
def AttrKind : EnumPropertyType<"attr::Kind">;
def AutoTypeKeyword : EnumPropertyType;
@ -109,7 +111,15 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"ValueDecl", DeclRef>;
def ElaboratedTypeKeyword : EnumPropertyType;
def ExtParameterInfo : PropertyType<"FunctionProtoType::ExtParameterInfo">;
def FixedPointSemantics : PropertyType<"llvm::FixedPointSemantics"> {
let PassByReference = 1;
}
def Identifier : RefPropertyType<"IdentifierInfo"> { let ConstWhenWriting = 1; }
def LValuePathEntry : PropertyType<"APValue::LValuePathEntry">;
def LValuePathSerializationHelper :
PropertyType<"APValue::LValuePathSerializationHelper"> {
let BufferElementTypes = [ LValuePathEntry ];
}
def NestedNameSpecifier : PropertyType<"NestedNameSpecifier *">;
def NestedNameSpecifierKind :
EnumPropertyType<"NestedNameSpecifier::SpecifierKind">;
@ -237,6 +247,304 @@ class PropertyTypeCase<PropertyType type, string name> : HasProperties {
string Name = name;
}
// Type cases for APValue.
def : PropertyTypeKind<APValue, APValueKind,
"node.getKind()">;
let Class = PropertyTypeCase<APValue, "None"> in {
def : Creator<[{ return APValue(); }]>;
}
let Class = PropertyTypeCase<APValue, "Indeterminate"> in {
def : Creator<[{ return APValue::IndeterminateValue(); }]>;
}
let Class = PropertyTypeCase<APValue, "Int"> in {
def : Property<"value", APSInt> {
let Read = [{ node.getInt() }];
}
def : Creator<[{ return APValue(value); }]>;
}
let Class = PropertyTypeCase<APValue, "Float"> in {
def : Property<"semantics", UInt32> {
let Read = [{
static_cast<uint32_t>(
llvm::APFloatBase::SemanticsToEnum(node.getFloat().getSemantics()))
}];
}
def : Property<"value", APInt> {
let Read = [{ node.getFloat().bitcastToAPInt() }];
}
def : Creator<[{
const llvm::fltSemantics &floatSema = llvm::APFloatBase::EnumToSemantics(
static_cast<llvm::APFloatBase::Semantics>(semantics));
return APValue(llvm::APFloat(floatSema, value));
}]>;
}
let Class = PropertyTypeCase<APValue, "FixedPoint"> in {
def : Property<"semantics", FixedPointSemantics> {
let Read = [{ node.getFixedPoint().getSemantics() }];
}
def : Property<"value", APSInt> {
let Read = [{ node.getFixedPoint().getValue() }];
}
def : Creator<[{
return APValue(llvm::APFixedPoint(std::move(value), semantics));
}]>;
}
let Class = PropertyTypeCase<APValue, "ComplexInt"> in {
def : Property<"real", APSInt> {
let Read = [{ node.getComplexIntReal() }];
}
def : Property<"imag", APSInt> {
let Read = [{ node.getComplexIntImag() }];
}
def : Creator<[{ return APValue(real, imag); }]>;
}
let Class = PropertyTypeCase<APValue, "ComplexFloat"> in {
def : ReadHelper<[{
auto sema = llvm::APFloatBase::SemanticsToEnum(
node.getComplexFloatReal().getSemantics());
assert(sema == llvm::APFloatBase::SemanticsToEnum(
node.getComplexFloatImag().getSemantics()));
}]>;
def : Property<"semantics", UInt32> {
let Read = [{ static_cast<uint32_t>(sema) }];
}
def : Property<"real", APInt> {
let Read = [{ node.getComplexFloatReal().bitcastToAPInt() }];
}
def : Property<"imag", APInt> {
let Read = [{ node.getComplexFloatImag().bitcastToAPInt() }];
}
def : Creator<[{
const llvm::fltSemantics &sema = llvm::APFloatBase::EnumToSemantics(
static_cast<llvm::APFloatBase::Semantics>(semantics));
return APValue(llvm::APFloat(sema, real),
llvm::APFloat(sema, imag));
}]>;
}
let Class = PropertyTypeCase<APValue, "Vector"> in {
def : ReadHelper<[{
SmallVector<APValue, 4> buffer;
unsigned len = node.getVectorLength();
for (unsigned i = 0; i < len; ++i)
buffer.push_back(node.getVectorElt(i));
}]>;
def : Property<"elements", Array<APValue>> {
let Read = [{ buffer }];
}
def : Creator<[{
APValue result;
result.MakeVector();
unsigned length = elements.size();
(void)result.setVectorUninit(length);
for (unsigned i = 0; i < length; i++)
result.getVectorElt(i) = elements[i];
return result;
}]>;
}
let Class = PropertyTypeCase<APValue, "Array"> in {
def : ReadHelper<[{
SmallVector<APValue, 4> buffer{};
unsigned initLength = node.getArrayInitializedElts();
for (unsigned i = 0; i < initLength; ++i)
buffer.push_back(node.getArrayInitializedElt(i));
if (node.hasArrayFiller())
buffer.push_back(node.getArrayFiller());
}]>;
def : Property<"totalLength", UInt32> {
let Read = [{ node.getArraySize() }];
}
def : Property<"hasFiller", Bool> {
let Read = [{ node.hasArrayFiller() }];
}
def : Property<"elements", Array<APValue>> {
let Read = [{ buffer }];
}
def : Creator<[{
APValue result;
unsigned initLength = elements.size() - (hasFiller ? 1 : 0);
result.MakeArray(initLength, totalLength);
for (unsigned i = 0; i < initLength; ++i)
result.getArrayInitializedElt(i) = elements[i];
if (hasFiller)
result.getArrayFiller() = elements.back();
return result;
}]>;
}
let Class = PropertyTypeCase<APValue, "Struct"> in {
def : ReadHelper<[{
SmallVector<APValue, 4> structBases;
unsigned numBases = node.getStructNumBases();
for (unsigned i = 0; i < numBases; ++i)
structBases.push_back(node.getStructBase(i));
SmallVector<APValue, 4> structFields;
unsigned numFields = node.getStructNumFields();
for (unsigned i = 0; i < numFields; ++i)
structFields.push_back(node.getStructField(i));
}]>;
def : Property<"bases", Array<APValue>> {
let Read = [{ structBases }];
}
def : Property<"fields", Array<APValue>> {
let Read = [{ structFields }];
}
def : Creator<[{
APValue result;
result.MakeStruct(bases.size(), fields.size());
for (unsigned i = 0; i < bases.size(); ++i)
result.getStructBase(i) = bases[i];
for (unsigned i = 0; i < fields.size(); ++i)
result.getStructField(i) = fields[i];
return result;
}]>;
}
let Class = PropertyTypeCase<APValue, "Union"> in {
def : Property<"fieldDecl", DeclRef> {
let Read = [{ node.getUnionField() }];
}
def : Property<"value", APValue> {
let Read = [{ node.getUnionValue() }];
}
def : Creator<[{
return APValue(cast<clang::FieldDecl>(fieldDecl), std::move(value));
}]>;
}
let Class = PropertyTypeCase<APValue, "AddrLabelDiff"> in {
def : Property<"lhs", StmtRef> {
let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffLHS()) }];
}
def : Property<"rhs", StmtRef> {
let Read = [{ const_cast<AddrLabelExpr *>(node.getAddrLabelDiffRHS()) }];
}
def : Creator<[{
return APValue(cast<AddrLabelExpr>(lhs), cast<AddrLabelExpr>(rhs));
}]>;
}
let Class = PropertyTypeCase<APValue, "MemberPointer"> in {
def : Property<"isDerived", Bool> {
let Read = [{ node.isMemberPointerToDerivedMember() }];
}
def : Property<"member", ValueDeclRef> {
let Read = [{ node.getMemberPointerDecl() }];
}
def : Property<"memberPath", Array<CXXRecordDeclRef>> {
let Read = [{ node.getMemberPointerPath() }];
}
def : Creator<[{
APValue result;
unsigned pathSize = memberPath.size();
const CXXRecordDecl **pathArray =
result.setMemberPointerUninit(member, isDerived, pathSize).data();
for (unsigned i = 0; i < pathSize; ++i)
pathArray[i] = memberPath[i]->getCanonicalDecl();
return result;
}]>;
}
let Class = PropertyTypeCase<APValue, "LValue"> in {
def : ReadHelper<[{
auto lvalueBase = node.getLValueBase();
const Expr *expr =
lvalueBase ? lvalueBase.dyn_cast<const Expr *>() : nullptr;
bool lvalueBaseIsExpr = (bool) expr;
bool lvalueBaseIsTypeInfo = lvalueBase.is<TypeInfoLValue>();
QualType elemTy;
if (lvalueBase) {
if (lvalueBaseIsTypeInfo) {
elemTy = lvalueBase.getTypeInfoType();
} else if (lvalueBaseIsExpr) {
elemTy = expr->getType();
} else {
elemTy = lvalueBase.get<const ValueDecl *>()->getType();
}
}
}]>;
def : Property<"hasLValuePath", Bool> {
let Read = [{ node.hasLValuePath() }];
}
def : Property<"isLValueOnePastTheEnd", Bool> {
let Read = [{ node.isLValueOnePastTheEnd() }];
}
def : Property<"isExpr", Bool> {
let Read = [{ lvalueBaseIsExpr }];
}
def : Property<"isTypeInfo", Bool> {
let Read = [{ lvalueBaseIsTypeInfo }];
}
def : Property<"hasBase", Bool> {
let Read = [{ static_cast<bool>(lvalueBase) }];
}
def : Property<"isNullPtr", Bool> {
let Read = [{ node.isNullPointer() }];
}
def : Property<"typeInfo", QualType> {
let Conditional = [{ hasBase && isTypeInfo }];
let Read = [{
QualType(node.getLValueBase().get<TypeInfoLValue>().getType(), 0)
}];
}
def : Property<"type", QualType> {
let Conditional = [{ hasBase && isTypeInfo }];
let Read = [{ node.getLValueBase().getTypeInfoType() }];
}
def : Property<"callIndex", UInt32> {
let Conditional = [{ hasBase && !isTypeInfo }];
let Read = [{ node.getLValueBase().getCallIndex() }];
}
def : Property<"version", UInt32> {
let Conditional = [{ hasBase && !isTypeInfo }];
let Read = [{ node.getLValueBase().getVersion() }];
}
def : Property<"stmt", StmtRef> {
let Conditional = [{ hasBase && !isTypeInfo && isExpr }];
let Read = [{ const_cast<Expr *>(expr) }];
}
def : Property<"decl", DeclRef> {
let Conditional = [{ hasBase && !isTypeInfo && !isExpr }];
let Read = [{ lvalueBase.get<const ValueDecl *>() }];
}
def : Property<"offsetQuantity", UInt32> {
let Read = [{ node.getLValueOffset().getQuantity() }];
}
def : Property<"lvaluePath", LValuePathSerializationHelper> {
let Conditional = [{ hasLValuePath }];
let Read = [{
APValue::LValuePathSerializationHelper(node.getLValuePath(), elemTy)
}];
}
def : Creator<[{
(void)ctx;
APValue::LValueBase base;
QualType elemTy;
if (hasBase) {
if (isTypeInfo) {
base = APValue::LValueBase::getTypeInfo(
TypeInfoLValue(typeInfo.getValue().getTypePtr()), type.getValue());
elemTy = base.getTypeInfoType();
} else if (isExpr) {
base = APValue::LValueBase(cast<Expr>(stmt.getValue()),
callIndex.getValue(), version.getValue());
elemTy = base.get<const Expr *>()->getType();
} else {
base = APValue::LValueBase(cast<ValueDecl>(decl.getValue()),
callIndex.getValue(), version.getValue());
elemTy = base.get<const ValueDecl *>()->getType();
}
}
CharUnits offset = CharUnits::fromQuantity(offsetQuantity);
APValue result;
result.MakeLValue();
if (!hasLValuePath) {
result.setLValue(base, offset, APValue::NoLValuePath{}, isNullPtr);
return result;
}
auto pathLength = lvaluePath->Path.size();
APValue::LValuePathEntry *path = result.setLValueUninit(
base, offset, pathLength, isLValueOnePastTheEnd, isNullPtr).data();
assert(lvaluePath->getType() == elemTy && "Unexpected type reference!");
llvm::copy(lvaluePath->Path, path);
return result;
}]>;
}
// Type cases for DeclarationName.
def : PropertyTypeKind<DeclarationName, DeclarationNameKind,
"node.getNameKind()">;

View File

@ -70,6 +70,11 @@ class ASTRecordLayout {
// Alignment - Alignment of record in characters.
CharUnits Alignment;
// PreferredAlignment - Preferred alignment of record in characters. This
// can be different than Alignment in cases where it is beneficial for
// performance or backwards compatibility preserving (e.g. AIX-ABI).
CharUnits PreferredAlignment;
// UnadjustedAlignment - Maximum of the alignments of the record members in
// characters.
CharUnits UnadjustedAlignment;
@ -91,6 +96,11 @@ class ASTRecordLayout {
/// which is the alignment of the object without virtual bases.
CharUnits NonVirtualAlignment;
/// PreferredNVAlignment - The preferred non-virtual alignment (in chars) of
/// an object, which is the preferred alignment of the object without
/// virtual bases.
CharUnits PreferredNVAlignment;
/// SizeOfLargestEmptySubobject - The size of the largest empty subobject
/// (either a base or a member). Will be zero if the class doesn't contain
/// any empty subobjects.
@ -139,30 +149,26 @@ class ASTRecordLayout {
CXXRecordLayoutInfo *CXXInfo = nullptr;
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
CharUnits unadjustedAlignment,
CharUnits preferredAlignment, CharUnits unadjustedAlignment,
CharUnits requiredAlignment, CharUnits datasize,
ArrayRef<uint64_t> fieldoffsets);
using BaseOffsetsMapTy = CXXRecordLayoutInfo::BaseOffsetsMapTy;
// Constructor for C++ records.
ASTRecordLayout(const ASTContext &Ctx,
CharUnits size, CharUnits alignment,
CharUnits unadjustedAlignment,
CharUnits requiredAlignment,
bool hasOwnVFPtr, bool hasExtendableVFPtr,
CharUnits vbptroffset,
CharUnits datasize,
ArrayRef<uint64_t> fieldoffsets,
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
CharUnits preferredAlignment, CharUnits unadjustedAlignment,
CharUnits requiredAlignment, bool hasOwnVFPtr,
bool hasExtendableVFPtr, CharUnits vbptroffset,
CharUnits datasize, ArrayRef<uint64_t> fieldoffsets,
CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
CharUnits preferrednvalignment,
CharUnits SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool IsPrimaryBaseVirtual,
const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual,
const CXXRecordDecl *BaseSharingVBPtr,
bool EndsWithZeroSizedObject,
bool LeadsWithZeroSizedBase,
const BaseOffsetsMapTy& BaseOffsets,
const VBaseOffsetsMapTy& VBaseOffsets);
bool EndsWithZeroSizedObject, bool LeadsWithZeroSizedBase,
const BaseOffsetsMapTy &BaseOffsets,
const VBaseOffsetsMapTy &VBaseOffsets);
~ASTRecordLayout() = default;
@ -175,6 +181,10 @@ class ASTRecordLayout {
/// getAlignment - Get the record alignment in characters.
CharUnits getAlignment() const { return Alignment; }
/// getPreferredFieldAlignment - Get the record preferred alignment in
/// characters.
CharUnits getPreferredAlignment() const { return PreferredAlignment; }
/// getUnadjustedAlignment - Get the record alignment in characters, before
/// alignment adjustement.
CharUnits getUnadjustedAlignment() const { return UnadjustedAlignment; }
@ -193,9 +203,7 @@ class ASTRecordLayout {
/// getDataSize() - Get the record data size, which is the record size
/// without tail padding, in characters.
CharUnits getDataSize() const {
return DataSize;
}
CharUnits getDataSize() const { return DataSize; }
/// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
/// which is the size of the object without virtual bases.
@ -205,14 +213,23 @@ class ASTRecordLayout {
return CXXInfo->NonVirtualSize;
}
/// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
/// which is the alignment of the object without virtual bases.
/// getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an
/// object, which is the alignment of the object without virtual bases.
CharUnits getNonVirtualAlignment() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->NonVirtualAlignment;
}
/// getPreferredNVAlignment - Get the preferred non-virtual alignment (in
/// chars) of an object, which is the preferred alignment of the object
/// without virtual bases.
CharUnits getPreferredNVAlignment() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->PreferredNVAlignment;
}
/// getPrimaryBase - Get the primary base for this record.
const CXXRecordDecl *getPrimaryBase() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
@ -231,6 +248,8 @@ class ASTRecordLayout {
/// getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
Base = Base->getDefinition();
assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
return CXXInfo->BaseOffsets[Base];
@ -239,6 +258,8 @@ class ASTRecordLayout {
/// getVBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
VBase = VBase->getDefinition();
assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
@ -287,9 +308,7 @@ class ASTRecordLayout {
return !CXXInfo->VBPtrOffset.isNegative();
}
CharUnits getRequiredAlignment() const {
return RequiredAlignment;
}
CharUnits getRequiredAlignment() const { return RequiredAlignment; }
bool endsWithZeroSizedObject() const {
return CXXInfo && CXXInfo->EndsWithZeroSizedObject;

View File

@ -461,6 +461,15 @@ template <typename Derived> class RecursiveASTVisitor {
bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child);
#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
DEF_TRAVERSE_TMPL_INST(Class)
DEF_TRAVERSE_TMPL_INST(Var)
DEF_TRAVERSE_TMPL_INST(Function)
#undef DEF_TRAVERSE_TMPL_INST
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
private:
// These are helper methods used by more than one Traverse* method.
bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
@ -469,12 +478,6 @@ template <typename Derived> class RecursiveASTVisitor {
template <typename T>
bool TraverseDeclTemplateParameterLists(T *D);
#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
DEF_TRAVERSE_TMPL_INST(Class)
DEF_TRAVERSE_TMPL_INST(Var)
DEF_TRAVERSE_TMPL_INST(Function)
#undef DEF_TRAVERSE_TMPL_INST
bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
unsigned Count);
bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
@ -487,15 +490,15 @@ template <typename Derived> class RecursiveASTVisitor {
bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
bool TraverseOMPLoopDirective(OMPLoopDirective *S);
bool TraverseOMPClause(OMPClause *C);
#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
#include "llvm/Frontend/OpenMP/OMPKinds.def"
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
#include "llvm/Frontend/OpenMP/OMP.inc"
/// Process clauses with list of variables.
template <typename T> bool VisitOMPClauseList(T *Node);
/// Process clauses with pre-initis.
bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node);
bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node);
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
bool PostVisitStmt(Stmt *S);
};
@ -1777,8 +1780,17 @@ DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
// D is the "T" in something like "template<typename T> class vector;"
if (D->getTypeForDecl())
TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
if (const auto *TC = D->getTypeConstraint())
TRY_TO(TraverseConceptReference(*TC));
if (const auto *TC = D->getTypeConstraint()) {
if (Expr *IDC = TC->getImmediatelyDeclaredConstraint()) {
TRY_TO(TraverseStmt(IDC));
} else {
// Avoid traversing the ConceptReference in the TypeCosntraint
// if we have an immediately-declared-constraint, otherwise
// we'll end up visiting the concept and the arguments in
// the TC twice.
TRY_TO(TraverseConceptReference(*TC));
}
}
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
})
@ -1961,6 +1973,8 @@ DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
DEF_TRAVERSE_DECL(MSGuidDecl, {})
DEF_TRAVERSE_DECL(TemplateParamObjectDecl, {})
DEF_TRAVERSE_DECL(FieldDecl, {
TRY_TO(TraverseDeclaratorHelper(D));
if (D->isBitField())
@ -2491,17 +2505,12 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
for (Decl *D : S->getExplicitTemplateParameters()) {
// Visit explicit template parameters.
TRY_TO(TraverseDecl(D));
}
TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
if (S->hasExplicitParameters()) {
// Visit parameters.
for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
TRY_TO(TraverseDecl(Proto.getParam(I)));
}
if (S->hasExplicitResultType())
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
auto *T = Proto.getTypePtr();
for (const auto &E : T->exceptions())
@ -2510,6 +2519,10 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
if (Expr *NE = T->getNoexceptExpr())
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
if (S->hasExplicitResultType())
TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getTrailingRequiresClause());
TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
}
ShouldVisitChildren = false;
@ -2938,16 +2951,15 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
if (!C)
return true;
switch (C->getClauseKind()) {
#define OMP_CLAUSE_CLASS(Enum, Str, Class) \
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) \
case llvm::omp::Clause::Enum: \
TRY_TO(Visit##Class(static_cast<Class *>(C))); \
break;
#define OMP_CLAUSE_NO_CLASS(Enum, Str) \
#define CLAUSE_NO_CLASS(Enum, Str) \
case llvm::omp::Clause::Enum: \
break;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
default:
break;
#include "llvm/Frontend/OpenMP/OMP.inc"
}
return true;
}

View File

@ -370,6 +370,7 @@ template <typename decl_type> class CanonicalDeclPtr {
private:
friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
friend struct llvm::PointerLikeTypeTraits<CanonicalDeclPtr<decl_type>>;
decl_type *Ptr = nullptr;
};
@ -407,6 +408,20 @@ struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
}
};
template <typename decl_type>
struct PointerLikeTypeTraits<clang::CanonicalDeclPtr<decl_type>> {
static inline void *getAsVoidPointer(clang::CanonicalDeclPtr<decl_type> P) {
return P.Ptr;
}
static inline clang::CanonicalDeclPtr<decl_type> getFromVoidPointer(void *P) {
clang::CanonicalDeclPtr<decl_type> C;
C.Ptr = PointerLikeTypeTraits<decl_type *>::getFromVoidPtr(P);
return C;
}
static constexpr int NumLowBitsAvailable =
PointerLikeTypeTraits<decl_type *>::NumLowBitsAvailable;
};
} // namespace llvm
#endif // LLVM_CLANG_AST_REDECLARABLE_H

View File

@ -464,8 +464,11 @@ class alignas(void *) Stmt {
/// True if the callee of the call expression was found using ADL.
unsigned UsesADL : 1;
/// True if the call expression has some floating-point features.
unsigned HasFPFeatures : 1;
/// Padding used to align OffsetToTrailingObjects to a byte multiple.
unsigned : 24 - 2 - NumExprBits;
unsigned : 24 - 3 - NumExprBits;
/// The offset in bytes from the this pointer to the start of the
/// trailing objects belonging to CallExpr. Intentionally byte sized
@ -518,6 +521,9 @@ class alignas(void *) Stmt {
unsigned Kind : 6;
unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr.
/// True if the call expression has some floating-point features.
unsigned HasFPFeatures : 1;
/// The number of CXXBaseSpecifiers in the cast. 14 bits would be enough
/// here. ([implimits] Direct and indirect base classes [16384]).
unsigned BasePathSize;
@ -1095,6 +1101,14 @@ class alignas(void *) Stmt {
/// de-serialization).
struct EmptyShell {};
/// The likelihood of a branch being taken.
enum Likelihood {
LH_Unlikely = -1, ///< Branch has the [[unlikely]] attribute.
LH_None, ///< No attribute set or branches of the IfStmt have
///< the same attribute.
LH_Likely ///< Branch has the [[likely]] attribute.
};
protected:
/// Iterator for iterating over Stmt * arrays that contain only T *.
///
@ -1163,6 +1177,26 @@ class alignas(void *) Stmt {
static void EnableStatistics();
static void PrintStats();
/// \returns the likelihood of a set of attributes.
static Likelihood getLikelihood(ArrayRef<const Attr *> Attrs);
/// \returns the likelihood of a statement.
static Likelihood getLikelihood(const Stmt *S);
/// \returns the likelihood attribute of a statement.
static const Attr *getLikelihoodAttr(const Stmt *S);
/// \returns the likelihood of the 'then' branch of an 'if' statement. The
/// 'else' branch is required to determine whether both branches specify the
/// same likelihood, which affects the result.
static Likelihood getLikelihood(const Stmt *Then, const Stmt *Else);
/// \returns whether the likelihood of the branches of an if statement are
/// conflicting. When the first element is \c true there's a conflict and
/// the Attr's are the conflicting attributes of the Then and Else Stmt.
static std::tuple<bool, const Attr *, const Attr *>
determineLikelihoodConflict(const Stmt *Then, const Stmt *Else);
/// Dumps the specified AST fragment and all subtrees to
/// \c llvm::errs().
void dump() const;
@ -1892,6 +1926,8 @@ class IfStmt final
// Present if and only if hasElseStorage().
enum { InitOffset = 0, ThenOffsetFromCond = 1, ElseOffsetFromCond = 2 };
enum { NumMandatoryStmtPtr = 2 };
SourceLocation LParenLoc;
SourceLocation RParenLoc;
unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
return NumMandatoryStmtPtr + hasElseStorage() + hasVarStorage() +
@ -1912,7 +1948,8 @@ class IfStmt final
/// Build an if/then/else statement.
IfStmt(const ASTContext &Ctx, SourceLocation IL, bool IsConstexpr, Stmt *Init,
VarDecl *Var, Expr *Cond, Stmt *Then, SourceLocation EL, Stmt *Else);
VarDecl *Var, Expr *Cond, SourceLocation LParenLoc,
SourceLocation RParenLoc, Stmt *Then, SourceLocation EL, Stmt *Else);
/// Build an empty if/then/else statement.
explicit IfStmt(EmptyShell Empty, bool HasElse, bool HasVar, bool HasInit);
@ -1921,7 +1958,8 @@ class IfStmt final
/// Create an IfStmt.
static IfStmt *Create(const ASTContext &Ctx, SourceLocation IL,
bool IsConstexpr, Stmt *Init, VarDecl *Var, Expr *Cond,
Stmt *Then, SourceLocation EL = SourceLocation(),
SourceLocation LPL, SourceLocation RPL, Stmt *Then,
SourceLocation EL = SourceLocation(),
Stmt *Else = nullptr);
/// Create an empty IfStmt optionally with storage for an else statement,
@ -2051,6 +2089,10 @@ class IfStmt final
return getElse()->getEndLoc();
return getThen()->getEndLoc();
}
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
// Iterators over subexpressions. The iterators will include iterating
// over the initialization expression referenced by the condition variable.
@ -2098,6 +2140,8 @@ class SwitchStmt final : public Stmt,
// Always present.
enum { InitOffset = 0, BodyOffsetFromCond = 1 };
enum { NumMandatoryStmtPtr = 2 };
SourceLocation LParenLoc;
SourceLocation RParenLoc;
unsigned numTrailingObjects(OverloadToken<Stmt *>) const {
return NumMandatoryStmtPtr + hasInitStorage() + hasVarStorage();
@ -2111,7 +2155,8 @@ class SwitchStmt final : public Stmt,
unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; }
/// Build a switch statement.
SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond);
SwitchStmt(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond,
SourceLocation LParenLoc, SourceLocation RParenLoc);
/// Build a empty switch statement.
explicit SwitchStmt(EmptyShell Empty, bool HasInit, bool HasVar);
@ -2119,7 +2164,8 @@ class SwitchStmt final : public Stmt,
public:
/// Create a switch statement.
static SwitchStmt *Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var,
Expr *Cond);
Expr *Cond, SourceLocation LParenLoc,
SourceLocation RParenLoc);
/// Create an empty switch statement optionally with storage for
/// an init expression and a condition variable.
@ -2207,6 +2253,10 @@ class SwitchStmt final : public Stmt,
SourceLocation getSwitchLoc() const { return SwitchStmtBits.SwitchLoc; }
void setSwitchLoc(SourceLocation L) { SwitchStmtBits.SwitchLoc = L; }
SourceLocation getLParenLoc() const { return LParenLoc; }
void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
void setBody(Stmt *S, SourceLocation SL) {
setBody(S);

View File

@ -104,12 +104,13 @@ class StmtIteratorImpl : public StmtIteratorBase,
return tmp;
}
bool operator==(const DERIVED& RHS) const {
return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr;
friend bool operator==(const DERIVED &LHS, const DERIVED &RHS) {
return LHS.stmt == RHS.stmt && LHS.DGI == RHS.DGI &&
LHS.RawVAPtr == RHS.RawVAPtr;
}
bool operator!=(const DERIVED& RHS) const {
return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr;
friend bool operator!=(const DERIVED &LHS, const DERIVED &RHS) {
return !(LHS == RHS);
}
REFERENCE operator*() const {

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,17 @@ namespace llvm {
class FoldingSetNodeID;
// Provide PointerLikeTypeTraits for clang::Expr*, this default one requires a
// full definition of Expr, but this file only sees a forward del because of
// the dependency.
template <> struct PointerLikeTypeTraits<clang::Expr *> {
static inline void *getAsVoidPointer(clang::Expr *P) { return P; }
static inline clang::Expr *getFromVoidPointer(void *P) {
return static_cast<clang::Expr *>(P);
}
static constexpr int NumLowBitsAvailable = 2;
};
} // namespace llvm
namespace clang {
@ -393,56 +404,51 @@ class TemplateArgument {
/// Location information for a TemplateArgument.
struct TemplateArgumentLocInfo {
private:
struct T {
struct TemplateTemplateArgLocInfo {
// FIXME: We'd like to just use the qualifier in the TemplateName,
// but template arguments get canonicalized too quickly.
NestedNameSpecifier *Qualifier;
void *QualifierLocData;
unsigned TemplateNameLoc;
unsigned EllipsisLoc;
SourceLocation TemplateNameLoc;
SourceLocation EllipsisLoc;
};
union {
struct T Template;
Expr *Expression;
TypeSourceInfo *Declarator;
};
llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
Pointer;
TemplateTemplateArgLocInfo *getTemplate() const {
return Pointer.get<TemplateTemplateArgLocInfo *>();
}
public:
constexpr TemplateArgumentLocInfo() : Template({nullptr, nullptr, 0, 0}) {}
TemplateArgumentLocInfo() {}
TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
TemplateArgumentLocInfo(TypeSourceInfo *TInfo) : Declarator(TInfo) {}
TemplateArgumentLocInfo(Expr *E) : Expression(E) {}
TemplateArgumentLocInfo(NestedNameSpecifierLoc QualifierLoc,
TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
// Ctx is used for allocation -- this case is unusually large and also rare,
// so we store the payload out-of-line.
TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc) {
Template.Qualifier = QualifierLoc.getNestedNameSpecifier();
Template.QualifierLocData = QualifierLoc.getOpaqueData();
Template.TemplateNameLoc = TemplateNameLoc.getRawEncoding();
Template.EllipsisLoc = EllipsisLoc.getRawEncoding();
}
SourceLocation EllipsisLoc);
TypeSourceInfo *getAsTypeSourceInfo() const {
return Declarator;
return Pointer.get<TypeSourceInfo *>();
}
Expr *getAsExpr() const {
return Expression;
}
Expr *getAsExpr() const { return Pointer.get<Expr *>(); }
NestedNameSpecifierLoc getTemplateQualifierLoc() const {
return NestedNameSpecifierLoc(Template.Qualifier,
Template.QualifierLocData);
const auto *Template = getTemplate();
return NestedNameSpecifierLoc(Template->Qualifier,
Template->QualifierLocData);
}
SourceLocation getTemplateNameLoc() const {
return SourceLocation::getFromRawEncoding(Template.TemplateNameLoc);
return getTemplate()->TemplateNameLoc;
}
SourceLocation getTemplateEllipsisLoc() const {
return SourceLocation::getFromRawEncoding(Template.EllipsisLoc);
return getTemplate()->EllipsisLoc;
}
};
@ -453,7 +459,7 @@ class TemplateArgumentLoc {
TemplateArgumentLocInfo LocInfo;
public:
constexpr TemplateArgumentLoc() {}
TemplateArgumentLoc() {}
TemplateArgumentLoc(const TemplateArgument &Argument,
TemplateArgumentLocInfo Opaque)
@ -475,12 +481,12 @@ class TemplateArgumentLoc {
Argument.getKind() == TemplateArgument::Expression);
}
TemplateArgumentLoc(const TemplateArgument &Argument,
TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc = SourceLocation())
: Argument(Argument),
LocInfo(QualifierLoc, TemplateNameLoc, EllipsisLoc) {
LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
assert(Argument.getKind() == TemplateArgument::Template ||
Argument.getKind() == TemplateArgument::TemplateExpansion);
}
@ -681,8 +687,8 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo {
TemplateArgumentListInfo &List) const;
};
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const TemplateArgument &Arg);
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const TemplateArgument &Arg);
inline TemplateSpecializationType::iterator
TemplateSpecializationType::end() const {

View File

@ -342,10 +342,8 @@ class TemplateName {
/// Insertion operator for diagnostics. This allows sending TemplateName's
/// into a diagnostic with <<.
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
TemplateName N);
const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
TemplateName N);
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
TemplateName N);
/// A structure for storing the information associated with a
/// substituted template template parameter.

View File

@ -155,6 +155,7 @@ class TextNodeDumper
const comments::CommandTraits *Traits = nullptr;
const char *getCommandName(unsigned CommandID);
void printFPOptions(FPOptionsOverride FPO);
void dumpAPValueChildren(const APValue &Value, QualType Ty,
const APValue &(*IdxToChildFun)(const APValue &,
@ -269,6 +270,7 @@ class TextNodeDumper
void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
void VisitCXXThisExpr(const CXXThisExpr *Node);
void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
void VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node);
void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
void VisitCXXConstructExpr(const CXXConstructExpr *Node);
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
@ -294,6 +296,7 @@ class TextNodeDumper
void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
void VisitOMPIteratorExpr(const OMPIteratorExpr *Node);
void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *Node);
void VisitRValueReferenceType(const ReferenceType *T);
void VisitArrayType(const ArrayType *T);

View File

@ -61,6 +61,7 @@ class ExtQuals;
class QualType;
class ConceptDecl;
class TagDecl;
class TemplateParameterList;
class Type;
enum {
@ -480,6 +481,11 @@ class Qualifiers {
// Otherwise in OpenCLC v2.0 s6.5.5: every address space except
// for __constant can be used as __generic.
(A == LangAS::opencl_generic && B != LangAS::opencl_constant) ||
// We also define global_device and global_host address spaces,
// to distinguish global pointers allocated on host from pointers
// allocated on device, which are a subset of __global.
(A == LangAS::opencl_global && (B == LangAS::opencl_global_device ||
B == LangAS::opencl_global_host)) ||
// Consider pointer size address spaces to be equivalent to default.
((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
(isPtrSizeAddressSpace(B) || B == LangAS::Default));
@ -1675,19 +1681,6 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
uint32_t NumElements;
};
class ConstantMatrixTypeBitfields {
friend class ConstantMatrixType;
unsigned : NumTypeBits;
/// Number of rows and columns. Using 20 bits allows supporting very large
/// matrixes, while keeping 24 bits to accommodate NumTypeBits.
unsigned NumRows : 20;
unsigned NumColumns : 20;
static constexpr uint32_t MaxElementsPerDimension = (1 << 20) - 1;
};
class AttributedTypeBitfields {
friend class AttributedType;
@ -1797,7 +1790,6 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
TypeWithKeywordBitfields TypeWithKeywordBits;
ElaboratedTypeBitfields ElaboratedTypeBits;
VectorTypeBitfields VectorTypeBits;
ConstantMatrixTypeBitfields ConstantMatrixTypeBits;
SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
DependentTemplateSpecializationTypeBitfields
@ -1853,6 +1845,10 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
Type(TypeClass tc, QualType canon, TypeDependence Dependence)
: ExtQualsTypeCommonBase(this,
canon.isNull() ? QualType(this_(), 0) : canon) {
static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase),
"changing bitfields changed sizeof(Type)!");
static_assert(alignof(decltype(*this)) % sizeof(void *) == 0,
"Insufficient alignment!");
TypeBits.TC = tc;
TypeBits.Dependence = static_cast<unsigned>(Dependence);
TypeBits.CacheValid = false;
@ -1925,6 +1921,16 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
bool isSizelessType() const;
bool isSizelessBuiltinType() const;
/// Determines if this is a sizeless type supported by the
/// 'arm_sve_vector_bits' type attribute, which can be applied to a single
/// SVE vector or predicate, excluding tuple types such as svint32x4_t.
bool isVLSTBuiltinType() const;
/// Returns the representative type for the element of an SVE builtin type.
/// This is used to represent fixed-length SVE vectors created with the
/// 'arm_sve_vector_bits' type attribute as VectorType.
QualType getSveEltType(const ASTContext &Ctx) const;
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
/// object types, function types, and incomplete types.
@ -1956,6 +1962,9 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
/// (C++11 [basic.types]p10)
bool isLiteralType(const ASTContext &Ctx) const;
/// Determine if this type is a structural type, per C++20 [temp.param]p7.
bool isStructuralType() const;
/// Test if this type is a standard-layout type.
/// (C++0x [basic.type]p9)
bool isStandardLayoutType() const;
@ -2118,6 +2127,7 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
bool isAtomicType() const; // C11 _Atomic()
bool isUndeducedAutoType() const; // C++11 auto or
// C++14 decltype(auto)
bool isTypedefNameType() const; // typedef or alias template
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
bool is##Id##Type() const;
@ -2513,6 +2523,9 @@ class BuiltinType : public Type {
// SVE Types
#define SVE_TYPE(Name, Id, SingletonId) Id,
#include "clang/Basic/AArch64SVEACLETypes.def"
// PPC MMA Types
#define PPC_VECTOR_TYPE(Name, Id, Size) Id,
#include "clang/Basic/PPCTypes.def"
// All other builtin types
#define BUILTIN_TYPE(Id, SingletonId) Id,
#define LAST_BUILTIN_TYPE(Id) LastKind = Id
@ -3250,7 +3263,13 @@ class VectorType : public Type, public llvm::FoldingSetNode {
NeonVector,
/// is ARM Neon polynomial vector
NeonPolyVector
NeonPolyVector,
/// is AArch64 SVE fixed-length data vector
SveFixedLengthDataVector,
/// is AArch64 SVE fixed-length predicate vector
SveFixedLengthPredicateVector
};
protected:
@ -3456,8 +3475,15 @@ class ConstantMatrixType final : public MatrixType {
friend class ASTContext;
/// The element type of the matrix.
// FIXME: Appears to be unused? There is also MatrixType::ElementType...
QualType ElementType;
/// Number of rows and columns.
unsigned NumRows;
unsigned NumColumns;
static constexpr unsigned MaxElementsPerDimension = (1 << 20) - 1;
ConstantMatrixType(QualType MatrixElementType, unsigned NRows,
unsigned NColumns, QualType CanonElementType);
@ -3466,25 +3492,24 @@ class ConstantMatrixType final : public MatrixType {
public:
/// Returns the number of rows in the matrix.
unsigned getNumRows() const { return ConstantMatrixTypeBits.NumRows; }
unsigned getNumRows() const { return NumRows; }
/// Returns the number of columns in the matrix.
unsigned getNumColumns() const { return ConstantMatrixTypeBits.NumColumns; }
unsigned getNumColumns() const { return NumColumns; }
/// Returns the number of elements required to embed the matrix into a vector.
unsigned getNumElementsFlattened() const {
return ConstantMatrixTypeBits.NumRows * ConstantMatrixTypeBits.NumColumns;
return getNumRows() * getNumColumns();
}
/// Returns true if \p NumElements is a valid matrix dimension.
static bool isDimensionValid(uint64_t NumElements) {
return NumElements > 0 &&
NumElements <= ConstantMatrixTypeBitfields::MaxElementsPerDimension;
static constexpr bool isDimensionValid(size_t NumElements) {
return NumElements > 0 && NumElements <= MaxElementsPerDimension;
}
/// Returns the maximum number of elements per dimension.
static unsigned getMaxElementsPerDimension() {
return ConstantMatrixTypeBitfields::MaxElementsPerDimension;
static constexpr unsigned getMaxElementsPerDimension() {
return MaxElementsPerDimension;
}
void Profile(llvm::FoldingSetNodeID &ID) {
@ -4372,10 +4397,11 @@ class UnresolvedUsingType : public Type {
class TypedefType : public Type {
TypedefNameDecl *Decl;
protected:
private:
friend class ASTContext; // ASTContext creates these.
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can);
TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying,
QualType can);
public:
TypedefNameDecl *getDecl() const { return Decl; }
@ -4726,6 +4752,9 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
case NullabilityKind::Nullable:
return attr::TypeNullable;
case NullabilityKind::NullableResult:
return attr::TypeNullableResult;
case NullabilityKind::Unspecified:
return attr::TypeNullUnspecified;
}
@ -5118,11 +5147,24 @@ class alignas(8) TemplateSpecializationType
public:
/// Determine whether any of the given template arguments are dependent.
static bool anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
bool &InstantiationDependent);
static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &,
bool &InstantiationDependent);
///
/// The converted arguments should be supplied when known; whether an
/// argument is dependent can depend on the conversions performed on it
/// (for example, a 'const int' passed as a template argument might be
/// dependent if the parameter is a reference but non-dependent if the
/// parameter is an int).
///
/// Note that the \p Args parameter is unused: this is intentional, to remind
/// the caller that they need to pass in the converted arguments, not the
/// specified arguments.
static bool
anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
ArrayRef<TemplateArgument> Converted);
static bool
anyDependentTemplateArguments(const TemplateArgumentListInfo &,
ArrayRef<TemplateArgument> Converted);
static bool anyInstantiationDependentTemplateArguments(
ArrayRef<TemplateArgumentLoc> Args);
/// True if this template specialization type matches a current
/// instantiation in the context in which it is found.
@ -5207,15 +5249,18 @@ class alignas(8) TemplateSpecializationType
/// enclosing the template arguments.
void printTemplateArgumentList(raw_ostream &OS,
ArrayRef<TemplateArgument> Args,
const PrintingPolicy &Policy);
const PrintingPolicy &Policy,
const TemplateParameterList *TPL = nullptr);
void printTemplateArgumentList(raw_ostream &OS,
ArrayRef<TemplateArgumentLoc> Args,
const PrintingPolicy &Policy);
const PrintingPolicy &Policy,
const TemplateParameterList *TPL = nullptr);
void printTemplateArgumentList(raw_ostream &OS,
const TemplateArgumentListInfo &Args,
const PrintingPolicy &Policy);
const PrintingPolicy &Policy,
const TemplateParameterList *TPL = nullptr);
/// The injected class name of a C++ class template or class
/// template partial specialization. Used to record that a type was
@ -5401,7 +5446,9 @@ class ElaboratedType final
ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
: TypeWithKeyword(Keyword, Elaborated, CanonType,
NamedType->getDependence()),
NamedType->getDependence() |
(NNS ? toTypeDependence(NNS->getDependence())
: TypeDependence::None)),
NNS(NNS), NamedType(NamedType) {
ElaboratedTypeBits.HasOwnedTagDecl = false;
if (OwnedTagDecl) {
@ -7056,6 +7103,15 @@ inline bool Type::isOverloadableType() const {
return isDependentType() || isRecordType() || isEnumeralType();
}
/// Determines whether this type is written as a typedef-name.
inline bool Type::isTypedefNameType() const {
if (getAs<TypedefType>())
return true;
if (auto *TST = getAs<TemplateSpecializationType>())
return TST->isTypeAlias();
return false;
}
/// Determines whether this type can decay to a pointer type.
inline bool Type::canDecayToPointerType() const {
return isFunctionType() || isArrayType();
@ -7085,55 +7141,28 @@ inline const Type *Type::getPointeeOrArrayElementType() const {
return type->getBaseElementTypeUnsafe();
return type;
}
/// Insertion operator for diagnostics. This allows sending address spaces into
/// a diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
LangAS AS) {
DB.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
DiagnosticsEngine::ArgumentKind::ak_addrspace);
return DB;
}
/// Insertion operator for partial diagnostics. This allows sending adress
/// spaces into a diagnostic with <<.
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
LangAS AS) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
LangAS AS) {
PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
DiagnosticsEngine::ArgumentKind::ak_addrspace);
return PD;
}
/// Insertion operator for diagnostics. This allows sending Qualifiers into a
/// diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
Qualifiers Q) {
DB.AddTaggedVal(Q.getAsOpaqueValue(),
DiagnosticsEngine::ArgumentKind::ak_qual);
return DB;
}
/// Insertion operator for partial diagnostics. This allows sending Qualifiers
/// into a diagnostic with <<.
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
Qualifiers Q) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
Qualifiers Q) {
PD.AddTaggedVal(Q.getAsOpaqueValue(),
DiagnosticsEngine::ArgumentKind::ak_qual);
return PD;
}
/// Insertion operator for diagnostics. This allows sending QualType's into a
/// diagnostic with <<.
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
QualType T) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
DiagnosticsEngine::ak_qualtype);
return DB;
}
/// Insertion operator for partial diagnostics. This allows sending QualType's
/// into a diagnostic with <<.
inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
QualType T) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
QualType T) {
PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
DiagnosticsEngine::ak_qualtype);
return PD;

View File

@ -603,32 +603,32 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
if (needsExtraLocalData())
return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
else
return TSS_unspecified;
return TypeSpecifierSign::Unspecified;
}
bool hasWrittenSignSpec() const {
return getWrittenSignSpec() != TSS_unspecified;
return getWrittenSignSpec() != TypeSpecifierSign::Unspecified;
}
void setWrittenSignSpec(TypeSpecifierSign written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Sign = written;
getWrittenBuiltinSpecs().Sign = static_cast<unsigned>(written);
}
TypeSpecifierWidth getWrittenWidthSpec() const {
if (needsExtraLocalData())
return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
else
return TSW_unspecified;
return TypeSpecifierWidth::Unspecified;
}
bool hasWrittenWidthSpec() const {
return getWrittenWidthSpec() != TSW_unspecified;
return getWrittenWidthSpec() != TypeSpecifierWidth::Unspecified;
}
void setWrittenWidthSpec(TypeSpecifierWidth written) {
if (needsExtraLocalData())
getWrittenBuiltinSpecs().Width = written;
getWrittenBuiltinSpecs().Width = static_cast<unsigned>(written);
}
TypeSpecifierType getWrittenTypeSpec() const;
@ -658,8 +658,8 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
setBuiltinLoc(Loc);
if (needsExtraLocalData()) {
WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
wbs.Sign = TSS_unspecified;
wbs.Width = TSW_unspecified;
wbs.Sign = static_cast<unsigned>(TypeSpecifierSign::Unspecified);
wbs.Width = static_cast<unsigned>(TypeSpecifierWidth::Unspecified);
wbs.Type = TST_unspecified;
wbs.ModeAttr = false;
}
@ -1749,30 +1749,79 @@ class DependentAddressSpaceTypeLoc
// FIXME: size expression and attribute locations (or keyword if we
// ever fully support altivec syntax).
class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
VectorTypeLoc,
VectorType> {
struct VectorTypeLocInfo {
SourceLocation NameLoc;
};
class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc,
VectorType, VectorTypeLocInfo> {
public:
SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
};
// FIXME: size expression and attribute locations (or keyword if we
// ever fully support altivec syntax).
class DependentVectorTypeLoc
: public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DependentVectorTypeLoc,
DependentVectorType> {};
: public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc,
DependentVectorType, VectorTypeLocInfo> {
public:
SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
};
// FIXME: size expression and attribute locations.
class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
ExtVectorTypeLoc,
ExtVectorType> {
};
class ExtVectorTypeLoc
: public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc,
ExtVectorType> {};
// FIXME: attribute locations.
// For some reason, this isn't a subtype of VectorType.
class DependentSizedExtVectorTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
DependentSizedExtVectorTypeLoc,
DependentSizedExtVectorType> {
class DependentSizedExtVectorTypeLoc
: public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc,
DependentSizedExtVectorType, VectorTypeLocInfo> {
public:
SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
SourceRange getLocalSourceRange() const {
return SourceRange(getNameLoc(), getNameLoc());
}
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setNameLoc(Loc);
}
TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
};
struct MatrixTypeLocInfo {

View File

@ -484,8 +484,12 @@ let Class = TagType in {
let Read = [{ node->isDependentType() }];
}
def : Property<"declaration", DeclRef> {
// Serializing a reference to the canonical declaration is apparently
// necessary to make module-merging work.
// We don't know which declaration was originally referenced here, and we
// cannot reference a declaration that follows the use (because that can
// introduce deserialization cycles), so conservatively generate a
// reference to the first declaration.
// FIXME: If this is a reference to a class template specialization, that
// can still introduce a deserialization cycle.
let Read = [{ node->getDecl()->getCanonicalDecl() }];
}
}
@ -761,6 +765,10 @@ let Class = BuiltinType in {
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/Basic/AArch64SVEACLETypes.def"
#define PPC_VECTOR_TYPE(NAME, ID, SIZE) \
case BuiltinType::ID: return ctx.ID##Ty;
#include "clang/Basic/PPCTypes.def"
#define BUILTIN_TYPE(ID, SINGLETON_ID) \
case BuiltinType::ID: return ctx.SINGLETON_ID;
#include "clang/AST/BuiltinTypes.def"

View File

@ -159,6 +159,8 @@ class MatchFinder {
MatchCallback *Action);
void addMatcher(const CXXCtorInitializerMatcher &NodeMatch,
MatchCallback *Action);
void addMatcher(const TemplateArgumentLocMatcher &NodeMatch,
MatchCallback *Action);
/// @}
/// Adds a matcher to execute when running over the AST.
@ -209,6 +211,8 @@ class MatchFinder {
NestedNameSpecifierLoc;
std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc;
std::vector<std::pair<CXXCtorInitializerMatcher, MatchCallback *>> CtorInit;
std::vector<std::pair<TemplateArgumentLocMatcher, MatchCallback *>>
TemplateArgumentLoc;
/// All the callbacks in one container to simplify iteration.
llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks;
};

View File

@ -145,6 +145,8 @@ using TypeLocMatcher = internal::Matcher<TypeLoc>;
using NestedNameSpecifierMatcher = internal::Matcher<NestedNameSpecifier>;
using NestedNameSpecifierLocMatcher = internal::Matcher<NestedNameSpecifierLoc>;
using CXXCtorInitializerMatcher = internal::Matcher<CXXCtorInitializer>;
using TemplateArgumentMatcher = internal::Matcher<TemplateArgument>;
using TemplateArgumentLocMatcher = internal::Matcher<TemplateArgumentLoc>;
/// @}
/// Matches any node.
@ -306,10 +308,9 @@ AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching,
/// Does not match if only part of the statement is expanded from that macro or
/// if different parts of the the statement are expanded from different
/// appearances of the macro.
///
/// FIXME: Change to be a polymorphic matcher that works on any syntactic
/// node. There's nothing `Stmt`-specific about it.
AST_MATCHER_P(Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) {
AST_POLYMORPHIC_MATCHER_P(isExpandedFromMacro,
AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc),
std::string, MacroName) {
// Verifies that the statement' beginning and ending are both expanded from
// the same instance of the given macro.
auto& Context = Finder->getASTContext();
@ -333,6 +334,19 @@ AST_MATCHER_P(Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) {
/// \endcode
extern const internal::VariadicAllOfMatcher<Decl> decl;
/// Matches decomposition-declarations.
///
/// Examples matches the declaration node with \c foo and \c bar, but not
/// \c number.
/// (matcher = declStmt(has(decompositionDecl())))
///
/// \code
/// int number = 42;
/// auto [foo, bar] = std::make_pair{42, 42};
/// \endcode
extern const internal::VariadicAllOfMatcher<DecompositionDecl>
decompositionDecl;
/// Matches a declaration of a linkage specification.
///
/// Given
@ -515,6 +529,18 @@ extern const internal::VariadicAllOfMatcher<CXXCtorInitializer>
/// matches 'int' in C<int>.
extern const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
/// Matches template arguments (with location info).
///
/// Given
/// \code
/// template <typename T> struct C {};
/// C<int> c;
/// \endcode
/// templateArgumentLoc()
/// matches 'int' in C<int>.
extern const internal::VariadicAllOfMatcher<TemplateArgumentLoc>
templateArgumentLoc;
/// Matches template name.
///
/// Given
@ -549,6 +575,18 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl,
extern const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
templateTypeParmDecl;
/// Matches template template parameter declarations.
///
/// Given
/// \code
/// template <template <typename> class Z, int N> struct C {};
/// \endcode
/// templateTypeParmDecl()
/// matches 'Z', but not 'N'.
extern const internal::VariadicDynCastAllOfMatcher<Decl,
TemplateTemplateParmDecl>
templateTemplateParmDecl;
/// Matches public C++ declarations and C++ base specifers that specify public
/// inheritance.
///
@ -730,7 +768,7 @@ AST_POLYMORPHIC_MATCHER_P(
ArrayRef<TemplateArgument> List =
internal::getTemplateSpecializationArgs(Node);
return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
Builder);
Builder) != List.end();
}
/// Causes all nested matchers to be matched with the specified traversal kind.
@ -744,7 +782,7 @@ AST_POLYMORPHIC_MATCHER_P(
/// \endcode
/// The matcher
/// \code
/// traverse(TK_IgnoreImplicitCastsAndParentheses,
/// traverse(TK_IgnoreUnlessSpelledInSource,
/// varDecl(hasInitializer(floatLiteral().bind("init")))
/// )
/// \endcode
@ -809,6 +847,12 @@ traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam2<
TK, InnerMatcher);
}
template <typename... T>
internal::Matcher<typename internal::GetClade<T...>::Type>
traverse(TraversalKind TK, const internal::MapAnyOfHelper<T...> &InnerMatcher) {
return traverse(TK, InnerMatcher.with());
}
/// Matches expressions that match InnerMatcher after any implicit AST
/// nodes are stripped off.
///
@ -1124,7 +1168,7 @@ AST_MATCHER(TemplateArgument, isIntegral) {
return Node.getKind() == TemplateArgument::Integral;
}
/// Matches a TemplateArgument that referes to an integral type.
/// Matches a TemplateArgument that refers to an integral type.
///
/// Given
/// \code
@ -1927,9 +1971,32 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
/// ostream &o; int b = 1, c = 1;
/// o << b << c;
/// \endcode
/// See also the binaryOperation() matcher for more-general matching of binary
/// uses of this AST node.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
cxxOperatorCallExpr;
/// Matches rewritten binary operators
///
/// Example matches use of "<":
/// \code
/// #include <compare>
/// struct HasSpaceshipMem {
/// int a;
/// constexpr auto operator<=>(const HasSpaceshipMem&) const = default;
/// };
/// void compare() {
/// HasSpaceshipMem hs1, hs2;
/// if (hs1 < hs2)
/// return;
/// }
/// \endcode
/// See also the binaryOperation() matcher for more-general matching
/// of this AST node.
extern const internal::VariadicDynCastAllOfMatcher<Stmt,
CXXRewrittenBinaryOperator>
cxxRewrittenBinaryOperator;
/// Matches expressions.
///
/// Example matches x()
@ -2324,6 +2391,10 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr>
gnuNullExpr;
/// Matches C11 _Generic expression.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, GenericSelectionExpr>
genericSelectionExpr;
/// Matches atomic builtins.
/// Example matches __atomic_load_n(ptr, 1)
/// \code
@ -2345,6 +2416,7 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
/// \code
/// !(a || b)
/// \endcode
/// See also the binaryOperation() matcher for more-general matching.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
binaryOperator;
@ -2651,6 +2723,112 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt,
UnaryExprOrTypeTraitExpr>
unaryExprOrTypeTraitExpr;
/// Matches any of the \p NodeMatchers with InnerMatchers nested within
///
/// Given
/// \code
/// if (true);
/// for (; true; );
/// \endcode
/// with the matcher
/// \code
/// mapAnyOf(ifStmt, forStmt).with(
/// hasCondition(cxxBoolLiteralExpr(equals(true)))
/// ).bind("trueCond")
/// \endcode
/// matches the \c if and the \c for. It is equivalent to:
/// \code
/// auto trueCond = hasCondition(cxxBoolLiteralExpr(equals(true)));
/// anyOf(
/// ifStmt(trueCond).bind("trueCond"),
/// forStmt(trueCond).bind("trueCond")
/// );
/// \endcode
///
/// The with() chain-call accepts zero or more matchers which are combined
/// as-if with allOf() in each of the node matchers.
/// Usable as: Any Matcher
template <typename T, typename... U>
auto mapAnyOf(internal::VariadicDynCastAllOfMatcher<T, U> const &...) {
return internal::MapAnyOfHelper<U...>();
}
/// Matches nodes which can be used with binary operators.
///
/// The code
/// \code
/// var1 != var2;
/// \endcode
/// might be represented in the clang AST as a binaryOperator, a
/// cxxOperatorCallExpr or a cxxRewrittenBinaryOperator, depending on
///
/// * whether the types of var1 and var2 are fundamental (binaryOperator) or at
/// least one is a class type (cxxOperatorCallExpr)
/// * whether the code appears in a template declaration, if at least one of the
/// vars is a dependent-type (binaryOperator)
/// * whether the code relies on a rewritten binary operator, such as a
/// spaceship operator or an inverted equality operator
/// (cxxRewrittenBinaryOperator)
///
/// This matcher elides details in places where the matchers for the nodes are
/// compatible.
///
/// Given
/// \code
/// binaryOperation(
/// hasOperatorName("!="),
/// hasLHS(expr().bind("lhs")),
/// hasRHS(expr().bind("rhs"))
/// )
/// \endcode
/// matches each use of "!=" in:
/// \code
/// struct S{
/// bool operator!=(const S&) const;
/// };
///
/// void foo()
/// {
/// 1 != 2;
/// S() != S();
/// }
///
/// template<typename T>
/// void templ()
/// {
/// 1 != 2;
/// T() != S();
/// }
/// struct HasOpEq
/// {
/// bool operator==(const HasOpEq &) const;
/// };
///
/// void inverse()
/// {
/// HasOpEq s1;
/// HasOpEq s2;
/// if (s1 != s2)
/// return;
/// }
///
/// struct HasSpaceship
/// {
/// bool operator<=>(const HasOpEq &) const;
/// };
///
/// void use_spaceship()
/// {
/// HasSpaceship s1;
/// HasSpaceship s2;
/// if (s1 != s2)
/// return;
/// }
/// \endcode
extern const internal::MapAnyOfMatcher<BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator>
binaryOperation;
/// Matches unary expressions that have a specific type of argument.
///
/// Given
@ -2787,7 +2965,7 @@ hasOverloadedOperatorName(StringRef Name) {
/// Matches overloaded operator names specified in strings without the
/// "operator" prefix: e.g. "<<".
///
/// hasAnyOverloadesOperatorName("+", "-")
/// hasAnyOverloadedOperatorName("+", "-")
/// Is equivalent to
/// anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-"))
extern const internal::VariadicFunction<
@ -2797,6 +2975,80 @@ extern const internal::VariadicFunction<
StringRef, internal::hasAnyOverloadedOperatorNameFunc>
hasAnyOverloadedOperatorName;
/// Matches template-dependent, but known, member names.
///
/// In template declarations, dependent members are not resolved and so can
/// not be matched to particular named declarations.
///
/// This matcher allows to match on the known name of members.
///
/// Given
/// \code
/// template <typename T>
/// struct S {
/// void mem();
/// };
/// template <typename T>
/// void x() {
/// S<T> s;
/// s.mem();
/// }
/// \endcode
/// \c cxxDependentScopeMemberExpr(hasMemberName("mem")) matches `s.mem()`
AST_MATCHER_P(CXXDependentScopeMemberExpr, hasMemberName, std::string, N) {
return Node.getMember().getAsString() == N;
}
/// Matches template-dependent, but known, member names against an already-bound
/// node
///
/// In template declarations, dependent members are not resolved and so can
/// not be matched to particular named declarations.
///
/// This matcher allows to match on the name of already-bound VarDecl, FieldDecl
/// and CXXMethodDecl nodes.
///
/// Given
/// \code
/// template <typename T>
/// struct S {
/// void mem();
/// };
/// template <typename T>
/// void x() {
/// S<T> s;
/// s.mem();
/// }
/// \endcode
/// The matcher
/// @code
/// \c cxxDependentScopeMemberExpr(
/// hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
/// hasDeclaration(classTemplateDecl(has(cxxRecordDecl(has(
/// cxxMethodDecl(hasName("mem")).bind("templMem")
/// )))))
/// )))),
/// memberHasSameNameAsBoundNode("templMem")
/// )
/// @endcode
/// first matches and binds the @c mem member of the @c S template, then
/// compares its name to the usage in @c s.mem() in the @c x function template
AST_MATCHER_P(CXXDependentScopeMemberExpr, memberHasSameNameAsBoundNode,
std::string, BindingID) {
auto MemberName = Node.getMember().getAsString();
return Builder->removeBindings(
[this, MemberName](const BoundNodesMap &Nodes) {
const auto &BN = Nodes.getNode(this->BindingID);
if (const auto *ND = BN.get<NamedDecl>()) {
if (!isa<FieldDecl, CXXMethodDecl, VarDecl>(ND))
return true;
return ND->getName() != MemberName;
}
return true;
});
}
/// Matches C++ classes that are directly or indirectly derived from a class
/// matching \c Base, or Objective-C classes that directly or indirectly
/// subclass a class matching \c Base.
@ -2994,8 +3246,16 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
/// \c A but not \c B.
AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>,
InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
Node.method_end(), Finder, Builder);
BoundNodesTreeBuilder Result(*Builder);
auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.method_begin(),
Node.method_end(), Finder, &Result);
if (MatchIt == Node.method_end())
return false;
if (Finder->isTraversalIgnoringImplicitNodes() && (*MatchIt)->isImplicit())
return false;
*Builder = std::move(Result);
return true;
}
/// Matches the generated class of lambda expressions.
@ -3771,7 +4031,8 @@ AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
AST_MATCHER_P(OverloadExpr, hasAnyDeclaration, internal::Matcher<Decl>,
InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.decls_begin(),
Node.decls_end(), Finder, Builder);
Node.decls_end(), Finder,
Builder) != Node.decls_end();
}
/// Matches the Decl of a DeclStmt which has a single declaration.
@ -3926,11 +4187,19 @@ AST_MATCHER(VarDecl, isExceptionVariable) {
/// f(0, 0);
/// \endcode
AST_POLYMORPHIC_MATCHER_P(argumentCountIs,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
CXXConstructExpr,
ObjCMessageExpr),
AST_POLYMORPHIC_SUPPORTED_TYPES(
CallExpr, CXXConstructExpr,
CXXUnresolvedConstructExpr, ObjCMessageExpr),
unsigned, N) {
return Node.getNumArgs() == N;
unsigned NumArgs = Node.getNumArgs();
if (!Finder->isTraversalIgnoringImplicitNodes())
return NumArgs == N;
while (NumArgs) {
if (!isa<CXXDefaultArgExpr>(Node.getArg(NumArgs - 1)))
break;
--NumArgs;
}
return NumArgs == N;
}
/// Matches the n'th argument of a call expression or a constructor
@ -3942,13 +4211,16 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs,
/// void x(int) { int y; x(y); }
/// \endcode
AST_POLYMORPHIC_MATCHER_P2(hasArgument,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
CXXConstructExpr,
ObjCMessageExpr),
AST_POLYMORPHIC_SUPPORTED_TYPES(
CallExpr, CXXConstructExpr,
CXXUnresolvedConstructExpr, ObjCMessageExpr),
unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
return (N < Node.getNumArgs() &&
InnerMatcher.matches(
*Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
if (N >= Node.getNumArgs())
return false;
const Expr *Arg = Node.getArg(N);
if (Finder->isTraversalIgnoringImplicitNodes() && isa<CXXDefaultArgExpr>(Arg))
return false;
return InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, Builder);
}
/// Matches the n'th item of an initializer list expression.
@ -4040,8 +4312,11 @@ AST_MATCHER(CXXCatchStmt, isCatchAll) {
/// record matches Foo, hasAnyConstructorInitializer matches foo_(1)
AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
Node.init_end(), Finder, Builder);
auto MatchIt = matchesFirstInPointerRange(InnerMatcher, Node.init_begin(),
Node.init_end(), Finder, Builder);
if (MatchIt == Node.init_end())
return false;
return (*MatchIt)->isWritten() || !Finder->isTraversalIgnoringImplicitNodes();
}
/// Matches the field declaration of a constructor initializer.
@ -4166,6 +4441,9 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
CXXUnresolvedConstructExpr, ObjCMessageExpr),
internal::Matcher<Expr>, InnerMatcher) {
for (const Expr *Arg : Node.arguments()) {
if (Finder->isTraversalIgnoringImplicitNodes() &&
isa<CXXDefaultArgExpr>(Arg))
break;
BoundNodesTreeBuilder Result(*Builder);
if (InnerMatcher.matches(*Arg, Finder, &Result)) {
*Builder = std::move(Result);
@ -4324,6 +4602,103 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
return Matched;
}
/// Matches all arguments and their respective types for a \c CallExpr or
/// \c CXXConstructExpr. It is very similar to \c forEachArgumentWithParam but
/// it works on calls through function pointers as well.
///
/// The difference is, that function pointers do not provide access to a
/// \c ParmVarDecl, but only the \c QualType for each argument.
///
/// Given
/// \code
/// void f(int i);
/// int y;
/// f(y);
/// void (*f_ptr)(int) = f;
/// f_ptr(y);
/// \endcode
/// callExpr(
/// forEachArgumentWithParamType(
/// declRefExpr(to(varDecl(hasName("y")))),
/// qualType(isInteger()).bind("type)
/// ))
/// matches f(y) and f_ptr(y)
/// with declRefExpr(...)
/// matching int y
/// and qualType(...)
/// matching int
AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
CXXConstructExpr),
internal::Matcher<Expr>, ArgMatcher,
internal::Matcher<QualType>, ParamMatcher) {
BoundNodesTreeBuilder Result;
// The first argument of an overloaded member operator is the implicit object
// 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;
const FunctionProtoType *FProto = nullptr;
if (const auto *Call = dyn_cast<CallExpr>(&Node)) {
if (const auto *Value =
dyn_cast_or_null<ValueDecl>(Call->getCalleeDecl())) {
QualType QT = Value->getType().getCanonicalType();
// This does not necessarily lead to a `FunctionProtoType`,
// e.g. K&R functions do not have a function prototype.
if (QT->isFunctionPointerType())
FProto = QT->getPointeeType()->getAs<FunctionProtoType>();
if (QT->isMemberFunctionPointerType()) {
const auto *MP = QT->getAs<MemberPointerType>();
assert(MP && "Must be member-pointer if its a memberfunctionpointer");
FProto = MP->getPointeeType()->getAs<FunctionProtoType>();
assert(FProto &&
"The call must have happened through a member function "
"pointer");
}
}
}
int ParamIndex = 0;
bool Matched = false;
for (; ArgIndex < Node.getNumArgs(); ++ArgIndex, ++ParamIndex) {
BoundNodesTreeBuilder ArgMatches(*Builder);
if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), Finder,
&ArgMatches)) {
BoundNodesTreeBuilder ParamMatches(ArgMatches);
// This test is cheaper compared to the big matcher in the next if.
// Therefore, please keep this order.
if (FProto) {
QualType ParamType = FProto->getParamType(ParamIndex);
if (ParamMatcher.matches(ParamType, Finder, &ParamMatches)) {
Result.addMatch(ParamMatches);
Matched = true;
continue;
}
}
if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
hasParameter(ParamIndex, hasType(ParamMatcher))))),
callExpr(callee(functionDecl(
hasParameter(ParamIndex, hasType(ParamMatcher)))))))
.matches(Node, Finder, &ParamMatches)) {
Result.addMatch(ParamMatches);
Matched = true;
continue;
}
}
}
*Builder = std::move(Result);
return Matched;
}
/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter
/// list. The parameter list could be that of either a block, function, or
/// objc-method.
@ -4390,7 +4765,8 @@ AST_POLYMORPHIC_MATCHER_P(hasAnyParameter,
internal::Matcher<ParmVarDecl>,
InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.param_begin(),
Node.param_end(), Finder, Builder);
Node.param_end(), Finder,
Builder) != Node.param_end();
}
/// Matches \c FunctionDecls and \c FunctionProtoTypes that have a
@ -4512,6 +4888,17 @@ AST_MATCHER(FunctionDecl, isDefaulted) {
return Node.isDefaulted();
}
/// Matches weak function declarations.
///
/// Given:
/// \code
/// void foo() __attribute__((__weakref__("__foo")));
/// void bar();
/// \endcode
/// functionDecl(isWeak())
/// matches the weak declaration "foo", but not "bar".
AST_MATCHER(FunctionDecl, isWeak) { return Node.isWeak(); }
/// Matches functions that have a dynamic exception specification.
///
/// Given:
@ -4744,7 +5131,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
}
/// Matches a 'for', 'while', 'do while' statement or a function
/// definition that has a given body.
/// definition that has a given body. Note that in case of functions
/// this matcher only matches the definition itself and not the other
/// declarations of the same function.
///
/// Given
/// \code
@ -4754,17 +5143,55 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase,
/// matches 'for (;;) {}'
/// with compoundStmt()
/// matching '{}'
///
/// Given
/// \code
/// void f();
/// void f() {}
/// \endcode
/// hasBody(functionDecl())
/// matches 'void f() {}'
/// with compoundStmt()
/// matching '{}'
/// but does not match 'void f();'
AST_POLYMORPHIC_MATCHER_P(hasBody,
AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt,
WhileStmt,
CXXForRangeStmt,
FunctionDecl),
internal::Matcher<Stmt>, InnerMatcher) {
if (Finder->isTraversalIgnoringImplicitNodes() && isDefaultedHelper(&Node))
return false;
const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node);
return (Statement != nullptr &&
InnerMatcher.matches(*Statement, Finder, Builder));
}
/// Matches a function declaration that has a given body present in the AST.
/// Note that this matcher matches all the declarations of a function whose
/// body is present in the AST.
///
/// Given
/// \code
/// void f();
/// void f() {}
/// void g();
/// \endcode
/// hasAnyBody(functionDecl())
/// matches both 'void f();'
/// and 'void f() {}'
/// with compoundStmt()
/// matching '{}'
/// but does not match 'void g();'
AST_MATCHER_P(FunctionDecl, hasAnyBody,
internal::Matcher<Stmt>, InnerMatcher) {
const Stmt *const Statement = Node.getBody();
return (Statement != nullptr &&
InnerMatcher.matches(*Statement, Finder, Builder));
}
/// Matches compound statements where at least one substatement matches
/// a given matcher. Also matches StmtExprs that have CompoundStmt as children.
///
@ -4782,7 +5209,8 @@ AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement,
internal::Matcher<Stmt>, InnerMatcher) {
const CompoundStmt *CS = CompoundStmtMatcher<NodeType>::get(Node);
return CS && matchesFirstInPointerRange(InnerMatcher, CS->body_begin(),
CS->body_end(), Finder, Builder);
CS->body_end(), Finder,
Builder) != CS->body_end();
}
/// Checks that a compound statement contains a specific number of
@ -4867,11 +5295,14 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(equals,
/// \code
/// !(a || b)
/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasOperatorName,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
UnaryOperator),
std::string, Name) {
return Name == Node.getOpcodeStr(Node.getOpcode());
AST_POLYMORPHIC_MATCHER_P(
hasOperatorName,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator, UnaryOperator),
std::string, Name) {
if (Optional<StringRef> OpName = internal::getOpName(Node))
return *OpName == Name;
return false;
}
/// Matches operator expressions (binary or unary) that have any of the
@ -4883,7 +5314,9 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName,
extern const internal::VariadicFunction<
internal::PolymorphicMatcherWithParam1<
internal::HasAnyOperatorNameMatcher, std::vector<std::string>,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, UnaryOperator)>,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator,
UnaryOperator)>,
StringRef, internal::hasAnyOperatorNameFunc>
hasAnyOperatorName;
@ -4901,9 +5334,10 @@ extern const internal::VariadicFunction<
/// struct S { S& operator=(const S&); };
/// void x() { S s1, s2; s1 = s2; }
/// \endcode
AST_POLYMORPHIC_MATCHER(isAssignmentOperator,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
CXXOperatorCallExpr)) {
AST_POLYMORPHIC_MATCHER(
isAssignmentOperator,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator)) {
return Node.isAssignmentOp();
}
@ -4921,9 +5355,10 @@ AST_POLYMORPHIC_MATCHER(isAssignmentOperator,
/// struct S { bool operator<(const S& other); };
/// void x(S s1, S s2) { bool b1 = s1 < s2; }
/// \endcode
AST_POLYMORPHIC_MATCHER(isComparisonOperator,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
CXXOperatorCallExpr)) {
AST_POLYMORPHIC_MATCHER(
isComparisonOperator,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator)) {
return Node.isComparisonOp();
}
@ -4934,10 +5369,11 @@ AST_POLYMORPHIC_MATCHER(isComparisonOperator,
/// a || b
/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasLHS,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
ArraySubscriptExpr),
AST_POLYMORPHIC_SUPPORTED_TYPES(
BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator, ArraySubscriptExpr),
internal::Matcher<Expr>, InnerMatcher) {
const Expr *LeftHandSide = Node.getLHS();
const Expr *LeftHandSide = internal::getLHS(Node);
return (LeftHandSide != nullptr &&
InnerMatcher.matches(*LeftHandSide, Finder, Builder));
}
@ -4949,19 +5385,25 @@ AST_POLYMORPHIC_MATCHER_P(hasLHS,
/// a || b
/// \endcode
AST_POLYMORPHIC_MATCHER_P(hasRHS,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator,
ArraySubscriptExpr),
AST_POLYMORPHIC_SUPPORTED_TYPES(
BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator, ArraySubscriptExpr),
internal::Matcher<Expr>, InnerMatcher) {
const Expr *RightHandSide = Node.getRHS();
const Expr *RightHandSide = internal::getRHS(Node);
return (RightHandSide != nullptr &&
InnerMatcher.matches(*RightHandSide, Finder, Builder));
}
/// Matches if either the left hand side or the right hand side of a
/// binary operator matches.
inline internal::Matcher<BinaryOperator> hasEitherOperand(
const internal::Matcher<Expr> &InnerMatcher) {
return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher));
AST_POLYMORPHIC_MATCHER_P(
hasEitherOperand,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator),
internal::Matcher<Expr>, InnerMatcher) {
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)))
.matches(Node, Finder, Builder);
}
/// Matches if both matchers match with opposite sides of the binary operator.
@ -4974,11 +5416,15 @@ inline internal::Matcher<BinaryOperator> hasEitherOperand(
/// 1 + 1 // No match
/// 2 + 2 // No match
/// \endcode
inline internal::Matcher<BinaryOperator>
hasOperands(const internal::Matcher<Expr> &Matcher1,
const internal::Matcher<Expr> &Matcher2) {
return anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
allOf(hasLHS(Matcher2), hasRHS(Matcher1)));
AST_POLYMORPHIC_MATCHER_P2(
hasOperands,
AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, CXXOperatorCallExpr,
CXXRewrittenBinaryOperator),
internal::Matcher<Expr>, Matcher1, internal::Matcher<Expr>, Matcher2) {
return internal::VariadicDynCastAllOfMatcher<Stmt, NodeType>()(
anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)),
allOf(hasLHS(Matcher2), hasRHS(Matcher1))))
.matches(Node, Finder, Builder);
}
/// Matches if the operand of a unary operator matches.
@ -4988,9 +5434,11 @@ hasOperands(const internal::Matcher<Expr> &Matcher1,
/// \code
/// !true
/// \endcode
AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
internal::Matcher<Expr>, InnerMatcher) {
const Expr * const Operand = Node.getSubExpr();
AST_POLYMORPHIC_MATCHER_P(hasUnaryOperand,
AST_POLYMORPHIC_SUPPORTED_TYPES(UnaryOperator,
CXXOperatorCallExpr),
internal::Matcher<Expr>, InnerMatcher) {
const Expr *const Operand = internal::getSubExpr(Node);
return (Operand != nullptr &&
InnerMatcher.matches(*Operand, Finder, Builder));
}
@ -5198,6 +5646,9 @@ AST_MATCHER(FunctionDecl, isVariadic) {
/// \endcode
AST_MATCHER_P(CXXMethodDecl, ofClass,
internal::Matcher<CXXRecordDecl>, InnerMatcher) {
ASTChildrenNotSpelledInSourceScope RAII(Finder, false);
const CXXRecordDecl *Parent = Node.getParent();
return (Parent != nullptr &&
InnerMatcher.matches(*Parent, Finder, Builder));
@ -5624,7 +6075,8 @@ AST_POLYMORPHIC_MATCHER_P(
AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
internal::Matcher<UsingShadowDecl>, InnerMatcher) {
return matchesFirstInPointerRange(InnerMatcher, Node.shadow_begin(),
Node.shadow_end(), Finder, Builder);
Node.shadow_end(), Finder,
Builder) != Node.shadow_end();
}
/// Matches a using shadow declaration where the target declaration is
@ -6399,7 +6851,7 @@ extern const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
/// \endcode
extern const AstTypeMatcher<DecayedType> decayedType;
/// Matches the decayed type, whos decayed type matches \c InnerMatcher
/// Matches the decayed type, whoes decayed type matches \c InnerMatcher
AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>,
InnerType) {
return InnerType.matches(Node.getDecayedType(), Finder, Builder);
@ -6616,6 +7068,8 @@ AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer,
BoundNodesTreeBuilder Result;
bool Matched = false;
for (const auto *I : Node.inits()) {
if (Finder->isTraversalIgnoringImplicitNodes() && !I->isWritten())
continue;
BoundNodesTreeBuilder InitBuilder(*Builder);
if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
Matched = true;
@ -6742,6 +7196,9 @@ AST_MATCHER_P(FunctionDecl, hasExplicitSpecifier, internal::Matcher<Expr>,
ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(&Node);
if (!ES.getExpr())
return false;
ASTChildrenNotSpelledInSourceScope RAII(Finder, false);
return InnerMatcher.matches(*ES.getExpr(), Finder, Builder);
}
@ -7180,7 +7637,8 @@ AST_MATCHER_P(OMPExecutableDirective, hasAnyClause,
internal::Matcher<OMPClause>, InnerMatcher) {
ArrayRef<OMPClause *> Clauses = Node.clauses();
return matchesFirstInPointerRange(InnerMatcher, Clauses.begin(),
Clauses.end(), Finder, Builder);
Clauses.end(), Finder,
Builder) != Clauses.end();
}
/// Matches OpenMP ``default`` clause.

View File

@ -134,8 +134,9 @@
class matcher_##DefineMatcher##OverloadId##Matcher \
: public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
public: \
explicit matcher_##DefineMatcher##OverloadId##Matcher(ParamType A##Param) \
: Param(std::move(A##Param)) {} \
explicit matcher_##DefineMatcher##OverloadId##Matcher( \
ParamType const &A##Param) \
: Param(A##Param) {} \
bool matches(const Type &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder \
@ -146,13 +147,12 @@
}; \
} \
inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
ParamType Param) { \
ParamType const &Param) { \
return ::clang::ast_matchers::internal::makeMatcher( \
new internal::matcher_##DefineMatcher##OverloadId##Matcher( \
std::move(Param))); \
new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
} \
typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
&DefineMatcher##_Type##OverloadId)(ParamType Param); \
typedef ::clang::ast_matchers::internal::Matcher<Type>( \
&DefineMatcher##_Type##OverloadId)(ParamType const &Param); \
inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
const Type &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
@ -183,9 +183,9 @@
class matcher_##DefineMatcher##OverloadId##Matcher \
: public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
public: \
matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 A##Param1, \
ParamType2 A##Param2) \
: Param1(std::move(A##Param1)), Param2(std::move(A##Param2)) {} \
matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
ParamType2 const &A##Param2) \
: Param1(A##Param1), Param2(A##Param2) {} \
bool matches(const Type &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder \
@ -197,14 +197,14 @@
}; \
} \
inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
ParamType1 Param1, ParamType2 Param2) { \
ParamType1 const &Param1, ParamType2 const &Param2) { \
return ::clang::ast_matchers::internal::makeMatcher( \
new internal::matcher_##DefineMatcher##OverloadId##Matcher( \
std::move(Param1), std::move(Param2))); \
new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
Param2)); \
} \
typedef ::clang::ast_matchers::internal::Matcher<Type> ( \
&DefineMatcher##_Type##OverloadId)(ParamType1 Param1, \
ParamType2 Param2); \
typedef ::clang::ast_matchers::internal::Matcher<Type>( \
&DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \
ParamType2 const &Param2); \
inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
const Type &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
@ -272,8 +272,9 @@
class matcher_##DefineMatcher##OverloadId##Matcher \
: public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
public: \
explicit matcher_##DefineMatcher##OverloadId##Matcher(ParamType A##Param) \
: Param(std::move(A##Param)) {} \
explicit matcher_##DefineMatcher##OverloadId##Matcher( \
ParamType const &A##Param) \
: Param(A##Param) {} \
bool matches(const NodeType &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder \
@ -286,14 +287,15 @@
inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
ReturnTypesF> \
DefineMatcher(ParamType Param) { \
DefineMatcher(ParamType const &Param) { \
return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
ReturnTypesF>(std::move(Param)); \
ReturnTypesF>(Param); \
} \
typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
ReturnTypesF> (&DefineMatcher##_Type##OverloadId)(ParamType Param); \
ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
ParamType const &Param); \
template <typename NodeType, typename ParamT> \
bool internal:: \
matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
@ -323,9 +325,9 @@
class matcher_##DefineMatcher##OverloadId##Matcher \
: public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
public: \
matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 A##Param1, \
ParamType2 A##Param2) \
: Param1(std::move(A##Param1)), Param2(std::move(A##Param2)) {} \
matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
ParamType2 const &A##Param2) \
: Param1(A##Param1), Param2(A##Param2) {} \
bool matches(const NodeType &Node, \
::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
::clang::ast_matchers::internal::BoundNodesTreeBuilder \
@ -339,15 +341,15 @@
inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
ParamType2, ReturnTypesF> \
DefineMatcher(ParamType1 Param1, ParamType2 Param2) { \
DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \
return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
ParamType2, ReturnTypesF>(std::move(Param1), std::move(Param2)); \
ParamType2, ReturnTypesF>(Param1, Param2); \
} \
typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
ParamType2, ReturnTypesF> (&DefineMatcher##_Type##OverloadId)( \
ParamType1 Param1, ParamType2 Param2); \
ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
ParamType1 const &Param1, ParamType2 const &Param2); \
template <typename NodeType, typename ParamT1, typename ParamT2> \
bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
NodeType, ParamT1, ParamT2>:: \

View File

@ -100,8 +100,7 @@ class VariantMatcher {
/// Convert \p Matcher the destination type and return it as a new
/// DynTypedMatcher.
virtual DynTypedMatcher
convertMatcher(const DynTypedMatcher &Matcher) const = 0;
DynTypedMatcher convertMatcher(const DynTypedMatcher &Matcher) const;
/// Constructs a variadic typed matcher from \p InnerMatchers.
/// Will try to convert each inner matcher to the destination type and
@ -110,9 +109,6 @@ class VariantMatcher {
constructVariadicOperator(DynTypedMatcher::VariadicOperator Op,
ArrayRef<VariantMatcher> InnerMatchers) const;
protected:
~MatcherOps() = default;
private:
ASTNodeKind NodeKind;
};
@ -174,8 +170,12 @@ class VariantMatcher {
/// that can, the result would be ambiguous and false is returned.
template <class T>
bool hasTypedMatcher() const {
return hasTypedMatcher(ASTNodeKind::getFromNodeKind<T>());
}
bool hasTypedMatcher(ASTNodeKind NK) const {
if (!Value) return false;
return Value->getTypedMatcher(TypedMatcherOps<T>()).hasValue();
return Value->getTypedMatcher(MatcherOps(NK)).hasValue();
}
/// Determines if the contained matcher can be converted to \p Kind.
@ -197,10 +197,15 @@ class VariantMatcher {
template <class T>
ast_matchers::internal::Matcher<T> getTypedMatcher() const {
assert(hasTypedMatcher<T>() && "hasTypedMatcher<T>() == false");
return Value->getTypedMatcher(TypedMatcherOps<T>())
return Value->getTypedMatcher(MatcherOps(ASTNodeKind::getFromNodeKind<T>()))
->template convertTo<T>();
}
DynTypedMatcher getTypedMatcher(ASTNodeKind NK) const {
assert(hasTypedMatcher(NK) && "hasTypedMatcher(NK) == false");
return *Value->getTypedMatcher(MatcherOps(NK));
}
/// String representation of the type of the value.
///
/// If the underlying matcher is a polymorphic one, the string will show all
@ -211,7 +216,6 @@ class VariantMatcher {
explicit VariantMatcher(std::shared_ptr<Payload> Value)
: Value(std::move(Value)) {}
template <typename T> struct TypedMatcherOps;
class SinglePayload;
class PolymorphicPayload;
@ -220,17 +224,6 @@ class VariantMatcher {
std::shared_ptr<const Payload> Value;
};
template <typename T>
struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps {
TypedMatcherOps() : MatcherOps(ASTNodeKind::getFromNodeKind<T>()) {}
typedef ast_matchers::internal::Matcher<T> MatcherT;
DynTypedMatcher
convertMatcher(const DynTypedMatcher &Matcher) const override {
return DynTypedMatcher(Matcher.convertTo<T>());
}
};
/// Variant value class.
///
/// Basically, a tagged union with value type semantics.
@ -258,6 +251,7 @@ class VariantValue {
VariantValue(double Double);
VariantValue(unsigned Unsigned);
VariantValue(StringRef String);
VariantValue(ASTNodeKind NodeKind);
VariantValue(const VariantMatcher &Matchers);
/// Constructs an \c unsigned value (disambiguation from bool).
@ -287,6 +281,10 @@ class VariantValue {
const std::string &getString() const;
void setString(StringRef String);
bool isNodeKind() const;
const ASTNodeKind &getNodeKind() const;
void setNodeKind(ASTNodeKind NodeKind);
/// Matcher value functions.
bool isMatcher() const;
const VariantMatcher &getMatcher() const;
@ -323,7 +321,8 @@ class VariantValue {
VT_Double,
VT_Unsigned,
VT_String,
VT_Matcher
VT_Matcher,
VT_NodeKind
};
/// All supported value types.
@ -333,6 +332,7 @@ class VariantValue {
bool Boolean;
std::string *String;
VariantMatcher *Matcher;
ASTNodeKind *NodeKind;
};
ValueType Type;

View File

@ -0,0 +1,112 @@
//===- CalledOnceCheck.h - Check 'called once' parameters -------*- 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 check for function-like parameters that should be
// called exactly one time.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H
namespace clang {
class AnalysisDeclContext;
class CFG;
class Decl;
class DeclContext;
class Expr;
class ParmVarDecl;
class Stmt;
/// Classification of situations when parameter is not called on every path.
/// \enum IfThen -- then branch of the if statement has no call.
/// \enum IfElse -- else branch of the if statement has no call.
/// \enum Switch -- one of the switch cases doesn't have a call.
/// \enum SwitchSkipped -- there is no call if none of the cases appies.
/// \enum LoopEntered -- no call when the loop is entered.
/// \enum LoopSkipped -- no call when the loop is not entered.
/// \enum FallbackReason -- fallback case when we were not able to figure out
/// the reason.
enum class NeverCalledReason {
IfThen,
IfElse,
Switch,
SwitchSkipped,
LoopEntered,
LoopSkipped,
FallbackReason,
LARGEST_VALUE = FallbackReason
};
class CalledOnceCheckHandler {
public:
CalledOnceCheckHandler() = default;
virtual ~CalledOnceCheckHandler() = default;
/// Called when parameter is called twice.
/// \param Parameter -- parameter that should be called once.
/// \param Call -- call to report the warning.
/// \param PrevCall -- previous call.
/// \param IsCompletionHandler -- true, if parameter is a completion handler.
/// \param Poised -- true, if the second call is guaranteed to happen after
/// the first call.
virtual void handleDoubleCall(const ParmVarDecl *Parameter, const Expr *Call,
const Expr *PrevCall, bool IsCompletionHandler,
bool Poised) {}
/// Called when parameter is not called at all.
/// \param Parameter -- parameter that should be called once.
/// \param IsCompletionHandler -- true, if parameter is a completion handler.
virtual void handleNeverCalled(const ParmVarDecl *Parameter,
bool IsCompletionHandler) {}
/// Called when captured parameter is not called at all.
/// \param Parameter -- parameter that should be called once.
/// \param Where -- declaration that captures \p Parameter
/// \param IsCompletionHandler -- true, if parameter is a completion handler.
virtual void handleCapturedNeverCalled(const ParmVarDecl *Parameter,
const Decl *Where,
bool IsCompletionHandler) {}
/// Called when parameter is not called on one of the paths.
/// Usually we try to find a statement that is the least common ancestor of
/// the path containing the call and not containing the call. This helps us
/// to pinpoint a bad path for the user.
/// \param Parameter -- parameter that should be called once.
/// \param Where -- the least common ancestor statement.
/// \param Reason -- a reason describing the path without a call.
/// \param IsCalledDirectly -- true, if parameter actually gets called on
/// the other path. It is opposed to be used in some other way (added to some
/// collection, passed as a parameter, etc.).
/// \param IsCompletionHandler -- true, if parameter is a completion handler.
virtual void handleNeverCalled(const ParmVarDecl *Parameter,
const Stmt *Where, NeverCalledReason Reason,
bool IsCalledDirectly,
bool IsCompletionHandler) {}
};
/// Check given CFG for 'called once' parameter violations.
///
/// It traverses the function and tracks how such parameters are used.
/// It detects two main violations:
/// * parameter is called twice
/// * parameter is not called
///
/// \param AC -- context.
/// \param Handler -- a handler for found violations.
/// \param CheckConventionalParameters -- true, if we want to check parameters
/// not explicitly marked as 'called once', but having the same requirements
/// according to conventions.
void checkCalledOnceParameters(AnalysisDeclContext &AC,
CalledOnceCheckHandler &Handler,
bool CheckConventionalParameters);
} // end namespace clang
#endif /* LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H */

View File

@ -273,76 +273,6 @@ class ControlDependencyCalculator : public ManagedAnalysis {
namespace llvm {
/// Clang's CFG contains nullpointers for unreachable succesors, e.g. when an
/// if statement's condition is always false, it's 'then' branch is represented
/// with a nullptr. This however will result in a nullpointer derefernece for
/// dominator tree calculation.
///
/// To circumvent this, let's just crudely specialize the children getters
/// used in LLVM's dominator tree builder.
namespace DomTreeBuilder {
using ClangCFGDomChildrenGetter =
SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/false>;
template <>
template <>
inline ClangCFGDomChildrenGetter::ResultTy ClangCFGDomChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) {
auto RChildren = reverse(children<NodePtr>(N));
ResultTy Ret(RChildren.begin(), RChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}
using ClangCFGDomReverseChildrenGetter =
SemiNCAInfo<clang::CFGDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/true>;
template <>
template <>
inline ClangCFGDomReverseChildrenGetter::ResultTy
ClangCFGDomReverseChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) {
auto IChildren = inverse_children<NodePtr>(N);
ResultTy Ret(IChildren.begin(), IChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}
using ClangCFGPostDomChildrenGetter =
SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/false>;
template <>
template <>
inline ClangCFGPostDomChildrenGetter::ResultTy
ClangCFGPostDomChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/false>) {
auto RChildren = reverse(children<NodePtr>(N));
ResultTy Ret(RChildren.begin(), RChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}
using ClangCFGPostDomReverseChildrenGetter =
SemiNCAInfo<clang::CFGPostDomTree::DominatorTreeBase>::ChildrenGetter<
/*Inverse=*/true>;
template <>
template <>
inline ClangCFGPostDomReverseChildrenGetter::ResultTy
ClangCFGPostDomReverseChildrenGetter::Get(
clang::CFGBlock *N, std::integral_constant<bool, /*Inverse=*/true>) {
auto IChildren = inverse_children<NodePtr>(N);
ResultTy Ret(IChildren.begin(), IChildren.end());
Ret.erase(std::remove(Ret.begin(), Ret.end(), nullptr), Ret.end());
return Ret;
}
} // end of namespace DomTreeBuilder
//===-------------------------------------
/// DominatorTree GraphTraits specialization so the DominatorTree can be
/// iterable by generic graph iterators.

View File

@ -30,22 +30,22 @@ class LiveVariables : public ManagedAnalysis {
class LivenessValues {
public:
llvm::ImmutableSet<const Stmt *> liveStmts;
llvm::ImmutableSet<const Expr *> liveExprs;
llvm::ImmutableSet<const VarDecl *> liveDecls;
llvm::ImmutableSet<const BindingDecl *> liveBindings;
bool equals(const LivenessValues &V) const;
LivenessValues()
: liveStmts(nullptr), liveDecls(nullptr), liveBindings(nullptr) {}
: liveExprs(nullptr), liveDecls(nullptr), liveBindings(nullptr) {}
LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
LivenessValues(llvm::ImmutableSet<const Expr *> liveExprs,
llvm::ImmutableSet<const VarDecl *> LiveDecls,
llvm::ImmutableSet<const BindingDecl *> LiveBindings)
: liveStmts(LiveStmts), liveDecls(LiveDecls),
: liveExprs(liveExprs), liveDecls(LiveDecls),
liveBindings(LiveBindings) {}
bool isLive(const Stmt *S) const;
bool isLive(const Expr *E) const;
bool isLive(const VarDecl *D) const;
friend class LiveVariables;
@ -83,17 +83,17 @@ class LiveVariables : public ManagedAnalysis {
/// only returns liveness information for block-level expressions.
bool isLive(const Stmt *S, const VarDecl *D);
/// Returns true the block-level expression "value" is live
/// Returns true the block-level expression value is live
/// before the given block-level expression (see runOnAllBlocks).
bool isLive(const Stmt *Loc, const Stmt *StmtVal);
bool isLive(const Stmt *Loc, const Expr *Val);
/// Print to stderr the variable liveness information associated with
/// each basic block.
void dumpBlockLiveness(const SourceManager &M);
/// Print to stderr the statement liveness information associated with
/// Print to stderr the expression liveness information associated with
/// each basic block.
void dumpStmtLiveness(const SourceManager &M);
void dumpExprLiveness(const SourceManager &M);
void runOnAllBlocks(Observer &obs);

View File

@ -202,6 +202,14 @@ class ThreadSafetyHandler {
virtual void handleNegativeNotHeld(StringRef Kind, Name LockName, Name Neg,
SourceLocation Loc) {}
/// Warn when calling a function that a negative capability is not held.
/// \param D -- The decl for the function requiring the negative capability.
/// \param LockName -- The name for the lock expression, to be printed in the
/// diagnostic.
/// \param Loc -- The location of the protected operation.
virtual void handleNegativeNotHeld(const NamedDecl *D, Name LockName,
SourceLocation Loc) {}
/// Warn when a function is called while an excluded mutex is locked. For
/// example, the mutex may be locked inside the function.
/// \param Kind -- the capability's name parameter (role, mutex, etc).

View File

@ -634,7 +634,9 @@ typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
/// At compile time, pointer literals are represented by symbolic names.
class LiteralPtr : public SExpr {
public:
LiteralPtr(const ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
LiteralPtr(const ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {
assert(D && "ValueDecl must not be null");
}
LiteralPtr(const LiteralPtr &) = default;
static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }

View File

@ -91,8 +91,8 @@ class CallGraph : public RecursiveASTVisitor<CallGraph> {
/// Get the number of nodes in the graph.
unsigned size() const { return FunctionMap.size(); }
/// \ brief Get the virtual root of the graph, all the functions available
/// externally are represented as callees of the node.
/// Get the virtual root of the graph, all the functions available externally
/// are represented as callees of the node.
CallGraphNode *getRoot() const { return Root; }
/// Iterators through all the nodes of the graph that have no parent. These

View File

@ -0,0 +1,49 @@
//===---------- IssueHash.h - Generate identification hashes ----*- 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_STATICANALYZER_CORE_ISSUE_HASH_H
#define LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H
#include "llvm/ADT/SmallString.h"
namespace clang {
class Decl;
class FullSourceLoc;
class LangOptions;
/// Returns an opaque identifier for a diagnostic.
///
/// This opaque identifier is intended to be stable even when the source code
/// is changed. It allows to track diagnostics in the long term, for example,
/// find which diagnostics are "new", maintain a database of suppressed
/// diagnostics etc.
///
/// We may introduce more variants of issue hashes in the future
/// but older variants will still be available for compatibility.
///
/// This hash is based on the following information:
/// - Name of the checker that emitted the diagnostic.
/// - Warning message.
/// - Name of the enclosing declaration.
/// - Contents of the line of code with the issue, excluding whitespace.
/// - Column number (but not the line number! - which makes it stable).
llvm::SmallString<32> getIssueHash(const FullSourceLoc &IssueLoc,
llvm::StringRef CheckerName,
llvm::StringRef WarningMessage,
const Decl *IssueDecl,
const LangOptions &LangOpts);
/// Get the unhashed string representation of the V1 issue hash.
/// When hashed, it becomes the actual issue hash. Useful for testing.
/// See GetIssueHashV1() for more information.
std::string getIssueString(const FullSourceLoc &IssueLoc,
llvm::StringRef CheckerName,
llvm::StringRef WarningMessage,
const Decl *IssueDecl, const LangOptions &LangOpts);
} // namespace clang
#endif

View File

@ -58,6 +58,45 @@ namespace ento {
class PathDiagnostic;
/// These options tweak the behavior of path diangostic consumers.
/// Most of these options are currently supported by very few consumers.
struct PathDiagnosticConsumerOptions {
/// Run-line of the tool that produced the diagnostic.
/// It can be included with the diagnostic for debugging purposes.
std::string ToolInvocation;
/// Whether to include additional information about macro expansions
/// with the diagnostics, because otherwise they can be hard to obtain
/// without re-compiling the program under analysis.
bool ShouldDisplayMacroExpansions = false;
/// Whether to include LLVM statistics of the process in the diagnostic.
/// Useful for profiling the tool on large real-world codebases.
bool ShouldSerializeStats = false;
/// If the consumer intends to produce multiple output files, should it
/// use randomly generated file names for these files (with the tiny risk of
/// having random collisions) or deterministic human-readable file names
/// (with a larger risk of deterministic collisions or invalid characters
/// in the file name). We should not really give this choice to the users
/// because deterministic mode is always superior when done right, but
/// for some consumers this mode is experimental and needs to be
/// off by default.
bool ShouldWriteStableReportFilename = false;
/// Whether the consumer should treat consumed diagnostics as hard errors.
/// Useful for breaking your build when issues are found.
bool ShouldDisplayWarningsAsErrors = false;
/// Whether the consumer should attempt to rewrite the source file
/// with fix-it hints attached to the diagnostics it consumes.
bool ShouldApplyFixIts = false;
/// Whether the consumer should present the name of the entity that emitted
/// the diagnostic (eg., a checker) so that the user knew how to disable it.
bool ShouldDisplayDiagnosticName = false;
};
class PathDiagnosticConsumer {
public:
class PDFileEntry : public llvm::FoldingSetNode {

View File

@ -36,6 +36,8 @@ enum class LangAS : unsigned {
opencl_constant,
opencl_private,
opencl_generic,
opencl_global_device,
opencl_global_host,
// CUDA specific address spaces.
cuda_device,

View File

@ -33,6 +33,8 @@ inline llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
return llvm::VersionTuple(11U);
case llvm::Triple::WatchOS: // Earliest supporting version is 4.0.0.
return llvm::VersionTuple(4U);
case llvm::Triple::ZOS:
return llvm::VersionTuple(); // All z/OS versions have no support.
}
llvm_unreachable("Unexpected OS");

View File

@ -126,6 +126,9 @@ def FunctionTmpl
FunctionDecl::TK_FunctionTemplate}],
"function templates">;
def ClassTmpl : SubsetSubject<CXXRecord, [{S->getDescribedClassTemplate()}],
"class templates">;
// FIXME: this hack is needed because DeclNodes.td defines the base Decl node
// type to be a class, not a definition. This makes it impossible to create an
// attribute subject which accepts a Decl. Normally, this is not a problem,
@ -267,8 +270,10 @@ class CXX11<string namespace, string name, int version = 1>
string Namespace = namespace;
int Version = version;
}
class C2x<string namespace, string name> : Spelling<name, "C2x"> {
class C2x<string namespace, string name, int version = 1>
: Spelling<name, "C2x"> {
string Namespace = namespace;
int Version = version;
}
class Keyword<string name> : Spelling<name, "Keyword">;
@ -319,6 +324,7 @@ class LangOpt<string name, code customCode = [{}]> {
def MicrosoftExt : LangOpt<"MicrosoftExt">;
def Borland : LangOpt<"Borland">;
def CUDA : LangOpt<"CUDA">;
def HIP : LangOpt<"HIP">;
def SYCL : LangOpt<"SYCLIsDevice">;
def COnly : LangOpt<"", "!LangOpts.CPlusPlus">;
def CPlusPlus : LangOpt<"CPlusPlus">;
@ -366,8 +372,8 @@ def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
let OSes = ["Win32"];
def TargetHasDLLImportExport : TargetSpec {
let CustomCode = [{ Target.getTriple().hasDLLImportExport() }];
}
def TargetItaniumCXXABI : TargetSpec {
let CustomCode = [{ Target.getCXXABI().isItaniumFamily() }];
@ -379,6 +385,9 @@ def TargetELF : TargetSpec {
let ObjectFormats = ["ELF"];
}
def TargetSupportsInitPriority : TargetSpec {
let CustomCode = [{ !Target.getTriple().isOSzOS() }];
}
// Attribute subject match rules that are used for #pragma clang attribute.
//
// A instance of AttrSubjectMatcherRule represents an individual match rule.
@ -562,6 +571,9 @@ class InheritableAttr : Attr {
/// attributes, but have historically been written on declarations.
class DeclOrTypeAttr : InheritableAttr;
/// A attribute is either a declaration attribute or a statement attribute.
class DeclOrStmtAttr : InheritableAttr;
/// A target-specific attribute. This class is meant to be used as a mixin
/// with InheritableAttr or Attr depending on the attribute's needs.
class TargetSpecificAttr<TargetSpec target> {
@ -670,10 +682,17 @@ def AlignMac68k : InheritableAttr {
let Documentation = [Undocumented];
}
def AlignNatural : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
let SemaHandler = 0;
let Documentation = [Undocumented];
}
def AlwaysInline : InheritableAttr {
let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
let Documentation = [AlwaysInlineDocs];
}
def Artificial : InheritableAttr {
@ -735,9 +754,19 @@ def AnalyzerNoReturn : InheritableAttr {
def Annotate : InheritableParamAttr {
let Spellings = [Clang<"annotate">];
let Args = [StringArgument<"Annotation">];
let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">];
// Ensure that the annotate attribute can be used with
// '#pragma clang attribute' even though it has no subject list.
let AdditionalMembers = [{
static AnnotateAttr *Create(ASTContext &Ctx, llvm::StringRef Annotation, \
const AttributeCommonInfo &CommonInfo) {
return AnnotateAttr::Create(Ctx, Annotation, nullptr, 0, CommonInfo);
}
static AnnotateAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef Annotation, \
const AttributeCommonInfo &CommonInfo = {SourceRange{}}) {
return AnnotateAttr::CreateImplicit(Ctx, Annotation, nullptr, 0, CommonInfo);
}
}];
let PragmaAttributeSupport = 1;
let Documentation = [Undocumented];
}
@ -823,6 +852,7 @@ static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
.Case("macos_app_extension", "macOSApplicationExtension")
.Case("tvos_app_extension", "tvOSApplicationExtension")
.Case("watchos_app_extension", "watchOSApplicationExtension")
.Case("zos", "z/OS")
.Default(Platform);
}
static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
@ -1060,6 +1090,7 @@ def CUDADeviceBuiltinSurfaceType : InheritableAttr {
let LangOpts = [CUDA];
let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [CUDADeviceBuiltinSurfaceTypeDocs];
let MeaningfulToClassTemplateDefinition = 1;
}
def CUDADeviceBuiltinTextureType : InheritableAttr {
@ -1068,6 +1099,7 @@ def CUDADeviceBuiltinTextureType : InheritableAttr {
let LangOpts = [CUDA];
let Subjects = SubjectList<[CXXRecord]>;
let Documentation = [CUDADeviceBuiltinTextureTypeDocs];
let MeaningfulToClassTemplateDefinition = 1;
}
def CUDAGlobal : InheritableAttr {
@ -1084,6 +1116,13 @@ def CUDAHost : InheritableAttr {
let Documentation = [Undocumented];
}
def HIPManaged : InheritableAttr {
let Spellings = [GNU<"managed">, Declspec<"__managed__">];
let Subjects = SubjectList<[Var]>;
let LangOpts = [HIP];
let Documentation = [HIPManagedAttrDocs];
}
def CUDAInvalidTarget : InheritableAttr {
let Spellings = [];
let Subjects = SubjectList<[Function]>;
@ -1178,6 +1217,16 @@ def OpenCLGlobalAddressSpace : TypeAttr {
let Documentation = [OpenCLAddressSpaceGlobalDocs];
}
def OpenCLGlobalDeviceAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_device">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
}
def OpenCLGlobalHostAddressSpace : TypeAttr {
let Spellings = [Clang<"opencl_global_host">];
let Documentation = [OpenCLAddressSpaceGlobalExtDocs];
}
def OpenCLLocalAddressSpace : TypeAttr {
let Spellings = [Keyword<"__local">, Keyword<"local">, Clang<"opencl_local">];
let Documentation = [OpenCLAddressSpaceLocalDocs];
@ -1211,7 +1260,8 @@ def RenderScriptKernel : Attr {
def Deprecated : InheritableAttr {
let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
CXX11<"","deprecated", 201309>, C2x<"", "deprecated">];
CXX11<"","deprecated", 201309>,
C2x<"", "deprecated", 201904>];
let Args = [StringArgument<"Message", 1>,
// An optional string argument that enables us to provide a
// Fix-It.
@ -1268,15 +1318,29 @@ def ExtVectorType : Attr {
}
def FallThrough : StmtAttr {
let Spellings = [CXX11<"", "fallthrough", 201603>, C2x<"", "fallthrough">,
let Spellings = [CXX11<"", "fallthrough", 201603>,
C2x<"", "fallthrough", 201904>,
CXX11<"clang", "fallthrough">, GCC<"fallthrough">];
// let Subjects = [NullStmt];
let Documentation = [FallthroughDocs];
}
def NoMerge : StmtAttr {
def Likely : StmtAttr {
let Spellings = [CXX11<"", "likely", 201803>, C2x<"clang", "likely">];
let Documentation = [LikelihoodDocs];
}
def Unlikely : StmtAttr {
let Spellings = [CXX11<"", "unlikely", 201803>, C2x<"clang", "unlikely">];
let Documentation = [LikelihoodDocs];
}
def NoMerge : DeclOrStmtAttr {
let Spellings = [Clang<"nomerge">];
let Documentation = [NoMergeDocs];
let InheritEvenIfAlreadyPresent = 1;
let Subjects = SubjectList<[Function], ErrorDiag, "functions and statements">;
let SimpleHandler = 1;
}
def FastCall : DeclOrTypeAttr {
@ -1405,6 +1469,13 @@ def LayoutVersion : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> {
let Documentation = [LayoutVersionDocs];
}
def Leaf : InheritableAttr {
let Spellings = [GCC<"leaf">];
let Subjects = SubjectList<[Function]>;
let Documentation = [LeafDocs];
let SimpleHandler = 1;
}
def LifetimeBound : DeclOrTypeAttr {
let Spellings = [Clang<"lifetimebound", 0>];
let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;
@ -1532,6 +1603,16 @@ def NeonVectorType : TypeAttr {
let ASTNode = 0;
}
def ArmSveVectorBits : TypeAttr {
let Spellings = [GNU<"arm_sve_vector_bits">];
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
let Args = [UnsignedArgument<"NumBits">];
let Documentation = [ArmSveVectorBitsDocs];
let PragmaAttributeSupport = 0;
// Represented as VectorType instead.
let ASTNode = 0;
}
def ArmMveStrictPolymorphism : TypeAttr, TargetSpecificAttr<TargetARM> {
let Spellings = [Clang<"__clang_arm_mve_strict_polymorphism">];
let Documentation = [ArmMveStrictPolymorphismDocs];
@ -1732,6 +1813,13 @@ def ReturnsNonNull : InheritableAttr {
let Documentation = [ReturnsNonNullDocs];
}
def CalledOnce : Attr {
let Spellings = [Clang<"called_once">];
let Subjects = SubjectList<[ParmVar]>;
let LangOpts = [ObjC];
let Documentation = [CalledOnceDocs];
}
// pass_object_size(N) indicates that the parameter should have
// __builtin_object_size with Type=N evaluated on the parameter at the callsite.
def PassObjectSize : InheritableParamAttr {
@ -1754,6 +1842,11 @@ def TypeNullable : TypeAttr {
let Documentation = [TypeNullableDocs];
}
def TypeNullableResult : TypeAttr {
let Spellings = [Keyword<"_Nullable_result">];
let Documentation = [TypeNullableResultDocs];
}
def TypeNullUnspecified : TypeAttr {
let Spellings = [Keyword<"_Null_unspecified">];
let Documentation = [TypeNullUnspecifiedDocs];
@ -1856,6 +1949,13 @@ def ObjCBridgeRelated : InheritableAttr {
let Documentation = [Undocumented];
}
def NSErrorDomain : InheritableAttr {
let Spellings = [GNU<"ns_error_domain">];
let Subjects = SubjectList<[Enum], ErrorDiag>;
let Args = [DeclArgument<Var, "ErrorDomain">];
let Documentation = [NSErrorDomainDocs];
}
def NSReturnsRetained : DeclOrTypeAttr {
let Spellings = [Clang<"ns_returns_retained">];
// let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
@ -1980,6 +2080,13 @@ def ObjCDirectMembers : Attr {
let Documentation = [ObjCDirectMembersDocs];
}
def ObjCNonRuntimeProtocol : Attr {
let Spellings = [Clang<"objc_non_runtime_protocol">];
let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
let LangOpts = [ObjC];
let Documentation = [ObjCNonRuntimeProtocolDocs];
}
def ObjCRuntimeName : Attr {
let Spellings = [Clang<"objc_runtime_name">];
let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
@ -2087,6 +2194,70 @@ def Regparm : TypeAttr {
let ASTNode = 0;
}
def SwiftAsyncName : InheritableAttr {
let Spellings = [GNU<"swift_async_name">];
let Args = [StringArgument<"Name">];
let Subjects = SubjectList<[ObjCMethod, Function], ErrorDiag>;
let Documentation = [SwiftAsyncNameDocs];
}
def SwiftAttr : InheritableAttr {
let Spellings = [GNU<"swift_attr">];
let Args = [StringArgument<"Attribute">];
let Documentation = [SwiftAttrDocs];
}
def SwiftBridge : InheritableAttr {
let Spellings = [GNU<"swift_bridge">];
let Args = [StringArgument<"SwiftType">];
let Subjects = SubjectList<[Tag, TypedefName, ObjCInterface, ObjCProtocol],
ErrorDiag>;
let Documentation = [SwiftBridgeDocs];
}
def SwiftBridgedTypedef : InheritableAttr {
let Spellings = [GNU<"swift_bridged_typedef">];
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
let Documentation = [SwiftBridgedTypedefDocs];
}
def SwiftObjCMembers : Attr {
let Spellings = [GNU<"swift_objc_members">];
let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
let Documentation = [SwiftObjCMembersDocs];
}
def SwiftError : InheritableAttr {
let Spellings = [GNU<"swift_error">];
let Args = [
EnumArgument<"Convention", "ConventionKind",
["none", "nonnull_error", "null_result", "zero_result", "nonzero_result"],
["None", "NonNullError", "NullResult", "ZeroResult", "NonZeroResult"]>
];
let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
let Documentation = [SwiftErrorDocs];
}
def SwiftName : InheritableAttr {
let Spellings = [GNU<"swift_name">];
let Args = [StringArgument<"Name">];
let Documentation = [SwiftNameDocs];
}
def SwiftNewType : InheritableAttr {
let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">];
let Args = [EnumArgument<"NewtypeKind", "NewtypeKind",
["struct", "enum"], ["NK_Struct", "NK_Enum"]>];
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
let Documentation = [SwiftNewTypeDocs];
let HasCustomParsing = 1;
}
def SwiftPrivate : InheritableAttr {
let Spellings = [GNU<"swift_private">];
let Documentation = [SwiftPrivateDocs];
}
def NoDeref : TypeAttr {
let Spellings = [Clang<"noderef">];
let Documentation = [NoDerefDocs];
@ -2111,7 +2282,7 @@ def WorkGroupSizeHint : InheritableAttr {
let Documentation = [Undocumented];
}
def InitPriority : InheritableAttr {
def InitPriority : InheritableAttr, TargetSpecificAttr<TargetSupportsInitPriority> {
let Spellings = [GCC<"init_priority", /*AllowInC*/0>];
let Args = [UnsignedArgument<"Priority">];
let Subjects = SubjectList<[Var], ErrorDiag>;
@ -2167,6 +2338,14 @@ def PragmaClangRelroSection : InheritableAttr {
let Documentation = [Undocumented];
}
def StrictFP : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
// Function uses strict floating point operations.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
def PragmaClangTextSection : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
@ -2210,6 +2389,16 @@ def SwiftIndirectResult : ParameterABIAttr {
let Documentation = [SwiftIndirectResultDocs];
}
def SwiftAsync : InheritableAttr {
let Spellings = [Clang<"swift_async">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let Args = [EnumArgument<"Kind", "Kind",
["none", "swift_private", "not_swift_private"],
["None", "SwiftPrivate", "NotSwiftPrivate"]>,
ParamIdxArgument<"CompletionHandlerIndex", /*opt=*/1>];
let Documentation = [SwiftAsyncDocs];
}
def Suppress : StmtAttr {
let Spellings = [CXX11<"gsl", "suppress">];
let Args = [VariadicStringArgument<"DiagnosticIdentifiers">];
@ -2242,6 +2431,16 @@ def Pascal : DeclOrTypeAttr {
let Documentation = [Undocumented];
}
def PreferredName : InheritableAttr {
let Spellings = [Clang<"preferred_name", /*AllowInC*/0>];
let Subjects = SubjectList<[ClassTmpl]>;
let Args = [TypeArgument<"TypedefType">];
let Documentation = [PreferredNameDocs];
let InheritEvenIfAlreadyPresent = 1;
let MeaningfulToClassTemplateDefinition = 1;
let TemplateDependent = 1;
}
def PreserveMost : DeclOrTypeAttr {
let Spellings = [Clang<"preserve_most">];
let Documentation = [PreserveMostDocs];
@ -2317,11 +2516,10 @@ def Target : InheritableAttr {
// accepting it weirdly.
Feature = Feature.trim();
// We don't support cpu tuning this way currently.
// TODO: Support the fpmath option. It will require checking
// overall feature validity for the function with the rest of the
// attributes on the function.
if (Feature.startswith("fpmath=") || Feature.startswith("tune="))
if (Feature.startswith("fpmath="))
continue;
if (Feature.startswith("branch-protection=")) {
@ -2335,6 +2533,11 @@ def Target : InheritableAttr {
Ret.DuplicateArchitecture = true;
else
Ret.Architecture = Feature.split("=").second.trim();
} else if (Feature.startswith("tune=")) {
if (!Ret.Tune.empty())
Ret.DuplicateTune = true;
else
Ret.Tune = Feature.split("=").second.trim();
} else if (Feature.startswith("no-"))
Ret.Features.push_back("-" + Feature.split("-").second.str());
else
@ -2424,7 +2627,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr {
def Unused : InheritableAttr {
let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">,
C2x<"", "maybe_unused">];
C2x<"", "maybe_unused", 201904>];
let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label,
Field, ObjCMethod, FunctionLike]>;
let Documentation = [WarnMaybeUnusedDocs];
@ -2510,7 +2713,8 @@ def WarnUnused : InheritableAttr {
}
def WarnUnusedResult : InheritableAttr {
let Spellings = [CXX11<"", "nodiscard", 201907>, C2x<"", "nodiscard">,
let Spellings = [CXX11<"", "nodiscard", 201907>,
C2x<"", "nodiscard", 201904>,
CXX11<"clang", "warn_unused_result">,
GCC<"warn_unused_result">];
let Subjects = SubjectList<[ObjCMethod, Enum, Record, FunctionLike]>;
@ -3031,24 +3235,24 @@ def MSStruct : InheritableAttr {
let SimpleHandler = 1;
}
def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLExport : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
let Documentation = [DLLExportDocs];
}
def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
// This attribute is used internally only when -fno-dllexport-inlines is
// passed. This attribute is added to inline function of class having
// dllexport attribute. And if the function has static local variables, this
// attribute is used to whether the variables are exported or not. Also if
// function has local static variables, the function is dllexported too.
// passed. This attribute is added to inline functions of a class having the
// dllexport attribute. If the function has static local variables, this
// attribute is used to determine whether the variables are exported or not. If
// the function has local static variables, the function is dllexported too.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
}
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLImport : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
let Documentation = [DLLImportDocs];
@ -3064,11 +3268,11 @@ public:
}];
}
def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> {
def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
// This attribute is used internally only when -fno-dllexport-inlines is
// passed. This attribute is added to inline function of class having
// dllimport attribute. And if the function has static local variables, this
// attribute is used to whether the variables are imported or not.
// passed. This attribute is added to inline functions of a class having the
// dllimport attribute. If the function has static local variables, this
// attribute is used to determine whether the variables are imported or not.
let Spellings = [];
let Subjects = SubjectList<[Function]>;
let Documentation = [Undocumented];
@ -3186,8 +3390,10 @@ def LoopHint : Attr {
"PipelineDisabled", "PipelineInitiationInterval", "Distribute",
"VectorizePredicate"]>,
EnumArgument<"State", "LoopHintState",
["enable", "disable", "numeric", "assume_safety", "full"],
["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
["enable", "disable", "numeric", "fixed_width",
"scalable_width", "assume_safety", "full"],
["Enable", "Disable", "Numeric", "FixedWidth",
"ScalableWidth", "AssumeSafety", "Full"]>,
ExprArgument<"Value">];
let AdditionalMembers = [{
@ -3296,13 +3502,15 @@ def OMPDeclareTargetDecl : InheritableAttr {
[ "MT_To", "MT_Link" ]>,
EnumArgument<"DevType", "DevTypeTy",
[ "host", "nohost", "any" ],
[ "DT_Host", "DT_NoHost", "DT_Any" ]>
[ "DT_Host", "DT_NoHost", "DT_Any" ]>,
UnsignedArgument<"Level">
];
let AdditionalMembers = [{
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const;
static llvm::Optional<MapTypeTy>
isDeclareTargetDeclaration(const ValueDecl *VD);
static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD);
static llvm::Optional<SourceLocation> getLocation(const ValueDecl *VD);
}];
}
@ -3349,6 +3557,14 @@ def OMPDeclareVariant : InheritableAttr {
}];
}
def Assumption : InheritableAttr {
let Spellings = [Clang<"assume">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let InheritEvenIfAlreadyPresent = 1;
let Documentation = [AssumptionDocs];
let Args = [StringArgument<"Assumption">];
}
def InternalLinkage : InheritableAttr {
let Spellings = [Clang<"internal_linkage">];
let Subjects = SubjectList<[Var, Function, CXXRecord]>;
@ -3452,3 +3668,19 @@ def Builtin : InheritableAttr {
let SemaHandler = 0;
let Documentation = [Undocumented];
}
def EnforceTCB : InheritableAttr {
let Spellings = [Clang<"enforce_tcb">];
let Subjects = SubjectList<[Function]>;
let Args = [StringArgument<"TCBName">];
let Documentation = [EnforceTCBDocs];
bit InheritEvenIfAlreadyPresent = 1;
}
def EnforceTCBLeaf : InheritableAttr {
let Spellings = [Clang<"enforce_tcb_leaf">];
let Subjects = SubjectList<[Function]>;
let Args = [StringArgument<"TCBName">];
let Documentation = [EnforceTCBLeafDocs];
bit InheritEvenIfAlreadyPresent = 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -115,6 +115,7 @@
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", "ncF")
BUILTIN(__builtin_copysignf, "fff", "ncF")
@ -130,9 +131,11 @@ 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_huge_val, "d", "nc")
BUILTIN(__builtin_huge_valf, "f", "nc")
BUILTIN(__builtin_huge_vall, "Ld", "nc")
@ -146,9 +149,11 @@ 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_modf , "ddd*" , "Fn")
BUILTIN(__builtin_modff, "fff*" , "Fn")
BUILTIN(__builtin_modfl, "LdLdLd*", "Fn")
BUILTIN(__builtin_modff128, "LLdLLdLLd*", "Fn")
BUILTIN(__builtin_nan, "dcC*" , "FnU")
BUILTIN(__builtin_nanf, "fcC*" , "FnU")
BUILTIN(__builtin_nanl, "LdcC*", "FnU")
@ -164,167 +169,216 @@ 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_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", "Fnc")
BUILTIN(__builtin_fmaxf, "fff", "Fnc")
BUILTIN(__builtin_fmaxf16, "hhh", "Fnc")
BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc")
BUILTIN(__builtin_fmaxf128, "LLdLLdLLd", "Fnc")
BUILTIN(__builtin_fmin, "ddd", "Fnc")
BUILTIN(__builtin_fminf, "fff", "Fnc")
BUILTIN(__builtin_fminf16, "hhh", "Fnc")
BUILTIN(__builtin_fminl, "LdLdLd", "Fnc")
BUILTIN(__builtin_fminf128, "LLdLLdLLd", "Fnc")
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_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
@ -398,6 +452,9 @@ BUILTIN(__builtin_ctanh, "XdXd", "Fne")
BUILTIN(__builtin_ctanhf, "XfXf", "Fne")
BUILTIN(__builtin_ctanhl, "XLdXLd", "Fne")
// GCC-compatible C99 CMPLX implementation.
BUILTIN(__builtin_complex, "v.", "nct")
// FP Comparisons.
BUILTIN(__builtin_isgreater , "i.", "Fnct")
BUILTIN(__builtin_isgreaterequal, "i.", "Fnct")
@ -910,6 +967,7 @@ 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)

View File

@ -99,6 +99,12 @@ BUILTIN(__builtin_arm_tcommit, "v", "n")
BUILTIN(__builtin_arm_tcancel, "vWUIi", "n")
BUILTIN(__builtin_arm_ttest, "WUi", "nc")
// Armv8.7-A load/store 64-byte intrinsics
BUILTIN(__builtin_arm_ld64b, "vvC*WUi*", "n")
BUILTIN(__builtin_arm_st64b, "vv*WUiC*", "n")
BUILTIN(__builtin_arm_st64bv, "WUiv*WUiC*", "n")
BUILTIN(__builtin_arm_st64bv0, "WUiv*WUiC*", "n")
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, "")
@ -153,6 +159,11 @@ TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh",
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_acq,"UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_nf ,"UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_rel,"UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
TARGET_HEADER_BUILTIN(_InterlockedOr8_rel, "ccD*c", "nh", "intrin.h", ALL_MS_LANGUAGES, "")

View File

@ -37,6 +37,10 @@ BUILTIN(__builtin_amdgcn_workgroup_size_x, "Us", "nc")
BUILTIN(__builtin_amdgcn_workgroup_size_y, "Us", "nc")
BUILTIN(__builtin_amdgcn_workgroup_size_z, "Us", "nc")
BUILTIN(__builtin_amdgcn_grid_size_x, "Ui", "nc")
BUILTIN(__builtin_amdgcn_grid_size_y, "Ui", "nc")
BUILTIN(__builtin_amdgcn_grid_size_z, "Ui", "nc")
BUILTIN(__builtin_amdgcn_mbcnt_hi, "UiUiUi", "nc")
BUILTIN(__builtin_amdgcn_mbcnt_lo, "UiUiUi", "nc")
@ -210,6 +214,8 @@ BUILTIN(__builtin_amdgcn_read_exec, "LUi", "nc")
BUILTIN(__builtin_amdgcn_read_exec_lo, "Ui", "nc")
BUILTIN(__builtin_amdgcn_read_exec_hi, "Ui", "nc")
BUILTIN(__builtin_amdgcn_endpgm, "v", "nr")
//===----------------------------------------------------------------------===//
// R600-NI only builtins.
//===----------------------------------------------------------------------===//

View File

@ -21,7 +21,13 @@
TARGET_BUILTIN(__builtin_preserve_field_info, "Ui.", "t", "")
// Get BTF type id.
TARGET_BUILTIN(__builtin_btf_type_id, "Ui.", "t", "")
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

View File

@ -43,7 +43,7 @@
#define PTX60 "ptx60|" PTX61
#pragma push_macro("AND")
#define AND(a, b) a "," b
#define AND(a, b) "(" a "),(" b ")"
// Special Registers

View File

@ -7,14 +7,23 @@
//===----------------------------------------------------------------------===//
//
// This file defines the PowerPC-specific builtin function database. Users of
// this file must define the BUILTIN macro to make use of this information.
// this file must define the BUILTIN macro or the CUSTOM_BUILTIN macro to
// make use of this information. The latter is used for builtins requiring
// custom code generation and checking.
//
//===----------------------------------------------------------------------===//
// FIXME: this needs to be the full list supported by GCC. Right now, I'm just
// adding stuff on demand.
// The format of this database matches clang/Basic/Builtins.def.
// The format of this database matches clang/Basic/Builtins.def except for the
// MMA builtins that are using their own format documented below.
#if defined(BUILTIN) && !defined(CUSTOM_BUILTIN)
# define CUSTOM_BUILTIN(ID, TYPES, ACCUMULATE) BUILTIN(__builtin_##ID, "i.", "t")
#elif defined(CUSTOM_BUILTIN) && !defined(BUILTIN)
# define BUILTIN(ID, TYPES, ATTRS)
#endif
BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n")
@ -100,6 +109,11 @@ BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "")
BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "")
BUILTIN(__builtin_altivec_vmulouw, "V2ULLiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vmulosw, "V2SLLiV4SiV4Si", "")
BUILTIN(__builtin_altivec_vmuleud, "V1ULLLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vmulesd, "V1SLLLiV2SLLiV2SLLi", "")
BUILTIN(__builtin_altivec_vmuloud, "V1ULLLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vmulosd, "V1SLLLiV2SLLiV2SLLi", "")
BUILTIN(__builtin_altivec_vmsumcud, "V1ULLLiV2ULLiV2ULLiV1ULLLi", "")
BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "")
@ -151,6 +165,14 @@ BUILTIN(__builtin_altivec_vcmpgtsd, "V2LLiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vcmpgtud, "V2LLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "")
// P10 Vector compare builtins.
BUILTIN(__builtin_altivec_vcmpequq, "V1LLLiV1ULLLiV1ULLLi", "")
BUILTIN(__builtin_altivec_vcmpgtsq, "V1LLLiV1SLLLiV1SLLLi", "")
BUILTIN(__builtin_altivec_vcmpgtuq, "V1LLLiV1ULLLiV1ULLLi", "")
BUILTIN(__builtin_altivec_vcmpequq_p, "iiV1ULLLiV1LLLi", "")
BUILTIN(__builtin_altivec_vcmpgtsq_p, "iiV1SLLLiV1SLLLi", "")
BUILTIN(__builtin_altivec_vcmpgtuq_p, "iiV1ULLLiV1ULLLi", "")
BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "")
BUILTIN(__builtin_altivec_vmaxub, "V16UcV16UcV16Uc", "")
BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "")
@ -298,10 +320,71 @@ BUILTIN(__builtin_altivec_vrldmi, "V2ULLiV2ULLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vrlwnm, "V4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "")
// P9 Vector extend sign builtins.
BUILTIN(__builtin_altivec_vextsb2w, "V4SiV16Sc", "")
BUILTIN(__builtin_altivec_vextsb2d, "V2SLLiV16Sc", "")
BUILTIN(__builtin_altivec_vextsh2w, "V4SiV8Ss", "")
BUILTIN(__builtin_altivec_vextsh2d, "V2SLLiV8Ss", "")
BUILTIN(__builtin_altivec_vextsw2d, "V2SLLiV4Si", "")
// P10 Vector extend sign builtins.
BUILTIN(__builtin_altivec_vextsd2q, "V1SLLLiV2SLLi", "")
// P10 Vector Extract with Mask built-ins.
BUILTIN(__builtin_altivec_vextractbm, "UiV16Uc", "")
BUILTIN(__builtin_altivec_vextracthm, "UiV8Us", "")
BUILTIN(__builtin_altivec_vextractwm, "UiV4Ui", "")
BUILTIN(__builtin_altivec_vextractdm, "UiV2ULLi", "")
BUILTIN(__builtin_altivec_vextractqm, "UiV1ULLLi", "")
// P10 Vector Divide Extended built-ins.
BUILTIN(__builtin_altivec_vdivesw, "V4SiV4SiV4Si", "")
BUILTIN(__builtin_altivec_vdiveuw, "V4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vdivesd, "V2LLiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vdiveud, "V2ULLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vdivesq, "V1SLLLiV1SLLLiV1SLLLi", "")
BUILTIN(__builtin_altivec_vdiveuq, "V1ULLLiV1ULLLiV1ULLLi", "")
// P10 Vector Multiply High built-ins.
BUILTIN(__builtin_altivec_vmulhsw, "V4SiV4SiV4Si", "")
BUILTIN(__builtin_altivec_vmulhuw, "V4UiV4UiV4Ui", "")
BUILTIN(__builtin_altivec_vmulhsd, "V2LLiV2LLiV2LLi", "")
BUILTIN(__builtin_altivec_vmulhud, "V2ULLiV2ULLiV2ULLi", "")
// P10 Vector Expand with Mask built-ins.
BUILTIN(__builtin_altivec_vexpandbm, "V16UcV16Uc", "")
BUILTIN(__builtin_altivec_vexpandhm, "V8UsV8Us", "")
BUILTIN(__builtin_altivec_vexpandwm, "V4UiV4Ui", "")
BUILTIN(__builtin_altivec_vexpanddm, "V2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vexpandqm, "V1ULLLiV1ULLLi", "")
// P10 Vector Count with Mask built-ins.
BUILTIN(__builtin_altivec_vcntmbb, "ULLiV16UcUi", "")
BUILTIN(__builtin_altivec_vcntmbh, "ULLiV8UsUi", "")
BUILTIN(__builtin_altivec_vcntmbw, "ULLiV4UiUi", "")
BUILTIN(__builtin_altivec_vcntmbd, "ULLiV2ULLiUi", "")
// P10 Move to VSR with Mask built-ins.
BUILTIN(__builtin_altivec_mtvsrbm, "V16UcULLi", "")
BUILTIN(__builtin_altivec_mtvsrhm, "V8UsULLi", "")
BUILTIN(__builtin_altivec_mtvsrwm, "V4UiULLi", "")
BUILTIN(__builtin_altivec_mtvsrdm, "V2ULLiULLi", "")
BUILTIN(__builtin_altivec_mtvsrqm, "V1ULLLiULLi", "")
// P10 Vector Parallel Bits built-ins.
BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "")
BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "")
// P10 Vector String Isolate Built-ins.
BUILTIN(__builtin_altivec_vstribr, "V16cV16c", "")
BUILTIN(__builtin_altivec_vstribl, "V16cV16c", "")
BUILTIN(__builtin_altivec_vstrihr, "V8sV8s", "")
BUILTIN(__builtin_altivec_vstrihl, "V8sV8s", "")
BUILTIN(__builtin_altivec_vstribr_p, "iiV16c", "")
BUILTIN(__builtin_altivec_vstribl_p, "iiV16c", "")
BUILTIN(__builtin_altivec_vstrihr_p, "iiV8s", "")
BUILTIN(__builtin_altivec_vstrihl_p, "iiV8s", "")
// P10 Vector Centrifuge built-in.
BUILTIN(__builtin_altivec_vcfuged, "V2ULLiV2ULLiV2ULLi", "")
@ -321,20 +404,36 @@ BUILTIN(__builtin_altivec_vsldbi, "V16UcV16UcV16UcIi", "")
BUILTIN(__builtin_altivec_vsrdbi, "V16UcV16UcV16UcIi", "")
// P10 Vector Insert built-ins.
BUILTIN(__builtin_altivec_vinsblx, "V16UcV16UcULLiULLi", "")
BUILTIN(__builtin_altivec_vinsbrx, "V16UcV16UcULLiULLi", "")
BUILTIN(__builtin_altivec_vinshlx, "V8UsV8UsULLiULLi", "")
BUILTIN(__builtin_altivec_vinshrx, "V8UsV8UsULLiULLi", "")
BUILTIN(__builtin_altivec_vinswlx, "V4UiV4UiULLiULLi", "")
BUILTIN(__builtin_altivec_vinswrx, "V4UiV4UiULLiULLi", "")
BUILTIN(__builtin_altivec_vinsblx, "V16UcV16UcUiUi", "")
BUILTIN(__builtin_altivec_vinsbrx, "V16UcV16UcUiUi", "")
BUILTIN(__builtin_altivec_vinshlx, "V8UsV8UsUiUi", "")
BUILTIN(__builtin_altivec_vinshrx, "V8UsV8UsUiUi", "")
BUILTIN(__builtin_altivec_vinswlx, "V4UiV4UiUiUi", "")
BUILTIN(__builtin_altivec_vinswrx, "V4UiV4UiUiUi", "")
BUILTIN(__builtin_altivec_vinsdlx, "V2ULLiV2ULLiULLiULLi", "")
BUILTIN(__builtin_altivec_vinsdrx, "V2ULLiV2ULLiULLiULLi", "")
BUILTIN(__builtin_altivec_vinsbvlx, "V16UcV16UcULLiV16Uc", "")
BUILTIN(__builtin_altivec_vinsbvrx, "V16UcV16UcULLiV16Uc", "")
BUILTIN(__builtin_altivec_vinshvlx, "V8UsV8UsULLiV8Us", "")
BUILTIN(__builtin_altivec_vinshvrx, "V8UsV8UsULLiV8Us", "")
BUILTIN(__builtin_altivec_vinswvlx, "V4UiV4UiULLiV4Ui", "")
BUILTIN(__builtin_altivec_vinswvrx, "V4UiV4UiULLiV4Ui", "")
BUILTIN(__builtin_altivec_vinsbvlx, "V16UcV16UcUiV16Uc", "")
BUILTIN(__builtin_altivec_vinsbvrx, "V16UcV16UcUiV16Uc", "")
BUILTIN(__builtin_altivec_vinshvlx, "V8UsV8UsUiV8Us", "")
BUILTIN(__builtin_altivec_vinshvrx, "V8UsV8UsUiV8Us", "")
BUILTIN(__builtin_altivec_vinswvlx, "V4UiV4UiUiV4Ui", "")
BUILTIN(__builtin_altivec_vinswvrx, "V4UiV4UiUiV4Ui", "")
BUILTIN(__builtin_altivec_vec_replace_elt, "V4UiV4UiUiIi", "t")
BUILTIN(__builtin_altivec_vec_replace_unaligned, "V4UiV4UiUiIi", "t")
// P10 Vector Extract built-ins.
BUILTIN(__builtin_altivec_vextdubvlx, "V2ULLiV16UcV16UcUi", "")
BUILTIN(__builtin_altivec_vextdubvrx, "V2ULLiV16UcV16UcUi", "")
BUILTIN(__builtin_altivec_vextduhvlx, "V2ULLiV8UsV8UsUi", "")
BUILTIN(__builtin_altivec_vextduhvrx, "V2ULLiV8UsV8UsUi", "")
BUILTIN(__builtin_altivec_vextduwvlx, "V2ULLiV4UiV4UiUi", "")
BUILTIN(__builtin_altivec_vextduwvrx, "V2ULLiV4UiV4UiUi", "")
BUILTIN(__builtin_altivec_vextddvlx, "V2ULLiV2ULLiV2ULLiUi", "")
BUILTIN(__builtin_altivec_vextddvrx, "V2ULLiV2ULLiV2ULLiUi", "")
// P10 Vector rotate built-ins.
BUILTIN(__builtin_altivec_vrlqmi, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi", "")
BUILTIN(__builtin_altivec_vrlqnm, "V1ULLLiV1ULLLiV1ULLLi", "")
// VSX built-ins.
@ -455,6 +554,9 @@ BUILTIN(__builtin_vsx_xvcvdpsp, "V4fV2d", "")
BUILTIN(__builtin_vsx_xvcvsphp, "V4fV4f", "")
BUILTIN(__builtin_vsx_xvcvhpsp, "V4fV8Us", "")
BUILTIN(__builtin_vsx_xvcvspbf16, "V16UcV16Uc", "")
BUILTIN(__builtin_vsx_xvcvbf16spn, "V16UcV16Uc", "")
// Vector Test Data Class builtins
BUILTIN(__builtin_vsx_xvtstdcdp, "V2ULLiV2dIi", "")
BUILTIN(__builtin_vsx_xvtstdcsp, "V4UiV4fIi", "")
@ -467,7 +569,12 @@ BUILTIN(__builtin_vsx_xxsldwi, "v.", "t")
BUILTIN(__builtin_vsx_xxeval, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "")
BUILTIN(__builtin_vsx_xvtlsbb, "iV16Ucb", "")
BUILTIN(__builtin_vsx_xvtlsbb, "iV16UcUi", "")
BUILTIN(__builtin_vsx_xvtdivdp, "iV2dV2d", "")
BUILTIN(__builtin_vsx_xvtdivsp, "iV4fV4f", "")
BUILTIN(__builtin_vsx_xvtsqrtdp, "iV2d", "")
BUILTIN(__builtin_vsx_xvtsqrtsp, "iV4f", "")
// P10 Vector Permute Extended built-in.
BUILTIN(__builtin_vsx_xxpermx, "V16UcV16UcV16UcV16UcIi", "")
@ -532,6 +639,11 @@ BUILTIN(__builtin_cfuged, "ULLiULLiULLi", "")
BUILTIN(__builtin_cntlzdm, "ULLiULLiULLi", "")
BUILTIN(__builtin_cnttzdm, "ULLiULLiULLi", "")
// Generate random number
BUILTIN(__builtin_darn, "LLi", "")
BUILTIN(__builtin_darn_raw, "LLi", "")
BUILTIN(__builtin_darn_32, "i", "")
// Vector int128 (un)pack
BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "")
BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")
@ -539,9 +651,103 @@ BUILTIN(__builtin_pack_vector_int128, "V1LLLiULLiULLi", "")
// Set the floating point rounding mode
BUILTIN(__builtin_setrnd, "di", "")
// Get content from current FPSCR
BUILTIN(__builtin_readflm, "d", "")
// Set content of FPSCR, and return its content before update
BUILTIN(__builtin_setflm, "dd", "")
// Cache built-ins
BUILTIN(__builtin_dcbf, "vvC*", "")
// Built-ins requiring custom code generation.
// Because these built-ins rely on target-dependent types and to avoid pervasive
// change, they are type checked manually in Sema using custom type descriptors.
// The first argument of the CUSTOM_BUILTIN macro is the name of the built-in
// with its prefix, the second argument specifies the type of the function
// (result value, then each argument) as follows:
// i -> Unsigned integer followed by the greatest possible value for that
// argument or 0 if no constraint on the value.
// (e.g. i15 for a 4-bits value)
// V -> Vector type used with MMA builtins (vector unsigned char)
// W -> PPC Vector type followed by the size of the vector type.
// (e.g. W512 for __vector_quad)
// any other descriptor -> Fall back to generic type descriptor decoding.
// The 'C' suffix can be used as a suffix to specify the const type.
// The '*' suffix can be used as a suffix to specify a pointer to a type.
// The third argument is set to true if the builtin accumulates its result into
// its given accumulator.
CUSTOM_BUILTIN(vsx_lxvp, "W256SLLiW256C*", false)
CUSTOM_BUILTIN(vsx_stxvp, "vW256SLLiW256C*", false)
CUSTOM_BUILTIN(vsx_assemble_pair, "vW256*VV", false)
CUSTOM_BUILTIN(vsx_disassemble_pair, "vv*W256*", false)
CUSTOM_BUILTIN(mma_assemble_acc, "vW512*VVVV", false)
CUSTOM_BUILTIN(mma_disassemble_acc, "vv*W512*", false)
CUSTOM_BUILTIN(mma_xxmtacc, "vW512*", true)
CUSTOM_BUILTIN(mma_xxmfacc, "vW512*", true)
CUSTOM_BUILTIN(mma_xxsetaccz, "vW512*", false)
CUSTOM_BUILTIN(mma_xvi4ger8, "vW512*VV", false)
CUSTOM_BUILTIN(mma_xvi8ger4, "vW512*VV", false)
CUSTOM_BUILTIN(mma_xvi16ger2, "vW512*VV", false)
CUSTOM_BUILTIN(mma_xvi16ger2s, "vW512*VV", false)
CUSTOM_BUILTIN(mma_xvf16ger2, "vW512*VV", false)
CUSTOM_BUILTIN(mma_xvf32ger, "vW512*VV", false)
CUSTOM_BUILTIN(mma_xvf64ger, "vW512*W256V", false)
CUSTOM_BUILTIN(mma_pmxvi4ger8, "vW512*VVi15i15i255", false)
CUSTOM_BUILTIN(mma_pmxvi8ger4, "vW512*VVi15i15i15", false)
CUSTOM_BUILTIN(mma_pmxvi16ger2, "vW512*VVi15i15i3", false)
CUSTOM_BUILTIN(mma_pmxvi16ger2s, "vW512*VVi15i15i3", false)
CUSTOM_BUILTIN(mma_pmxvf16ger2, "vW512*VVi15i15i3", false)
CUSTOM_BUILTIN(mma_pmxvf32ger, "vW512*VVi15i15", false)
CUSTOM_BUILTIN(mma_pmxvf64ger, "vW512*W256Vi15i3", false)
CUSTOM_BUILTIN(mma_xvi4ger8pp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvi8ger4pp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvi8ger4spp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvi16ger2pp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvi16ger2spp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_pmxvi4ger8pp, "vW512*VVi15i15i255", true)
CUSTOM_BUILTIN(mma_pmxvi8ger4pp, "vW512*VVi15i15i15", true)
CUSTOM_BUILTIN(mma_pmxvi8ger4spp, "vW512*VVi15i15i15", true)
CUSTOM_BUILTIN(mma_pmxvi16ger2pp, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_pmxvi16ger2spp, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_xvf16ger2pp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvf16ger2pn, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvf16ger2np, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvf16ger2nn, "vW512*VV", true)
CUSTOM_BUILTIN(mma_pmxvf16ger2pp, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_pmxvf16ger2pn, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_pmxvf16ger2np, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_pmxvf16ger2nn, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_xvf32gerpp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvf32gerpn, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvf32gernp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvf32gernn, "vW512*VV", true)
CUSTOM_BUILTIN(mma_pmxvf32gerpp, "vW512*VVi15i15", true)
CUSTOM_BUILTIN(mma_pmxvf32gerpn, "vW512*VVi15i15", true)
CUSTOM_BUILTIN(mma_pmxvf32gernp, "vW512*VVi15i15", true)
CUSTOM_BUILTIN(mma_pmxvf32gernn, "vW512*VVi15i15", true)
CUSTOM_BUILTIN(mma_xvf64gerpp, "vW512*W256V", true)
CUSTOM_BUILTIN(mma_xvf64gerpn, "vW512*W256V", true)
CUSTOM_BUILTIN(mma_xvf64gernp, "vW512*W256V", true)
CUSTOM_BUILTIN(mma_xvf64gernn, "vW512*W256V", true)
CUSTOM_BUILTIN(mma_pmxvf64gerpp, "vW512*W256Vi15i3", true)
CUSTOM_BUILTIN(mma_pmxvf64gerpn, "vW512*W256Vi15i3", true)
CUSTOM_BUILTIN(mma_pmxvf64gernp, "vW512*W256Vi15i3", true)
CUSTOM_BUILTIN(mma_pmxvf64gernn, "vW512*W256Vi15i3", true)
CUSTOM_BUILTIN(mma_xvbf16ger2, "vW512*VV", false)
CUSTOM_BUILTIN(mma_pmxvbf16ger2, "vW512*VVi15i15i3", false)
CUSTOM_BUILTIN(mma_xvbf16ger2pp, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvbf16ger2pn, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvbf16ger2np, "vW512*VV", true)
CUSTOM_BUILTIN(mma_xvbf16ger2nn, "vW512*VV", true)
CUSTOM_BUILTIN(mma_pmxvbf16ger2pp, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_pmxvbf16ger2pn, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_pmxvbf16ger2np, "vW512*VVi15i15i3", true)
CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true)
// FIXME: Obviously incomplete.
#undef BUILTIN
#undef CUSTOM_BUILTIN

View File

@ -38,12 +38,12 @@ BUILTIN(__builtin_wasm_max_f64, "ddd", "nc")
// Exception handling builtins.
TARGET_BUILTIN(__builtin_wasm_throw, "vIUiv*", "r", "exception-handling")
TARGET_BUILTIN(__builtin_wasm_rethrow_in_catch, "v", "r", "exception-handling")
TARGET_BUILTIN(__builtin_wasm_rethrow, "v", "r", "exception-handling")
// Atomic wait and notify.
TARGET_BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n", "atomics")
TARGET_BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n", "atomics")
TARGET_BUILTIN(__builtin_wasm_atomic_notify, "Uii*Ui", "n", "atomics")
TARGET_BUILTIN(__builtin_wasm_memory_atomic_wait32, "ii*iLLi", "n", "atomics")
TARGET_BUILTIN(__builtin_wasm_memory_atomic_wait64, "iLLi*LLiLLi", "n", "atomics")
TARGET_BUILTIN(__builtin_wasm_memory_atomic_notify, "Uii*Ui", "n", "atomics")
// Trapping fp-to-int conversions
BUILTIN(__builtin_wasm_trunc_s_i32_f32, "if", "nc")
@ -66,69 +66,101 @@ TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc", "nontrappi
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc", "nontrapping-fptoint")
// SIMD builtins
TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16ScV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16ScIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16UcIUi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i16x8, "iV8sIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8UsIUi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_i32x4, "iV4iIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_f32x4, "fV4fIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16cV16cIii", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16ScV16ScIii", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_replace_lane_i16x8, "V8sV8sIii", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_replace_lane_i32x4, "V4iV4iIii", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_i8x16, "V16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_i8x16, "V16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_i16x8, "V8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_i32x4, "V4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_s_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_u_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_s_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_u_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_s_i8x16, "V16ScV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_s_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_u_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_s_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_u_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_s_i32x4, "V4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_u_i32x4, "V4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_min_u_i32x4, "V4UiV4UiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_s_i32x4, "V4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_u_i32x4, "V4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_max_u_i32x4, "V4UiV4UiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16cV16cV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_popcnt_i8x16, "V16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_q15mulr_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_low_i8x16_s_i16x8, "V8sV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_high_i8x16_s_i16x8, "V8sV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_low_i8x16_u_i16x8, "V8UsV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_high_i8x16_u_i16x8, "V8UsV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_low_i16x8_s_i32x4, "V4iV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_high_i16x8_s_i32x4, "V4iV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_low_i16x8_u_i32x4, "V4UiV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_high_i16x8_u_i32x4, "V4UiV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_low_i32x4_s_i64x2, "V2LLiV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_high_i32x4_s_i64x2, "V2LLiV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_low_i32x4_u_i64x2, "V2ULLiV4UiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extmul_high_i32x4_u_i64x2, "V2ULLiV4UiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extadd_pairwise_i8x16_s_i16x8, "V8sV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extadd_pairwise_i8x16_u_i16x8, "V8UsV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extadd_pairwise_i16x8_s_i32x4, "V4iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_extadd_pairwise_i16x8_u_i32x4, "V4UiV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_shuffle_v8x16, "V16cV16cV16cIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_signselect_i8x16, "V16ScV16ScV16ScV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_signselect_i16x8, "V8sV8sV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_signselect_i32x4, "V4iV4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_signselect_i64x2, "V2LLiV2LLiV2LLiV2LLi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_shuffle_v8x16, "V16ScV16ScV16ScIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_any_true_i16x8, "iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_any_true_i32x4, "iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_any_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
TARGET_BUILTIN(__builtin_wasm_all_true_i8x16, "iV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_all_true_i8x16, "iV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
TARGET_BUILTIN(__builtin_wasm_bitmask_i8x16, "iV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_bitmask_i8x16, "iV16Sc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_bitmask_i16x8, "iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_bitmask_i32x4, "iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_bitmask_i64x2, "iV2LLi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "simd128")
@ -164,19 +196,39 @@ TARGET_BUILTIN(__builtin_wasm_qfms_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-s
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_s_i8x16_i16x8, "V16cV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_u_i8x16_i16x8, "V16cV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_s_i8x16_i16x8, "V16ScV8sV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_u_i8x16_i16x8, "V16UcV8UsV8Us", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_s_i16x8_i32x4, "V8sV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_u_i16x8_i32x4, "V8sV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_narrow_u_i16x8_i32x4, "V8UsV4UiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_low_s_i16x8_i8x16, "V8sV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_high_s_i16x8_i8x16, "V8sV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_low_u_i16x8_i8x16, "V8sV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_high_u_i16x8_i8x16, "V8sV16c", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_low_s_i32x4_i16x8, "V4iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_high_s_i32x4_i16x8, "V4iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_low_u_i32x4_i16x8, "V4iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_high_u_i32x4_i16x8, "V4iV8s", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_low_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_high_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_low_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_high_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_convert_low_s_i32x4_f64x2, "V2dV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_convert_low_u_i32x4_f64x2, "V2dV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_demote_zero_f64x2_f32x4, "V4fV2d", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_promote_low_f32x4_f64x2, "V2dV4f", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_load32_zero, "V4ii*", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_load64_zero, "V2LLiLLi*", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_load8_lane, "V16ScSc*V16ScIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_load16_lane, "V8ss*V8sIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_load32_lane, "V4ii*V4iIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_load64_lane, "V2LLiLLi*V2LLiIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_store8_lane, "vSc*V16ScIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_store16_lane, "vs*V8sIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_store32_lane, "vi*V4iIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_store64_lane, "vLLi*V2LLiIi", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_eq_i64x2, "V2LLiV2LLiV2LLi", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_prefetch_t, "vv*", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_prefetch_nt, "vv*", "n", "simd128")
#undef BUILTIN
#undef TARGET_BUILTIN

View File

@ -960,17 +960,17 @@ TARGET_BUILTIN(__builtin_ia32_alignq256, "V4OiV4OiV4OiIi", "ncV:256:", "avx512vl
TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_vpdpbusd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpbusds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssd128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssd256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssd512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds128, "V4iV4iV4iV4i", "ncV:128:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds256, "V8iV8iV8iV8i", "ncV:256:", "avx512vl,avx512vnni|avxvnni")
TARGET_BUILTIN(__builtin_ia32_vpdpwssds512, "V16iV16iV16iV16i", "ncV:512:", "avx512vnni")
TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2dvC*V2OiUcIi", "nV:128:", "avx512vl")
@ -1871,6 +1871,28 @@ TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "ncV:512:", "avx512f"
TARGET_BUILTIN(__builtin_ia32_selectss_128, "V4fUcV4fV4f", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_selectsd_128, "V2dUcV2dV2d", "ncV:128:", "avx512f")
// generic reduction intrinsics
TARGET_BUILTIN(__builtin_ia32_reduce_add_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_add_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_and_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_and_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_fadd_pd512, "ddV8d", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_fadd_ps512, "ffV16f", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_fmul_pd512, "ddV8d", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_fmul_ps512, "ffV16f", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_mul_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_mul_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_or_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_or_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smax_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smax_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smin_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_smin_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umax_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umax_q512, "OiV8Oi", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umin_d512, "iV16i", "ncV:512:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_reduce_umin_q512, "OiV8Oi", "ncV:512:", "avx512f")
// MONITORX/MWAITX
TARGET_BUILTIN(__builtin_ia32_monitorx, "vvC*UiUi", "n", "mwaitx")
TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "n", "mwaitx")
@ -1900,6 +1922,19 @@ TARGET_BUILTIN(__builtin_ia32_invpcid, "vUiv*", "nc", "invpcid")
TARGET_BUILTIN(__builtin_ia32_enqcmd, "Ucv*vC*", "n", "enqcmd")
TARGET_BUILTIN(__builtin_ia32_enqcmds, "Ucv*vC*", "n", "enqcmd")
// KEY LOCKER
TARGET_BUILTIN(__builtin_ia32_loadiwkey, "vV2OiV2OiV2OiUi", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_encodekey128_u32, "UiUiV2Oiv*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_encodekey256_u32, "UiUiV2OiV2Oiv*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesenc128kl_u8, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesenc256kl_u8, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesdec128kl_u8, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesdec256kl_u8, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesencwide128kl_u8, "UcV2Oi*V2OiC*vC*", "nV:128:", "kl,widekl")
TARGET_BUILTIN(__builtin_ia32_aesencwide256kl_u8, "UcV2Oi*V2OiC*vC*", "nV:128:", "kl,widekl")
TARGET_BUILTIN(__builtin_ia32_aesdecwide128kl_u8, "UcV2Oi*V2OiC*vC*", "nV:128:", "kl,widekl")
TARGET_BUILTIN(__builtin_ia32_aesdecwide256kl_u8, "UcV2Oi*V2OiC*vC*", "nV:128:", "kl,widekl")
// SERIALIZE
TARGET_BUILTIN(__builtin_ia32_serialize, "v", "n", "serialize")

View File

@ -94,6 +94,17 @@ TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dUOiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fUOiIi", "ncV:128:", "avx512f")
TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri")
// UINTR
TARGET_BUILTIN(__builtin_ia32_clui, "v", "n", "uintr")
TARGET_BUILTIN(__builtin_ia32_stui, "v", "n", "uintr")
TARGET_BUILTIN(__builtin_ia32_testui, "Uc", "n", "uintr")
TARGET_BUILTIN(__builtin_ia32_senduipi, "vUWi", "n", "uintr")
// AMX internal builtin
TARGET_BUILTIN(__builtin_ia32_tileloadd64_internal, "V256iUsUsvC*z", "n", "amx-tile")
TARGET_BUILTIN(__builtin_ia32_tdpbssd_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-int8")
TARGET_BUILTIN(__builtin_ia32_tilestored64_internal, "vUsUsv*zV256i", "n", "amx-tile")
TARGET_BUILTIN(__builtin_ia32_tilezero_internal, "V256iUsUs", "n", "amx-tile")
// AMX
TARGET_BUILTIN(__builtin_ia32_tile_loadconfig, "vvC*", "n", "amx-tile")
TARGET_BUILTIN(__builtin_ia32_tile_storeconfig, "vvC*", "n", "amx-tile")

View File

@ -32,11 +32,14 @@ ENUM_CODEGENOPT(CompressDebugSections, llvm::DebugCompressionType, 2,
llvm::DebugCompressionType::None)
CODEGENOPT(RelaxELFRelocations, 1, 0) ///< -Wa,--mrelax-relocations
CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm.
CODEGENOPT(Dwarf64 , 1, 0) ///< -gdwarf64.
CODEGENOPT(Dwarf32 , 1, 1) ///< -gdwarf32.
CODEGENOPT(PreserveAsmComments, 1, 1) ///< -dA, -fno-preserve-as-comments.
CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new
CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink
CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
CODEGENOPT(IgnoreXCOFFVisibility , 1, 0) ///< -mignore-xcoff-visibility
CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks
CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard
CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors.
@ -48,11 +51,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(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory.
CODEGENOPT(DiscardValueNames , 1, 0) ///< Discard Value Names from the IR (LLVMContext flag)
CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing.
CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get
///< the pristine IR generated by the
///< frontend.
@ -60,8 +63,7 @@ CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers
CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optnone at O0
CODEGENOPT(ExperimentalStrictFloatingPoint, 1, 0) ///< Enables the new, experimental
///< strict floating point.
CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental
///< pass manager.
CODEGENOPT(LegacyPassManager, 1, 0) ///< Use the legacy pass manager.
CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
///< pass manager.
CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled.
@ -120,6 +122,12 @@ CODEGENOPT(XRayOmitFunctionIndex , 1, 0)
///< XRay instrumentation.
VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200)
///< Only instrument 1 in N functions, by dividing functions into N total groups and
///< instrumenting only the specified group at a time. Group numbers start at 0
///< and end at N-1.
VALUE_CODEGENOPT(XRayTotalFunctionGroups, 32, 1)
VALUE_CODEGENOPT(XRaySelectedFunctionGroup, 32, 0)
VALUE_CODEGENOPT(PatchableFunctionEntryCount , 32, 0) ///< Number of NOPs at function entry
VALUE_CODEGENOPT(PatchableFunctionEntryOffset , 32, 0)
@ -161,6 +169,7 @@ CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enable
CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined.
CODEGENOPT(CorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt
CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names.
CODEGENOPT(SplitMachineFunctions, 1, 0) ///< Split machine functions using profile information.
/// When false, this attempts to generate code as if the result of an
/// overflowing conversion matches the overflowing behavior of a target's native
@ -177,6 +186,7 @@ CODEGENOPT(ObjCConvertMessagesToRuntimeCalls , 1, 1)
VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic
/// Choose profile instrumenation kind or no instrumentation.
ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone)
/// Choose profile kind for PGO use compilation.
@ -243,7 +253,8 @@ CODEGENOPT(SpeculativeLoadHardening, 1, 0) ///< Enable speculative load hardenin
CODEGENOPT(FineGrainedBitfieldAccesses, 1, 0) ///< Enable fine-grained bitfield accesses.
CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition.
CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers
CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled.
CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report or -ftime-report= is enabled.
CODEGENOPT(TimePassesPerRun , 1, 0) ///< Set when -ftime-report=per-pass-run is enabled.
CODEGENOPT(TimeTrace , 1, 0) ///< Set when -ftime-trace is enabled.
VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (in microseconds),
///< traced by time profiler
@ -288,7 +299,6 @@ CODEGENOPT(DebugFwdTemplateParams, 1, 0) ///< Whether to emit complete
///< template parameter descriptions in
///< forward declarations (versus just
///< including them in the name).
CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
CODEGENOPT(WholeProgramVTables, 1, 0) ///< Whether to apply whole-program
@ -313,7 +323,7 @@ VALUE_CODEGENOPT(SmallDataLimit, 32, 0)
VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
/// The kind of generated debug info.
ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 3, codegenoptions::NoDebugInfo)
ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 4, codegenoptions::NoDebugInfo)
/// Whether to generate macro debug info.
CODEGENOPT(MacroDebugInfo, 1, 0)
@ -326,6 +336,9 @@ ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 2,
/// emitted.
VALUE_CODEGENOPT(DwarfVersion, 3, 0)
/// Whether to use experimental new variable location tracking.
CODEGENOPT(ValueTrackingVariableLocations, 1, 0)
/// Whether we should emit CodeView debug information. It's possible to emit
/// CodeView and DWARF into the same object.
CODEGENOPT(EmitCodeView, 1, 0)
@ -337,7 +350,7 @@ CODEGENOPT(CodeViewGHash, 1, 0)
ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
// Vector functions library to use.
ENUM_CODEGENOPT(VecLib, VectorLibrary, 2, NoLibrary)
ENUM_CODEGENOPT(VecLib, VectorLibrary, 3, NoLibrary)
/// The default TLS model to use.
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
@ -345,6 +358,9 @@ ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
/// Bit size of immediate TLS offsets (0 == use the default).
VALUE_CODEGENOPT(TLSSize, 8, 0)
/// The default stack protector guard offset to use.
VALUE_CODEGENOPT(StackProtectorGuardOffset, 32, (unsigned)-1)
/// Number of path components to strip when emitting checks. (0 == full
/// filename)
VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
@ -352,12 +368,8 @@ VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
/// Whether to report the hotness of the code region for optimization remarks.
CODEGENOPT(DiagnosticsWithHotness, 1, 0)
/// The minimum hotness value a diagnostic needs in order to be included in
/// optimization diagnostics.
VALUE_CODEGENOPT(DiagnosticsHotnessThreshold, 32, 0)
/// Whether copy relocations support is available when building as PIE.
CODEGENOPT(PIECopyRelocations, 1, 0)
/// Whether to use direct access relocations (instead of GOT) to reference external data symbols.
CODEGENOPT(DirectAccessExternalData, 1, 0)
/// Whether we should use the undefined behaviour optimization for control flow
/// paths that reach the end of a function without executing a required return.
@ -366,6 +378,9 @@ CODEGENOPT(StrictReturn, 1, 1)
/// Whether emit extra debug info for sample pgo profile collection.
CODEGENOPT(DebugInfoForProfiling, 1, 0)
/// Whether emit pseudo probes for sample pgo profile collection.
CODEGENOPT(PseudoProbeForProfiling, 1, 0)
/// Whether 3-component vector type is preserved.
CODEGENOPT(PreserveVec3Type, 1, 0)
@ -389,9 +404,16 @@ CODEGENOPT(Addrsig, 1, 0)
/// Whether to emit unused static constants.
CODEGENOPT(KeepStaticConsts, 1, 0)
/// Whether to not follow the AAPCS that enforce at least one read before storing to a volatile bitfield
/// Whether to follow the AAPCS enforcing at least one read before storing to a volatile bitfield
CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0)
/// Assume that by-value parameters do not alias any other values.
CODEGENOPT(PassByValueIsNoAlias, 1, 0)
/// Whether to not follow the AAPCS that enforces volatile bit-field access width to be
/// according to the field declaring type width.
CODEGENOPT(AAPCSBitfieldWidth, 1, 1)
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
#undef VALUE_CODEGENOPT

View File

@ -30,6 +30,8 @@ namespace clang {
/// Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure
/// that this large collection of bitfields is a trivial class type.
class CodeGenOptionsBase {
friend class CompilerInvocation;
public:
#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits;
#define ENUM_CODEGENOPT(Name, Type, Bits, Default)
@ -54,11 +56,11 @@ class CodeGenOptions : public CodeGenOptionsBase {
enum VectorLibrary {
NoLibrary, // Don't use any vector library.
Accelerate, // Use the Accelerate framework.
LIBMVEC, // GLIBC vector math library.
MASSV, // IBM MASS vector library.
SVML // Intel short vector math library.
};
enum ObjCDispatchMethodKind {
Legacy = 0,
NonLegacy = 1,
@ -126,6 +128,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
// "none": Disable sections/labels for basic blocks.
std::string BBSections;
// If set, override the default value of MCAsmInfo::BinutilsVersion. If
// DisableIntegratedAS is specified, the assembly output will consider GNU as
// support. "none" means that all ELF features can be used, regardless of
// binutils support.
std::string BinutilsVersion;
enum class FramePointerKind {
None, // Omit all frame pointers.
NonLeaf, // Keep non-leaf frame pointers.
@ -167,6 +175,7 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::string RecordCommandLine;
std::map<std::string, std::string> DebugPrefixMap;
std::map<std::string, std::string> ProfilePrefixMap;
/// The ABI to use for passing floating point arguments.
std::string FloatABI;
@ -211,9 +220,6 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// The name of the relocation model to use.
llvm::Reloc::Model RelocationModel;
/// The thread model to use
std::string ThreadModel;
/// If not an empty string, trap intrinsics are lowered to calls to this
/// function instead of to trap instructions.
std::string TrapFuncName;
@ -231,6 +237,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// Name of the profile file to use with -fprofile-sample-use.
std::string SampleProfileFile;
/// Name of the profile file to use as output for with -fmemory-profile.
std::string MemoryProfileOutput;
/// Name of the profile file to use as input for -fprofile-instr-use
std::string ProfileInstrumentUsePath;
@ -327,6 +336,15 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// by sanitizer coverage pass.
std::vector<std::string> SanitizeCoverageAllowlistFiles;
/// The guard style used for stack protector to get a initial value, this
/// value usually be gotten from TLS or get from __stack_chk_guard, or some
/// other styles we may implement in the future.
std::string StackProtectorGuard;
/// The TLS base register when StackProtectorGuard is "tls".
/// On x86 this can be "fs" or "gs".
std::string StackProtectorGuardReg;
/// Path to blocklist file specifying which objects
/// (files, functions) listed for instrumentation by sanitizer
/// coverage pass should actually not be instrumented.
@ -337,6 +355,21 @@ class CodeGenOptions : public CodeGenOptionsBase {
const char *Argv0 = nullptr;
ArrayRef<const char *> CommandLineArgs;
/// The minimum hotness value a diagnostic needs in order to be included in
/// optimization diagnostics.
///
/// The threshold is an Optional value, which maps to one of the 3 states:
/// 1. 0 => threshold disabled. All remarks will be printed.
/// 2. positive int => manual threshold by user. Remarks with hotness exceed
/// threshold will be printed.
/// 3. None => 'auto' threshold by user. The actual value is not
/// available at command line, but will be synced with
/// hotness threshold from profile summary during
/// compilation.
///
/// If threshold option is not specified, it is disabled by default.
Optional<uint64_t> DiagnosticsHotnessThreshold = 0;
public:
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
@ -388,6 +421,11 @@ class CodeGenOptions : public CodeGenOptionsBase {
bool hasReducedDebugInfo() const {
return getDebugInfo() >= codegenoptions::DebugInfoConstructor;
}
/// Check if maybe unused type info should be emitted.
bool hasMaybeUnusedDebugInfo() const {
return getDebugInfo() >= codegenoptions::UnusedTypeInfo;
}
};
} // end namespace clang

View File

@ -37,6 +37,7 @@ const char *CudaVersionToString(CudaVersion V);
CudaVersion CudaStringToVersion(const llvm::Twine &S);
enum class CudaArch {
UNUSED,
UNKNOWN,
SM_20,
SM_21,
@ -56,14 +57,17 @@ enum class CudaArch {
SM_80,
GFX600,
GFX601,
GFX602,
GFX700,
GFX701,
GFX702,
GFX703,
GFX704,
GFX705,
GFX801,
GFX802,
GFX803,
GFX805,
GFX810,
GFX900,
GFX902,
@ -71,10 +75,14 @@ enum class CudaArch {
GFX906,
GFX908,
GFX909,
GFX90c,
GFX1010,
GFX1011,
GFX1012,
GFX1030,
GFX1031,
GFX1032,
GFX1033,
LAST,
};

View File

@ -46,7 +46,11 @@ enum DebugInfoKind {
LimitedDebugInfo,
/// Generate complete debug info.
FullDebugInfo
FullDebugInfo,
/// Generate debug info for types that may be unused in the source
/// (-fno-eliminate-unused-debug-types).
UnusedTypeInfo,
};
} // end namespace codegenoptions

View File

@ -41,6 +41,7 @@ def Named : DeclNode<Decl, "named declarations", 1>;
def OMPDeclareReduction : DeclNode<Value>, DeclContext;
def OMPDeclareMapper : DeclNode<Value>, DeclContext;
def MSGuid : DeclNode<Value>;
def TemplateParamObject : DeclNode<Value>;
def Declarator : DeclNode<Value, "declarators", 1>;
def Field : DeclNode<Declarator, "non-static data members">;
def ObjCIvar : DeclNode<Field>;

View File

@ -144,6 +144,44 @@ class FixItHint {
}
};
struct DiagnosticStorage {
enum {
/// The maximum number of arguments we can hold. We
/// currently only support up to 10 arguments (%0-%9).
///
/// A single diagnostic with more than that almost certainly has to
/// be simplified anyway.
MaxArguments = 10
};
/// The number of entries in Arguments.
unsigned char NumDiagArgs = 0;
/// Specifies for each argument whether it is in DiagArgumentsStr
/// or in DiagArguments.
unsigned char DiagArgumentsKind[MaxArguments];
/// The values for the various substitution positions.
///
/// This is used when the argument is not an std::string. The specific value
/// is mangled into an intptr_t and the interpretation depends on exactly
/// what sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];
/// The values for the various substitution positions that have
/// string arguments.
std::string DiagArgumentsStr[MaxArguments];
/// The list of ranges added to this diagnostic.
SmallVector<CharSourceRange, 8> DiagRanges;
/// If valid, provides a hint with some code to insert, remove, or
/// modify at a particular position.
SmallVector<FixItHint, 6> FixItHints;
DiagnosticStorage() = default;
};
/// Concrete class used by the front-end to report problems and issues.
///
/// This massages the diagnostics (e.g. handling things like "report warnings
@ -928,38 +966,10 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// We currently only support up to 10 arguments (%0-%9). A single
/// diagnostic with more than that almost certainly has to be simplified
/// anyway.
MaxArguments = 10,
MaxArguments = DiagnosticStorage::MaxArguments,
};
/// The number of entries in Arguments.
signed char NumDiagArgs;
/// Specifies whether an argument is in DiagArgumentsStr or
/// in DiagArguments.
///
/// This is an array of ArgumentKind::ArgumentKind enum values, one for each
/// argument.
unsigned char DiagArgumentsKind[MaxArguments];
/// Holds the values of each string argument for the current
/// diagnostic.
///
/// This is only used when the corresponding ArgumentKind is ak_std_string.
std::string DiagArgumentsStr[MaxArguments];
/// The values for the various substitution positions.
///
/// This is used when the argument is not an std::string. The specific
/// value is mangled into an intptr_t and the interpretation depends on
/// exactly what sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];
/// The list of ranges added to this diagnostic.
SmallVector<CharSourceRange, 8> DiagRanges;
/// If valid, provides a hint with some code to insert, remove,
/// or modify at a particular position.
SmallVector<FixItHint, 8> DiagFixItHints;
DiagnosticStorage DiagStorage;
DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
bool isPragma = L.isValid();
@ -1043,6 +1053,156 @@ class DiagnosticErrorTrap {
}
};
/// The streaming interface shared between DiagnosticBuilder and
/// PartialDiagnostic. This class is not intended to be constructed directly
/// but only as base class of DiagnosticBuilder and PartialDiagnostic builder.
///
/// Any new type of argument accepted by DiagnosticBuilder and PartialDiagnostic
/// should be implemented as a '<<' operator of StreamingDiagnostic, e.g.
///
/// const StreamingDiagnostic&
/// operator<<(const StreamingDiagnostic&, NewArgType);
///
class StreamingDiagnostic {
public:
/// An allocator for DiagnosticStorage objects, which uses a small cache to
/// objects, used to reduce malloc()/free() traffic for partial diagnostics.
class DiagStorageAllocator {
static const unsigned NumCached = 16;
DiagnosticStorage Cached[NumCached];
DiagnosticStorage *FreeList[NumCached];
unsigned NumFreeListEntries;
public:
DiagStorageAllocator();
~DiagStorageAllocator();
/// Allocate new storage.
DiagnosticStorage *Allocate() {
if (NumFreeListEntries == 0)
return new DiagnosticStorage;
DiagnosticStorage *Result = FreeList[--NumFreeListEntries];
Result->NumDiagArgs = 0;
Result->DiagRanges.clear();
Result->FixItHints.clear();
return Result;
}
/// Free the given storage object.
void Deallocate(DiagnosticStorage *S) {
if (S >= Cached && S <= Cached + NumCached) {
FreeList[NumFreeListEntries++] = S;
return;
}
delete S;
}
};
protected:
mutable DiagnosticStorage *DiagStorage = nullptr;
/// Allocator used to allocate storage for this diagnostic.
DiagStorageAllocator *Allocator = nullptr;
public:
/// Retrieve storage for this particular diagnostic.
DiagnosticStorage *getStorage() const {
if (DiagStorage)
return DiagStorage;
assert(Allocator);
DiagStorage = Allocator->Allocate();
return DiagStorage;
}
void freeStorage() {
if (!DiagStorage)
return;
// The hot path for PartialDiagnostic is when we just used it to wrap an ID
// (typically so we have the flexibility of passing a more complex
// diagnostic into the callee, but that does not commonly occur).
//
// Split this out into a slow function for silly compilers (*cough*) which
// can't do decent partial inlining.
freeStorageSlow();
}
void freeStorageSlow() {
if (!Allocator)
return;
Allocator->Deallocate(DiagStorage);
DiagStorage = nullptr;
}
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
if (!DiagStorage)
DiagStorage = getStorage();
assert(DiagStorage->NumDiagArgs < DiagnosticStorage::MaxArguments &&
"Too many arguments to diagnostic!");
DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
}
void AddString(StringRef V) const {
if (!DiagStorage)
DiagStorage = getStorage();
assert(DiagStorage->NumDiagArgs < DiagnosticStorage::MaxArguments &&
"Too many arguments to diagnostic!");
DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] =
DiagnosticsEngine::ak_std_string;
DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = std::string(V);
}
void AddSourceRange(const CharSourceRange &R) const {
if (!DiagStorage)
DiagStorage = getStorage();
DiagStorage->DiagRanges.push_back(R);
}
void AddFixItHint(const FixItHint &Hint) const {
if (Hint.isNull())
return;
if (!DiagStorage)
DiagStorage = getStorage();
DiagStorage->FixItHints.push_back(Hint);
}
/// Conversion of StreamingDiagnostic to bool always returns \c true.
///
/// This allows is to be used in boolean error contexts (where \c true is
/// used to indicate that an error has occurred), like:
/// \code
/// return Diag(...);
/// \endcode
operator bool() const { return true; }
protected:
StreamingDiagnostic() = default;
/// Construct with an external storage not owned by itself. The allocator
/// is a null pointer in this case.
explicit StreamingDiagnostic(DiagnosticStorage *Storage)
: DiagStorage(Storage) {}
/// Construct with a storage allocator which will manage the storage. The
/// allocator is not a null pointer in this case.
explicit StreamingDiagnostic(DiagStorageAllocator &Alloc)
: Allocator(&Alloc) {}
StreamingDiagnostic(const StreamingDiagnostic &Diag) = default;
StreamingDiagnostic(StreamingDiagnostic &&Diag) = default;
~StreamingDiagnostic() { freeStorage(); }
};
//===----------------------------------------------------------------------===//
// DiagnosticBuilder
//===----------------------------------------------------------------------===//
@ -1059,12 +1219,11 @@ class DiagnosticErrorTrap {
/// This ensures that compilers with somewhat reasonable optimizers will promote
/// the common fields to registers, eliminating increments of the NumArgs field,
/// for example.
class DiagnosticBuilder {
class DiagnosticBuilder : public StreamingDiagnostic {
friend class DiagnosticsEngine;
friend class PartialDiagnostic;
mutable DiagnosticsEngine *DiagObj = nullptr;
mutable unsigned NumArgs = 0;
/// Status variable indicating if this diagnostic is still active.
///
@ -1080,17 +1239,17 @@ class DiagnosticBuilder {
DiagnosticBuilder() = default;
explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
: DiagObj(diagObj), IsActive(true) {
: StreamingDiagnostic(&diagObj->DiagStorage), DiagObj(diagObj),
IsActive(true) {
assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
diagObj->DiagRanges.clear();
diagObj->DiagFixItHints.clear();
assert(DiagStorage &&
"DiagnosticBuilder requires a valid DiagnosticStorage!");
DiagStorage->NumDiagArgs = 0;
DiagStorage->DiagRanges.clear();
DiagStorage->FixItHints.clear();
}
protected:
void FlushCounts() {
DiagObj->NumDiagArgs = NumArgs;
}
/// Clear out the current diagnostic.
void Clear() const {
DiagObj = nullptr;
@ -1113,10 +1272,6 @@ class DiagnosticBuilder {
// (or by a subclass, as in SemaDiagnosticBuilder).
if (!isActive()) return false;
// When emitting diagnostics, we set the final argument count into
// the DiagnosticsEngine object.
FlushCounts();
// Process the diagnostic.
bool Result = DiagObj->EmitCurrentDiagnostic(IsForceEmit);
@ -1129,20 +1284,37 @@ class DiagnosticBuilder {
public:
/// Copy constructor. When copied, this "takes" the diagnostic info from the
/// input and neuters it.
DiagnosticBuilder(const DiagnosticBuilder &D) {
DiagnosticBuilder(const DiagnosticBuilder &D) : StreamingDiagnostic() {
DiagObj = D.DiagObj;
DiagStorage = D.DiagStorage;
IsActive = D.IsActive;
IsForceEmit = D.IsForceEmit;
D.Clear();
NumArgs = D.NumArgs;
}
template <typename T> const DiagnosticBuilder &operator<<(const T &V) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
const StreamingDiagnostic &DB = *this;
DB << V;
return *this;
}
// It is necessary to limit this to rvalue reference to avoid calling this
// function with a bitfield lvalue argument since non-const reference to
// bitfield is not allowed.
template <typename T, typename = typename std::enable_if<
!std::is_lvalue_reference<T>::value>::type>
const DiagnosticBuilder &operator<<(T &&V) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
const StreamingDiagnostic &DB = *this;
DB << std::move(V);
return *this;
}
DiagnosticBuilder &operator=(const DiagnosticBuilder &) = delete;
/// Emits the diagnostic.
~DiagnosticBuilder() {
Emit();
}
~DiagnosticBuilder() { Emit(); }
/// Forces the diagnostic to be emitted.
const DiagnosticBuilder &setForceEmit() const {
@ -1150,42 +1322,6 @@ class DiagnosticBuilder {
return *this;
}
/// Conversion of DiagnosticBuilder to bool always returns \c true.
///
/// This allows is to be used in boolean error contexts (where \c true is
/// used to indicate that an error has occurred), like:
/// \code
/// return Diag(...);
/// \endcode
operator bool() const { return true; }
void AddString(StringRef S) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
"Too many arguments to diagnostic!");
DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
DiagObj->DiagArgumentsStr[NumArgs++] = std::string(S);
}
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
"Too many arguments to diagnostic!");
DiagObj->DiagArgumentsKind[NumArgs] = Kind;
DiagObj->DiagArgumentsVal[NumArgs++] = V;
}
void AddSourceRange(const CharSourceRange &R) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
DiagObj->DiagRanges.push_back(R);
}
void AddFixItHint(const FixItHint &Hint) const {
assert(isActive() && "Clients must not add to cleared diagnostic!");
if (!Hint.isNull())
DiagObj->DiagFixItHints.push_back(Hint);
}
void addFlagValue(StringRef V) const { DiagObj->FlagValue = std::string(V); }
};
@ -1205,20 +1341,21 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
StringRef S) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
StringRef S) {
DB.AddString(S);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const char *Str) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const char *Str) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str),
DiagnosticsEngine::ak_c_string);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
int I) {
DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
return DB;
}
@ -1226,26 +1363,27 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) {
// We use enable_if here to prevent that this overload is selected for
// pointers or other arguments that are implicitly convertible to bool.
template <typename T>
inline std::enable_if_t<std::is_same<T, bool>::value, const DiagnosticBuilder &>
operator<<(const DiagnosticBuilder &DB, T I) {
inline std::enable_if_t<std::is_same<T, bool>::value,
const StreamingDiagnostic &>
operator<<(const StreamingDiagnostic &DB, T I) {
DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
unsigned I) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
unsigned I) {
DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
tok::TokenKind I) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
tok::TokenKind I) {
DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const IdentifierInfo *II) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const IdentifierInfo *II) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
DiagnosticsEngine::ak_identifierinfo);
return DB;
@ -1258,63 +1396,64 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
template <typename T>
inline std::enable_if_t<
std::is_same<std::remove_const_t<T>, DeclContext>::value,
const DiagnosticBuilder &>
operator<<(const DiagnosticBuilder &DB, T *DC) {
const StreamingDiagnostic &>
operator<<(const StreamingDiagnostic &DB, T *DC) {
DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
DiagnosticsEngine::ak_declcontext);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
SourceRange R) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
SourceRange R) {
DB.AddSourceRange(CharSourceRange::getTokenRange(R));
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
ArrayRef<SourceRange> Ranges) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
ArrayRef<SourceRange> Ranges) {
for (SourceRange R : Ranges)
DB.AddSourceRange(CharSourceRange::getTokenRange(R));
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const CharSourceRange &R) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const CharSourceRange &R) {
DB.AddSourceRange(R);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const FixItHint &Hint) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
const FixItHint &Hint) {
DB.AddFixItHint(Hint);
return DB;
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
ArrayRef<FixItHint> Hints) {
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
ArrayRef<FixItHint> Hints) {
for (const FixItHint &Hint : Hints)
DB.AddFixItHint(Hint);
return DB;
}
inline const DiagnosticBuilder &
operator<<(const DiagnosticBuilder &DB,
inline const StreamingDiagnostic &
operator<<(const StreamingDiagnostic &DB,
const llvm::Optional<SourceRange> &Opt) {
if (Opt)
DB << *Opt;
return DB;
}
inline const DiagnosticBuilder &
operator<<(const DiagnosticBuilder &DB,
inline const StreamingDiagnostic &
operator<<(const StreamingDiagnostic &DB,
const llvm::Optional<CharSourceRange> &Opt) {
if (Opt)
DB << *Opt;
return DB;
}
inline const DiagnosticBuilder &
operator<<(const DiagnosticBuilder &DB, const llvm::Optional<FixItHint> &Opt) {
inline const StreamingDiagnostic &
operator<<(const StreamingDiagnostic &DB,
const llvm::Optional<FixItHint> &Opt) {
if (Opt)
DB << *Opt;
return DB;
@ -1324,8 +1463,8 @@ operator<<(const DiagnosticBuilder &DB, const llvm::Optional<FixItHint> &Opt) {
/// context-sensitive keyword.
using DiagNullabilityKind = std::pair<NullabilityKind, bool>;
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
DiagNullabilityKind nullability);
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
DiagNullabilityKind nullability);
inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
unsigned DiagID) {
@ -1337,8 +1476,8 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
return DiagnosticBuilder(this);
}
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
llvm::Error &&E);
const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
llvm::Error &&E);
inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
return Report(SourceLocation(), DiagID);
@ -1366,7 +1505,7 @@ class Diagnostic {
bool hasSourceManager() const { return DiagObj->hasSourceManager(); }
SourceManager &getSourceManager() const { return DiagObj->getSourceManager();}
unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
unsigned getNumArgs() const { return DiagObj->DiagStorage.NumDiagArgs; }
/// Return the kind of the specified index.
///
@ -1376,7 +1515,8 @@ class Diagnostic {
/// \pre Idx < getNumArgs()
DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const {
assert(Idx < getNumArgs() && "Argument index out of range!");
return (DiagnosticsEngine::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
return (DiagnosticsEngine::ArgumentKind)
DiagObj->DiagStorage.DiagArgumentsKind[Idx];
}
/// Return the provided argument string specified by \p Idx.
@ -1384,7 +1524,7 @@ class Diagnostic {
const std::string &getArgStdStr(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_std_string &&
"invalid argument accessor!");
return DiagObj->DiagArgumentsStr[Idx];
return DiagObj->DiagStorage.DiagArgumentsStr[Idx];
}
/// Return the specified C string argument.
@ -1392,7 +1532,8 @@ class Diagnostic {
const char *getArgCStr(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_c_string &&
"invalid argument accessor!");
return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
return reinterpret_cast<const char *>(
DiagObj->DiagStorage.DiagArgumentsVal[Idx]);
}
/// Return the specified signed integer argument.
@ -1400,7 +1541,7 @@ class Diagnostic {
int getArgSInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_sint &&
"invalid argument accessor!");
return (int)DiagObj->DiagArgumentsVal[Idx];
return (int)DiagObj->DiagStorage.DiagArgumentsVal[Idx];
}
/// Return the specified unsigned integer argument.
@ -1408,7 +1549,7 @@ class Diagnostic {
unsigned getArgUInt(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_uint &&
"invalid argument accessor!");
return (unsigned)DiagObj->DiagArgumentsVal[Idx];
return (unsigned)DiagObj->DiagStorage.DiagArgumentsVal[Idx];
}
/// Return the specified IdentifierInfo argument.
@ -1416,7 +1557,8 @@ class Diagnostic {
const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
assert(getArgKind(Idx) == DiagnosticsEngine::ak_identifierinfo &&
"invalid argument accessor!");
return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
return reinterpret_cast<IdentifierInfo *>(
DiagObj->DiagStorage.DiagArgumentsVal[Idx]);
}
/// Return the specified non-string argument in an opaque form.
@ -1424,36 +1566,36 @@ class Diagnostic {
intptr_t getRawArg(unsigned Idx) const {
assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string &&
"invalid argument accessor!");
return DiagObj->DiagArgumentsVal[Idx];
return DiagObj->DiagStorage.DiagArgumentsVal[Idx];
}
/// Return the number of source ranges associated with this diagnostic.
unsigned getNumRanges() const {
return DiagObj->DiagRanges.size();
return DiagObj->DiagStorage.DiagRanges.size();
}
/// \pre Idx < getNumRanges()
const CharSourceRange &getRange(unsigned Idx) const {
assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
return DiagObj->DiagRanges[Idx];
return DiagObj->DiagStorage.DiagRanges[Idx];
}
/// Return an array reference for this diagnostic's ranges.
ArrayRef<CharSourceRange> getRanges() const {
return DiagObj->DiagRanges;
return DiagObj->DiagStorage.DiagRanges;
}
unsigned getNumFixItHints() const {
return DiagObj->DiagFixItHints.size();
return DiagObj->DiagStorage.FixItHints.size();
}
const FixItHint &getFixItHint(unsigned Idx) const {
assert(Idx < getNumFixItHints() && "Invalid index!");
return DiagObj->DiagFixItHints[Idx];
return DiagObj->DiagStorage.FixItHints[Idx];
}
ArrayRef<FixItHint> getFixItHints() const {
return DiagObj->DiagFixItHints;
return DiagObj->DiagStorage.FixItHints;
}
/// Format this diagnostic into a string, substituting the

View File

@ -45,6 +45,7 @@ class TextSubstitution<string Text> {
// diagnostics
string Component = "";
string CategoryName = "";
bit Deferrable = 0;
}
// Diagnostic Categories. These can be applied to groups or individual
@ -83,6 +84,7 @@ class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
bit AccessControl = 0;
bit WarningNoWerror = 0;
bit ShowInSystemHeader = 0;
bit Deferrable = 0;
Severity DefaultSeverity = defaultmapping;
DiagGroup Group;
string CategoryName = "";
@ -106,6 +108,14 @@ class SuppressInSystemHeader {
bit ShowInSystemHeader = 0;
}
class Deferrable {
bit Deferrable = 1;
}
class NonDeferrable {
bit Deferrable = 0;
}
// FIXME: ExtWarn and Extension should also be SFINAEFailure by default.
class Error<string str> : Diagnostic<str, CLASS_ERROR, SEV_Error>, SFINAEFailure {
bit ShowInSystemHeader = 1;

View File

@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, CATEGORY) \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
ENUM,
#define ASTSTART
#include "clang/Basic/DiagnosticASTKinds.inc"

View File

@ -54,6 +54,9 @@ def note_constexpr_nonliteral : Note<
def note_constexpr_non_global : Note<
"%select{pointer|reference}0 to %select{|subobject of }1"
"%select{temporary|%3}2 is not a constant expression">;
def note_constexpr_not_static : Note<
"address of non-static constexpr variable %0 may differ on each invocation "
"of the enclosing function; add 'static' to give it a constant address">;
def note_constexpr_dynamic_alloc : Note<
"%select{pointer|reference}0 to %select{|subobject of }1"
"heap-allocated object is not a constant expression">;
@ -69,6 +72,10 @@ def note_constexpr_array_index : Note<"cannot refer to element %0 of "
"in a constant expression">;
def note_constexpr_float_arithmetic : Note<
"floating point arithmetic produces %select{an infinity|a NaN}0">;
def note_constexpr_dynamic_rounding : Note<
"cannot evaluate this expression if rounding mode is dynamic">;
def note_constexpr_float_arithmetic_strict : Note<
"compile time floating point arithmetic suppressed in strict evaluation modes">;
def note_constexpr_pointer_subtraction_not_same_array : Note<
"subtracted pointers are not elements of the same array">;
def note_constexpr_pointer_subtraction_zero_size : Note<
@ -247,7 +254,7 @@ def note_constexpr_destroy_out_of_lifetime : Note<
"destroying object '%0' whose lifetime has already ended">;
def note_constexpr_unsupported_destruction : Note<
"non-trivial destruction of type %0 in a constant expression is not supported">;
def note_constexpr_unsupported_tempoarary_nontrivial_dtor : Note<
def note_constexpr_unsupported_temporary_nontrivial_dtor : Note<
"non-trivial destruction of lifetime-extended temporary with type %0 "
"used in the result of a constant expression is not yet supported">;
def note_constexpr_unsupported_unsized_array : Note<
@ -295,6 +302,8 @@ def note_constexpr_bit_cast_invalid_subtype : Note<
def note_constexpr_bit_cast_indet_dest : Note<
"indeterminate value can only initialize an object of type 'unsigned char'"
"%select{, 'char',|}1 or 'std::byte'; %0 is invalid">;
def note_constexpr_bit_cast_unrepresentable_value : Note<
"value %1 cannot be represented in type %0">;
def note_constexpr_pseudo_destructor : Note<
"pseudo-destructor call is not permitted in constant expressions "
"until C++20">;

View File

@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, CATEGORY) \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
ENUM,
#define ANALYSISSTART
#include "clang/Basic/DiagnosticAnalysisKinds.inc"

View File

@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, CATEGORY) \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
ENUM,
#define COMMENTSTART
#include "clang/Basic/DiagnosticCommentKinds.inc"

View File

@ -234,6 +234,12 @@ def err_seh___finally_block : Error<
// Sema && AST
def note_invalid_subexpr_in_const_expr : Note<
"subexpression not valid in a constant expression">;
def note_constexpr_invalid_template_arg : Note<
"%select{pointer|reference}0 to %select{|subobject of }1"
"%select{type_info object|string literal|temporary object|"
"predefined '%3' variable}2 is not allowed in a template argument">;
def err_constexpr_invalid_template_arg : Error<
note_constexpr_invalid_template_arg.Text>;
// Sema && Frontend
let CategoryName = "Inline Assembly Issue" in {

View File

@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, CATEGORY) \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
ENUM,
#define CROSSTUSTART
#include "clang/Basic/DiagnosticCrossTUKinds.inc"

View File

@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, CATEGORY) \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
ENUM,
#define DRIVERSTART
#include "clang/Basic/DiagnosticDriverKinds.inc"

View File

@ -44,6 +44,10 @@ def warn_drv_avr_libc_not_found: Warning<
def warn_drv_avr_family_linking_stdlibs_not_implemented: Warning<
"support for linking stdlibs for microcontroller '%0' is not implemented">,
InGroup<AVRRtlibLinkingQuirks>;
def warn_drv_avr_linker_section_addresses_not_implemented: Warning<
"support for passing the data section address to the linker for "
"microcontroller '%0' is not implemented">,
InGroup<AVRRtlibLinkingQuirks>;
def warn_drv_avr_stdlib_not_linked: Warning<
"standard library not linked and so no interrupt vector table or "
"compiler runtime routines will be linked">,
@ -73,12 +77,15 @@ def warn_drv_unknown_cuda_version: Warning<
InGroup<CudaUnknownVersion>;
def err_drv_cuda_host_arch : Error<"unsupported architecture '%0' for host compilation.">;
def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">;
def err_drv_bad_target_id : Error<"Invalid target ID: %0 (A target ID is a processor name "
"followed by an optional list of predefined features post-fixed by a plus or minus sign deliminated "
"by colon, e.g. 'gfx908:sramecc+:xnack-')">;
def err_drv_bad_offload_arch_combo : Error<"Invalid offload arch combinations: %0 and %1 (For a specific "
"processor, a feature should either exist in all offload archs, or not exist in any offload archs)">;
def err_drv_invalid_thread_model_for_target : Error<
"invalid thread model '%0' in '%1' for this target">;
def err_drv_invalid_linker_name : Error<
"invalid linker name in argument '%0'">;
def err_drv_invalid_pgo_instrumentor : Error<
"invalid PGO instrumentor in argument '%0'">;
def err_drv_invalid_rtlib_name : Error<
"invalid runtime library name in argument '%0'">;
def err_drv_unsupported_rtlib_for_platform : Error<
@ -108,12 +115,12 @@ def err_drv_command_failure : Error<
"unable to execute command: %0">;
def err_drv_invalid_darwin_version : Error<
"invalid Darwin version number: %0">;
def err_drv_invalid_diagnotics_hotness_threshold : Error<
"invalid argument in '%0', only integer or 'auto' is supported">;
def err_drv_missing_argument : Error<
"argument to '%0' is missing (expected %1 value%s1)">;
def err_drv_invalid_Xarch_argument_with_args : Error<
"invalid Xarch argument: '%0', options requiring arguments are unsupported">;
def err_drv_invalid_Xarch_argument_isdriver : Error<
"invalid Xarch argument: '%0', cannot change driver behavior inside Xarch argument">;
def err_drv_Xopenmp_target_missing_triple : Error<
"cannot deduce implicit triple value for -Xopenmp-target, specify triple using -Xopenmp-target=<triple>">;
def err_drv_invalid_Xopenmp_target_with_args : Error<
@ -208,6 +215,7 @@ def err_drv_dllexport_inlines_and_fallback : Error<
def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
def err_drv_invalid_value_with_suggestion : Error<"invalid value '%1' in '%0','%2'">;
def err_drv_invalid_remap_file : Error<
"invalid option '%0' not of the form <from-file>;<to-file>">;
def err_drv_invalid_gcc_output_type : Error<
@ -248,18 +256,19 @@ def err_drv_optimization_remark_format : Error<
"unknown remark serializer format: '%0'">;
def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, please use [no]simd instead">;
def err_drv_invalid_omp_target : Error<"OpenMP target is invalid: '%0'">;
def err_drv_incompatible_omp_arch : Error<"OpenMP target architecture '%0' pointer size is incompatible with host '%1'">;
def err_drv_omp_host_ir_file_not_found : Error<
"The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">;
def err_drv_omp_host_target_not_supported : Error<
"The target '%0' is not a supported OpenMP host target.">;
def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
"The option -fopenmp-targets must be used in conjunction with a -fopenmp option compatible with offloading, please use -fopenmp=libomp or -fopenmp=libiomp5.">;
def err_drv_omp_offload_target_missingbcruntime : Error<
"No library '%0' found in the default clang lib directory or in LIBRARY_PATH. Please use --libomptarget-nvptx-bc-path to specify nvptx bitcode library.">;
def err_drv_omp_offload_target_bcruntime_not_found : Error<"Bitcode library '%0' does not exist.">;
def warn_drv_omp_offload_target_duplicate : Warning<
"The OpenMP offloading target '%0' is similar to target '%1' already specified - will be ignored.">,
InGroup<OpenMPTarget>;
def warn_drv_omp_offload_target_missingbcruntime : Warning<
"No library '%0' found in the default clang lib directory or in LIBRARY_PATH. Expect degraded performance due to no inlining of runtime functions on target devices.">,
InGroup<OpenMPTarget>;
def err_drv_unsupported_embed_bitcode
: Error<"%0 is not supported with -fembed-bitcode">;
def err_drv_bitcode_unsupported_on_toolchain : Error<
@ -281,6 +290,9 @@ def warn_drv_unsupported_opt_for_target : Warning<
def warn_drv_unsupported_debug_info_opt_for_target : Warning<
"debug information option '%0' is not supported for target '%1'">,
InGroup<UnsupportedTargetOpt>;
def warn_drv_dwarf_version_limited_by_target : Warning<
"debug information option '%0' is not supported. It needs DWARF-%2 but target '%1' only provides DWARF-%3.">,
InGroup<UnsupportedTargetOpt>;
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
def warn_ignoring_fdiscard_for_bitcode : Warning<
@ -336,6 +348,8 @@ def err_invalid_branch_protection: Error <
"invalid branch protection option '%0' in '%1'">;
def err_invalid_sls_hardening : Error<
"invalid sls hardening option '%0' in '%1'">;
def err_sls_hardening_arm_not_supported : Error<
"-mharden-sls is only supported on armv7-a or later">;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
@ -458,6 +472,10 @@ def warn_drv_msvc_not_found : Warning<
"try running Clang from a developer command prompt">,
InGroup<DiagGroup<"msvc-not-found">>;
def warn_drv_fuse_ld_path : Warning<
"'-fuse-ld=' taking a path is deprecated. Use '--ld-path=' instead">,
InGroup<FUseLdPath>, DefaultIgnore;
def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
"option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored">,
InGroup<OptionIgnored>;
@ -478,6 +496,10 @@ def warn_drv_moutline_unsupported_opt : Warning<
"The '%0' architecture does not support -moutline; flag ignored">,
InGroup<OptionIgnored>;
def warn_drv_moutline_atomics_unsupported_opt : Warning<
"The '%0' architecture does not support -moutline-atomics; flag ignored">,
InGroup<OptionIgnored>;
def warn_drv_darwin_sdk_invalid_settings : Warning<
"SDK settings were ignored as 'SDKSettings.json' could not be parsed">,
InGroup<DiagGroup<"darwin-sdk-settings">>;
@ -511,4 +533,7 @@ def warn_drv_libstdcxx_not_found : Warning<
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_default_altivec_abi : Error<
"The default Altivec ABI on AIX is not yet supported, use '-mabi=vec-extabi' for the extended Altivec ABI">;
}

View File

@ -15,7 +15,7 @@ namespace clang {
namespace diag {
enum {
#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR, \
SHOWINSYSHEADER, CATEGORY) \
SHOWINSYSHEADER, DEFERRABLE, CATEGORY) \
ENUM,
#define FRONTENDSTART
#include "clang/Basic/DiagnosticFrontendKinds.inc"

Some files were not shown because too many files have changed in this diff Show More