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:
commit
e8d8bef961
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
63
contrib/llvm-project/clang/include/clang-c/Rewrite.h
Normal file
63
contrib/llvm-project/clang/include/clang-c/Rewrite.h
Normal 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
|
@ -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
|
734
contrib/llvm-project/clang/include/clang/APINotes/Types.h
Normal file
734
contrib/llvm-project/clang/include/clang/APINotes/Types.h
Normal 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
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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 {
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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).
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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()); }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -32,6 +32,7 @@ enum class DynamicInitKind : unsigned {
|
||||
NoStub = 0,
|
||||
Initializer,
|
||||
AtExit,
|
||||
GlobalArrayDestructor
|
||||
};
|
||||
|
||||
enum class KernelReferenceKind : unsigned {
|
||||
|
161
contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
Normal file
161
contrib/llvm-project/clang/include/clang/AST/IgnoreExpr.h
Normal 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
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()">;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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>:: \
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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).
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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
@ -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)
|
||||
|
@ -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, "")
|
||||
|
@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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">;
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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">;
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user